- Apply symbols.inc hardware register names to Defender 2 (U) (51 operands)
- Apply symbols.inc hardware register names to Donkey Kong 3 (JUE) (36 operands)
- Add APU register symbols (-) to Defender 2 (U) and Donkey Kong 3 (JUE) symbols.inc
- Apply symbols to Donkey Kong Jr. Math (U) (80 operands: 11 single + 69 hardware)
- Apply symbols to Excitebike (JU) (786 operands: 785 single + 1 hardware)
- Add promotion criteria to PROMPTS.md: symbol/local substitution,
ROM-specific semantic naming, and verification checklist
Add branch/jump target naming requirement to PROMPTS.md
All branches and jumps must target symbolic labels with descriptive names
derived from program flow role (e.g., _Loop, _Next, _Done, _Store, _Return),
never raw address literals. Adds criterion 8 to verification checklist.
Rename all OVERVIEW.md to README.md; add root README content to top-level
- Rename all OVERVIEW.md files to README.md throughout the repo (47 files)
- Prepend README.md content to top-level OVERVIEW.md before rename
- Fix apply_symbols.py NAME_RE regex to handle spaced assignments
- Apply symbols.inc to Defender 2 (U) (51 hardware operands)
- Apply symbols.inc to Donkey Kong 3 (JUE) (36 hardware operands)
- Apply symbols.inc to Donkey Kong Jr. Math (U) (80 operands: 11 single + 69 hardware)
- Apply symbols.inc to Excitebike (JU) (786 operands: 785 single + 1 hardware)
- Add missing Zp18/FrameCounter aliases to Excitebike prg.s
- Build all 27 top-level projects: byte-identical
Promote Donkey Kong Jr. Math back to _wip tier
Moves code from `copilot` folder and verifies each builds after
Add pre-commit hook for byte-identical verification
Add .git/hooks/pre-commit that runs 'make' then 'make clean' in each
project directory before committing. This ensures every project builds
byte-identical before any commit is accepted.
Also includes all file moves from the Donkey Kong Jr. Math (U) demotion
and other file restructuring from the session.
moves code out of copilot folder, its all AI generated.
Moves NROM games into NROM folder
removes copilot folder from Lunar Pool
Adds makefile to build all projects recursively
Updates docs to reflect changes in layout
Repromotes Donkey Kong Jr Math
Repromotes Excitebike
Promotes Popeye (JU) (PRG 1)
Updates Makefile to provide summary of build failure/success
Promote Raid on Bungeling Bay (U): Pass 2/3 partial, whole-ROM byte-identical
Move _wip/NROM/Raid on Bungeling Bay (U) to NROM/ and switch the build
from a PRG-only compare to a whole-ROM one:
- header.s/chr.s added (one-line .incbin of header.bin / chr.bin)
- linker.cfg gains HEADER ($0000, $0010) and CHR ($0000, $2000)
areas ahead of PRG ($C000, $4000)
- rom.nes symlink to the space-containing original ROM name
- Makefile builds header.o/prg.o/chr.o into reconstructed.nes and
compares it against rom.nes ('Byte-identical ROM verified.')
- one leftover neutral indirect operand jmp (Zp01) at $E2EC becomes
jmp (IndDispatch01); apply_symbols.py reports 0 substitutions pending
README.md / TODO.md / AGENTS.md updated: 29 promoted, 7 in _wip/.
Pac-Man (U): Pass 2 complete (label renaming) + Pass 3 partial (ZP aliases, table names)
Pass 2 — fresh map derived from the committed split, not from any drafted
map (the drafted maps in other projects were audited and found not
applicable):
- all 194 address-derived Label_XXXX definitions renamed to semantic
routine-entry names plus <Routine>_<Role>_<addr> internal branch
targets; zero Label_ remains
- all 49 jsr/jmp call sites resolved from raw $XXXX to labels; zero
raw $XXXX call operands remain
- routinemap.tsv / derived_names.tsv record the derivation
Pass 3 (partial):
- 15 proven semantic zero-page aliases added to locals.inc
(GameState, NmiFlag, ScrollX/Y, PpuCtrlShadow, OamDmaPage,
CocktailModeFlag, ActivePlayerFlag, GameplaySuspended, FrameCounter,
StateTimer, Player1/2Input, ActiveInput, CopyrightVerified)
- 112 operands substituted into prg.s (11 single + 101 hardware)
- key data tables named: ProgrammerSig ($C0EB), GameStateDispatchTable
($C253), TitleScreenData ($C2FD), EntityPtrTable ($D912),
AudioCommandTable ($EFDD)
Also corrects the README's claim that the RESET vector points at padding:
$FF00 holds real boot code (sei/cld, PPU off, double vblank wait, then
jmp ColdStart at $C042).
.gitignore: ignore reconstructed_prg.bin (build artifact of the _wip
Makefiles; '**/reconstructed.*' does not match the underscore form).
Promote Pac-Man (U): Pass 2/3 complete, whole-ROM byte-identical
Move _wip/NROM/Pac-Man (U) to NROM/ and switch the build from a PRG-only
compare to a whole-ROM one:
- header.s/chr.s added (one-line .incbin of header.bin / chr.bin)
- linker.cfg gains HEADER ($0000, $0010) and CHR ($0000, $2000)
areas ahead of PRG ($C000, $4000)
- rom.nes symlink to 'Pac-Man (U) [!].nes' (the original ROM name
contains a space and brackets)
- Makefile builds header.o/prg.o/chr.o into reconstructed.nes and
compares it against rom.nes
- reconstructed.nes is 24,592 bytes, MD5 a69d310f8cae9397fbd39f204672b5c7
- equal to the original ROM; the header/prg/chr splits were checked
against the original before promotion and are byte-exact
Pass 3 residue closed. The last 7 multi-alias zero-page operands are
resolved per site through a new sites.tsv, each proven from context
rather than guessed:
- jmp ($0010) at $C250/$D3CA/$D90F/$D9B6 -> (DispatchPtrLo); each
is immediately preceded by sta DispatchPtrLo/sta DispatchPtrHi
- jmp ($00FE) at $EFDA -> (AudioHandlerPtrLo); preceded by
sta AudioHandlerPtrLo/sta AudioHandlerPtrHi
- sta a:$0000,y at $C048/$C089 -> a:Zp00,y; the literal zero-page
base in the two ZP clear loops, so the neutral name is used rather
than the semantic WorkPtrLo. The 'a:' prefix survives the
substitution, so the bytes stay 99 00 00 (sta abs,Y)
apply_symbols.py now reports 119 operands substituted (101 hardware,
11 single-name, 7 site) and 0 residue.
New tool _tools/align_audit_comments.py: re-aligns the audit comment to
column 35 after a substitution lengthens an operand (nesdis.py pads each
instruction to 31 characters). Whitespace-only, so the byte identity
cannot change. 405 lines re-aligned in this project; all 2,387 audit
comments still match prg.bin at the stated PRG offset, 0 mismatches.
Docs: root README.md / TODO.md / AGENTS.md updated - 30 promoted, 6 in
_wip/; a per-project detail entry for Pac-Man (U) added; the stale
'Donkey Kong 3 (JUE) has no README.md' claim corrected (it has a
318-line one).
Promote Raid on Bungeling Bay (U) [a2]: Pass 3 complete, whole-ROM byte-identical
Move _wip/NROM/Raid on Bungeling Bay (U) [a2] to NROM/ and switch the build
from a PRG-only compare to a whole-ROM one:
- header.s/chr.s added (one-line .incbin of header.bin / chr.bin)
- linker.cfg gains HEADER ($0000, $0010) and CHR ($0000, $2000)
areas ahead of PRG ($C000, $4000)
- rom.nes symlink to 'Raid on Bungeling Bay (U) [a2].nes' (the original
ROM name contains spaces and brackets)
- reconstructed.nes is 24,592 bytes, MD5 659d340a1e9d420eee28df13319b0094
- equal to the original ROM; the header/prg/chr splits were checked
against the original before promotion and are byte-exact
Pass 3 - 15 semantic zero-page aliases, each applied only at the sites
where its role is proven:
- PpuCtrlShadow ($C2), 15 sites: the reset entry primes it right after
'sta PPUCTRL', and every other use is an ora/and/eor followed by
'sta PPUCTRL'
- NmiPathSelector ($C4), 5 sites: written 1 at $C3E9 and 0 at $C962
- GameState ($D6), 6 sites: 'cmp #$02' and used as an index at $C4C7
- FrameSubCounter ($55), 6 sites: set to $0A at $C520, decremented per
NMI at $C07B
- PrngPeriodCounter ($EA) / PrngSeedB ($EB) / PrngState ($EC), 13 sites:
the PRNG state
- PtrLo ($00) / PtrHi ($01), 8 sites: the 16-bit pair $1C13 and $1610
compared at $E785/$E791
- IndDispatch01 ($01) / IndDispatch02 ($02), 3 sites: the computed
dispatch at $E2EC
- IndDispatch1B ($1B) / IndDispatch1C ($1C), 6 sites: the dispatch at
$E7A3
- IndDispatch17 ($17) / IndDispatch19 ($19): the dispatches at $E79D
and $E7A0
Addresses that carry two names keep the neutral ZpXX name where the other
role applies - $01 is PtrHi at the 16-bit compare and IndDispatch01 at the
dispatch; $17 is IndDispatch17 at the dispatch and Zp17 for the absolute
RAM $0017 store in the copy loop at $E895/$E8D0.
New tool _tools/apply_zp_aliases.py does the per-site substitution:
apply_symbols.py only rewrites *numeric* operands, so it cannot rename an
operand that is already written as a neutral ZpXX name. The tool keeps the
ca65 'a:' prefix (dropping it would turn 'sta a:Zp17,y' into a zero-page
store and change the bytes) and rewrites only the operand token, so the
audit comment survives byte for byte.
Naming correction in the promoted sibling. Finishing this dump showed that
$EA was misnamed 'VBlankWaitCounter': the routine at $C412 is the game's
pseudo-random generator (the classic eor/asl/php/lsr/plp/rol scrambler,
called from thirteen gameplay sites, twice in a row at $CDF4/$CDF9 with the
second result masked #$07), so $EA is the scrambler's phase counter.
Renamed PrngPeriodCounter in both dumps and named $EB/$EC PrngSeedB /
PrngState. The sibling's two 'sta a:IndDispatch17,y' operands were also
wrong - they are absolute stores to RAM $0017, not the dispatch pointer -
and are now 'a:Zp17,y', matching the file's 'a:' = absolute convention.
Audit-comment alignment re-done with _tools/align_audit_comments.py (1,040
lines here, 1,080 in the sibling). Both files still match prg.bin at every
stated PRG offset: 5,467 and 5,483 audit comments, 0 mismatches.
Docs: root README.md / TODO.md / AGENTS.md updated - 31 promoted, 5 in
_wip/; per-project detail entries added for both Raid dumps.
Promote Pac-Man (Tengen) (U): Pass 2/3 from scratch, whole-ROM byte-identical
Move _wip/NROM/Pac-Man (Tengen) (U) to NROM/ and switch the build from a
PRG-only compare to a whole-ROM one:
- header.s/chr.s added (one-line .incbin of header.bin / chr.bin)
- linker.cfg gains HEADER ($0000, $0010) and CHR ($0000, $2000)
areas ahead of PRG ($C000, $4000)
- rom.nes symlink to 'Pac-Man (Tengen) (U) [!].nes'
- reconstructed.nes is 24,592 bytes, MD5 d34e7a74d8d2c231b6cc601210e28ad0
- equal to the original ROM; the header/prg/chr splits were checked
against the original before promotion and are byte-exact
Disassembled from scratch. No name, map or file was carried over from the
sibling 'Pac-Man (U)' dump; the map was derived from this dump's own
committed split and the two were only compared afterwards.
Pass 2 (new tool _tools/apply_pass2_map.py):
- all 194 Label_XXXX definitions renamed to semantic routine entries plus
<Routine>_<Role> branch targets; zero Label_ remains
- all 48 raw $XXXX jsr/jmp operands resolved to labels; zero raw $XXXX
call or branch operands remain
- the map is in routinemap.tsv
Pass 3:
- 30 semantic zero-page aliases, each applied only at the sites where its
role is proven (per-site choice in sites.tsv; the addresses that carry
two roles keep the neutral ZpXX name elsewhere). _tools/
derive_zp_aliases.py records how the set was derived, and locals.inc
records the reason for every remaining neutral slot
- 28 data tables named (new tool _tools/name_data_region.py), including
CharacterDataTable ($C66A) and CharacterNameStrings ($C67E), where the
ROM itself names Blinky, Pinky, Inky and Clyde - which is why the four
indexed entities are called ghosts and not 'actors'
- apply_symbols.py reports 0 substitutions pending and 0 residue
- audit-comment alignment re-done with _tools/align_audit_comments.py;
all 2,479 audit comments still match prg.bin at the stated PRG offset
Pass 1 correction - six command handlers recovered (new tool
_tools/recode_region.py). ScriptCommandTable ($EFDD) is read by the traced
instruction at $EFCC, and six of its entries point at $F00A, $F022, $F03A,
$F052, $F062 and $F072 - all of which the tracer had left as data, and two
of which it had mis-split across the 'jmp $EF61' at $F01F and $F04F.
Those 120 bytes are code here, decoded straight from the ROM; the six
handlers tile $F00A-$F081 exactly. The same gap exists in the promoted
'Pac-Man (U)' dump, which has not been corrected - recorded in both READMEs.
Residue (documented, not guessed): the unreached main game logic at
$C45A-$C55F is still .byte data. It is code - the tracer's own decoder
walks it cleanly and the dispatch table at $C511 points into it - but
nothing reaches it, so it cannot be entered without a guess. The same gap
exists in the promoted 'Pac-Man (U)' dump. Re-deriving it is a Pass 1 job;
a Mesen Code Data Logger capture is the tool the repo uses for it.
Docs: root README.md / TODO.md / AGENTS.md updated - 32 promoted, 4 in
_wip/; a per-project detail entry added for the Tengen dump.
Promote Pyramid (U): Pass 1 corrected, Pass 2/3 complete, whole-ROM byte-identical
Move _wip/NROM/Pyramid (U) to NROM/ and switch the build from a PRG-only
compare to a whole-ROM one:
- header.s/chr.s added (one-line .incbin of header.bin / chr.bin)
- linker.cfg gains HEADER ($0000, $0010) and CHR ($0000, $2000)
areas ahead of PRG ($C000, $4000)
- rom.nes symlink to 'Pyramid (U) (Sachen).nes'
- reconstructed.nes is 24,592 bytes, MD5 aa285ff17f25dd05da5996b7466c59e2
- equal to the original ROM; the header/prg/chr splits were checked
against the original before promotion and are byte-exact
Pass 1 correction - the committed split was a strict subset of the correct
one. This game dispatches through 'jmp' trampoline tables that live
*inside* the data regions, and the tracer cannot follow a jmp there, so
828 bytes of code were still marked as data. Four such tables were found
($C01E 3 entries, $C02A 6, $C042 2, $C054 5) plus ten more entries at
$C000-$C01B; all sixteen targets decode as valid instructions. Seeding
them, the $C800 boot mainline and six further code starts recovers the
whole lot, plus a five-byte stub at $DF89 (lda $33 / jmp $DECB) that sat
in a hole between two routines. The re-trace loses NO committed code byte
and takes the split from 34.5% to 39.6% (3,130 instructions / 6,493 code
bytes). 'make regen' reproduces it, so the split stays verifiable.
Pass 2 - a fresh map derived from this dump's own committed split:
- 428 Label_XXXX definitions renamed; zero Label_ residue
- 320 raw $XXXX jsr/jmp operands resolved; zero raw $XXXX branch
operands remain
- 431 routine entries and the 32 data blocks named from the code
- the internal branch-target names are derived mechanically from the
branch that reaches them by the new _tools/derive_branch_names.py
(beq -> OnZero, bne -> OnNonzero, bcc/bcs -> the carry cases, a
backwards branch -> Loop)
- recorded in routinemap.tsv
Pass 3:
- 24 semantic zero-page aliases, each applied only where its role is
proven; the 57 slots that stay neutral are each listed with the reason
in locals.inc (the neutral set lives in zp_aliases.inc so that
'make regen' can rebuild locals.inc from prg.bin)
- 32 data tables named - TaskVectorTable1/2, LevelScriptData,
MusicPeriodTable, SoundEnvelopeTable, the actor tables - recorded in
data_region_names.tsv
- apply_symbols.py reports 0 substitutions pending and 0 residue; no
hardware register is left as a raw literal
- the audit comments are now canonical on every line, data included
(the old file carried only 'PRG:$xxxx' on its 1,358 data lines);
all 3,762 audit comments match prg.bin at their stated PRG offset
Kept as-is, not 'cleaned up':
- sta $4100 stays a raw operand. The iNES header claims mapper 0 but
the boot code writes past the NES register space; the ROM does not
explain it, so it is recorded rather than guessed
- the 'A'/'V' check on RAM $0120/$0121 and its seed/clear routines
are named for what they do, not for what they are for
- the ninth entry of the $C3A6 task vector table ($D820) is a junk
slot and stays data
Docs: root README.md / TODO.md / AGENTS.md updated - 33 promoted, 3 in
_wip/; a per-project detail entry added.
Hogan's Alley (JU): Pass 1 correction, Pass 2, Pass 3, promoted to NROM/
The light-gun game whose engine dispatches through *inline* tables:
`IndirectCall` at $C34D pops the return address of the `jsr` that called
it and reads a 16-bit handler pointer from the word that follows, so all
six handler tables ($C124 19 entries, $C219 4, $C89C 14, $CDD1 1, $D234 2,
$D3D6 14) live inside the code stream and the static tracer cannot follow
them.
Pass 1 correction. The committed split was a strict subset of the correct
one -- 41.8% of the PRG was classified as code. A fresh Mesen Code Data
Logger capture was merged with the four captures already in the folder
(hogans_merged.cdl, the OR of five per-byte flag arrays, 6,544 code bytes)
and _tools/cdl_reclass.py rewrote the split to match what the CPU actually
fetched: 1,216 bytes moved from data to code, five the other way, 59 labels
emitted. The split is now 49.1% code (3,950 instructions, 8,041 bytes).
The four branch targets the reclassifier could not prove were turned into
labels by the new _tools/resolve_raw_branches.py.
Pass 2. 206 routine entries hand-named from this dump's own code and 413
internal branch targets derived mechanically by _tools/derive_branch_names.py:
630 Label_XXXX definitions gone, 484 raw $XXXX call operands resolved, 15
call targets the tracer had never labelled given a label. Recorded in
routinemap.tsv. No SubC<addr> residue was needed -- every entry the engine
reaches is named after what it does.
Pass 3. 60 semantic zero-page aliases, each applied only where its role is
proven (zp_aliases.inc, zp_alias_sites.tsv); the slots that stay neutral are
each listed with the reason. All 34 data blocks named
(data_region_names.tsv). apply_symbols.py reports 1 residue: `sta a:$00B4,y`
at $C203, the same address as Zp40/ActorPalette but forced to absolute
addressing, so it must stay numeric.
Promotion. header.s, chr.s and a HEADER/PRG/CHR linker.cfg added, rom.nes
symlinked to the original ROM; the whole-ROM cmp passes on the first
promoted build. There is deliberately no `make regen` target: the Pass 1
split here is the static trace corrected by a CDL capture, and the base the
correction was applied to is not what the current _tools/nesdis.py
produces, so prg.s is the maintained source of truth.
Tools changed:
nesdis.py --split/--note/--provenance options, so a data
region can carry its own name and explanation;
a forced-data address is no longer reported as a
recovered routine entry
apply_pass2_map.py can create the label for a call target the tracer
left unlabelled; no longer double-labels it
apply_zp_aliases.py --at-file, an address-based per-site list
derive_branch_names.py keeps the map's own header instead of writing a
fixed one
resolve_raw_branches.py new: turns `bXX *+$NN` operands into labels
build_hogans_map.py new: the hand-written Pass 2 map builder
The existing regen pipelines (MUSCLE (U), Urban Champion (JU)) still
reproduce prg.s byte for byte.
Apply the symbols.inc register names at Pass 1; fix a dropped byte in cdl_reclass
nesdis.py now names the hardware registers as it renders the operands, so a
project's Pass 1 output already reads `lda PPUSTATUS` instead of `lda $2002`
and the Pass 3 apply_symbols.py step has nothing left to do for them.
* nesdis.py --symbols FILE reads a symbols.inc-style file and substitutes
the register names. Only unambiguous entries in the $2000-$4017 window
are used: $4017 is both JOY2 and APUFRAMECOUNTER, so it stays numeric
and apply_symbols.py reports it as multi-alias residue, exactly as
before. The default is the symbols.inc next to --out, so a new project
gets the names without asking; --no-symbols opts out.
* The renderer records the operand's numeric value on the Insn, because
operand_value() used to re-parse the operand text and could no longer
read a name.
* The controller bit masks in symbols.inc (PAD_A and friends) are
constants, not addresses, and are still never substituted.
MUSCLE (U) and Urban Champion (JU) keep --no-symbols: their committed
prg.s was produced with the registers named by the Pass 3 apply_symbols.py
step, and the columns in those files reflect the in-place substitution.
Adding the missing apply_symbols.py step to both regen pipelines makes
them reproduce their committed prg.s byte for byte again - neither did
before this change (MUSCLE was 440 lines out, Urban Champion 772).
cdl_reclass.py had a bug that cost a byte: a region whose last source row
straddled the region's end was replaced by a regeneration of the region
only, so the tail of that row was dropped. Mario Bros (JU) hit it at
$C595, where the rebuild came out one byte short and every label after it
shifted. A region now covers the whole rows it replaces.
pass2.py reflow takes an optional column argument; the default is
unchanged (the ';' lands on the same column as before).
Mario Bros (JU): Pass 1 correction, Pass 2, Pass 3, promoted to NROM/
A two-player platformer whose handler tables are *inline*: the pointers sit
in the middle of the code stream, right after the `jsr` that reads them, so
the static tracer could never follow them.
Pass 1 correction. The committed split was a strict subset of the correct
one -- only 72.0% of the PRG was classified as code. A Mesen Code Data
Logger capture of this ROM (mario_mesen.cdl, 10,915 code bytes) showed
1,010 bytes the tracer had left as data were code; two branch targets the
capture never reached ($E4CB and $E639) were forced with --override for 57
more, so 1,067 bytes moved from data to code and 22 moved the other way.
The split is now 78.4% code (6,210 instructions, 12,847 bytes). The three
branch targets the reclassifier could not prove were turned into labels by
_resolve_raw_branches.py, which now refuses to put a label on a `.byte` row.
Pass 2. 206 routine entries and 519 internal branch targets: 931
Label_XXXX definitions gone, 51 raw $XXXX call operands resolved and 12 call
targets the tracer had never labelled given a label. Zero SubC residue --
the 185 entries a previous session had left as address-derived residue were
all named from this dump's own code. Recorded in routinemap.tsv.
Pass 3. 25 semantic zero-page aliases, each applied only where its role is
proven (zp_aliases.inc); the slots that stay neutral are each listed with the
reason. 35 data tables named -- GameStateHandlerTable, EnemyBehaviourTable,
EnemyScriptTable, EnemyTypePointerTable, SoundRoutineTable,
NoteFrequencyTable and the rest -- and recorded in
data_region_names.tsv. apply_symbols.py reports 0 residue.
Promotion. header.s, chr.s and a HEADER/PRG/CHR linker.cfg added, rom.nes
symlinked to the original ROM; the whole-ROM cmp passes on the first
promoted build. There is deliberately no `make regen` target: the Pass 1
split here is the static trace corrected by a CDL capture, and the base the
correction was applied to is not what the current _tools/nesdis.py
produces, so prg.s is the maintained source of truth.
Tools:
apply_pass2_map.py renames a label of any spelling -- SubC<addr> is
the honest residue form -- and its references
follow it; one combined pattern, so a 16,000-line
file does not need a substitution per label
resolve_raw_branches.py refuses to label a data row
build_mario_map.py new: the hand-written Pass 2 map builder
Remove the old _wip/NROM/Mario Bros (JU) folder (promoted to NROM/)
Mario Bros (JU): add the promoted-tier header, CHR, rom.nes symlink and zero-page aliases
Moves _ROMS/<ROM> into _wip/<MAPPER>/<ROM>
Sync the docs and the skeleton tool with the 857-project _wip tier
The _wip/ tier now holds 857 projects across 30 mapper folders, all
building byte-identical for the whole ROM. README.md, TODO.md and
AGENTS.md still described the old 39-project tier, so bring them in line
with WIP.md, which carries the tier's index.
The tier is no longer 39 projects of NROM-256 with a 16/32 KB PRG:
only two projects have a 16 KB PRG, 151 have 32 KB, 523 have 128 KB and
one has 1.5 MB, so most of it is a banked mapper whose image does not fit
the 6502's address space. Those projects link their MEMORY areas at .nes
file offsets rather than CPU addresses, which is the only option and the
honest model; the 39 older projects keep the CPU-address layout because
their PRG really is one contiguous window.
make_skeleton.py gains the two layouts (--layout flat|cpu), the board
name for the mapper, and a fix for find_rom() mistaking the build
output reconstructed.nes for the source ROM.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
22402 lines
1.4 MiB
Plaintext
22402 lines
1.4 MiB
Plaintext
ca65 V2.18 - Debian 2.19-2
|
|
Main file : prg.s
|
|
Current file: prg.s
|
|
|
|
000000r 1 ; Balloon Fight - ca65 PRG disassembly
|
|
000000r 1 ; 16 KiB NROM PRG mapped at CPU $C000-$FFFF
|
|
000000r 1 ; Hardware register and controller symbols are provided by symbols.inc.
|
|
000000r 1 .setcpu "6502"
|
|
000000r 1 .include "symbols.inc"
|
|
000000r 2 ; PPU registers
|
|
000000r 2 PPUCTRL = $2000
|
|
000000r 2 PPUMASK = $2001
|
|
000000r 2 PPUSTATUS = $2002
|
|
000000r 2 OAMADDR = $2003
|
|
000000r 2 OAMDATA = $2004
|
|
000000r 2 PPUSCROLL = $2005
|
|
000000r 2 PPUADDR = $2006
|
|
000000r 2 PPUDATA = $2007
|
|
000000r 2 OAMDMA = $4014
|
|
000000r 2 JOY1 = $4016
|
|
000000r 2 JOY2 = $4017
|
|
000000r 2
|
|
000000r 2 APUPC1BASE = $4000
|
|
000000r 2 APUPC1SWEEP = $4001
|
|
000000r 2 APUPC1TLOW = $4002
|
|
000000r 2 APUPC1THIGH = $4003
|
|
000000r 2
|
|
000000r 2 APUPC2BASE = $4004
|
|
000000r 2 APUPC2SWEEP = $4005
|
|
000000r 2 APUPC2LOW = $4006
|
|
000000r 2 APUPC2HIGH = $4007
|
|
000000r 2
|
|
000000r 2 APUTRIBASE = $4008
|
|
000000r 2 APUTRILOW = $400A
|
|
000000r 2 APUTRIHIGH = $400B
|
|
000000r 2
|
|
000000r 2 APUNOISEBASE = $400C
|
|
000000r 2 APUNOISELOOP = $400E
|
|
000000r 2 APUNOISELENGTH = $400F
|
|
000000r 2
|
|
000000r 2 APUDMABASE = $4010
|
|
000000r 2 APUDMALOAD = $4011
|
|
000000r 2 APUDMAADDR = $4012
|
|
000000r 2 APUDMALEN = $4013
|
|
000000r 2
|
|
000000r 2 APUCTRL = $4015
|
|
000000r 2 APUSTATUS = $4015
|
|
000000r 2 APUFRAMECNT = $4017
|
|
000000r 2
|
|
000000r 2 ; Controller Masks
|
|
000000r 2 PAD_RIGHT=$01
|
|
000000r 2 PAD_LEFT=$02
|
|
000000r 2 PAD_DOWN=$04
|
|
000000r 2 PAD_UP=$08
|
|
000000r 2 PAD_START=$10
|
|
000000r 2 PAD_SELECT=$20
|
|
000000r 2 PAD_B=$40
|
|
000000r 2 PAD_A=$80
|
|
000000r 2 PAD_HORIZONTAL=PAD_LEFT|PAD_RIGHT
|
|
000000r 2 PAD_VERTICAL=PAD_UP|PAD_DOWN
|
|
000000r 2 PAD_DPAD=PAD_HORIZONTAL|PAD_VERTICAL
|
|
000000r 2
|
|
000000r 1 .include "locals.inc"
|
|
000000r 2 ; ============================================================================
|
|
000000r 2 ; Confirmed and high-confidence zero-page symbols
|
|
000000r 2 ; ============================================================================
|
|
000000r 2
|
|
000000r 2 IndirectPtrLo = $00
|
|
000000r 2 IndirectPtrHi = $01
|
|
000000r 2 RecordPtrLo = $02
|
|
000000r 2 RecordPtrHi = $03
|
|
000000r 2
|
|
000000r 2 MathTemp05 = $05
|
|
000000r 2 NmiSavedX = $0D
|
|
000000r 2 NmiSavedY = $0E
|
|
000000r 2 DerivedControl0 = $0F
|
|
000000r 2
|
|
000000r 2 ControllerHeld1 = $11
|
|
000000r 2 ControllerHeld2 = $12
|
|
000000r 2 InputState1 = $13
|
|
000000r 2 InputState2 = $14
|
|
000000r 2 ControllerPressed1 = $15
|
|
000000r 2 ControllerPressed2 = $16
|
|
000000r 2 InputAux1 = $17
|
|
000000r 2 InputAux2 = $18
|
|
000000r 2
|
|
000000r 2 RandomStateLo = $19
|
|
000000r 2 RandomStateHi = $1A
|
|
000000r 2 TransitionCounter = $1B
|
|
000000r 2 TransitionActive = $1D
|
|
000000r 2 SessionActive = $1E
|
|
000000r 2 NmiStateFlag = $1F
|
|
000000r 2 FrameState20 = $20
|
|
000000r 2 SelectedPitchAction = $21
|
|
000000r 2
|
|
000000r 2 SavedIndex = $22
|
|
000000r 2 InlineReturnLo = $26
|
|
000000r 2 InlineReturnHi = $27
|
|
000000r 2
|
|
000000r 2 SelectionValue0 = $32
|
|
000000r 2 RoundStateIndex = $33
|
|
000000r 2 PlayerOneSelection = $34
|
|
000000r 2 PlayerTwoSelection = $35
|
|
000000r 2
|
|
000000r 2 ObjectScreenX = $36
|
|
000000r 2 ObjectScreenXHi = $37
|
|
000000r 2 ObjectScreenY = $38
|
|
000000r 2 ObjectScreenYHi = $39
|
|
000000r 2
|
|
000000r 2 PpuQueueOffset = $3E
|
|
000000r 2 OamWriteOffset = $3F
|
|
000000r 2
|
|
000000r 2 ModeFlags = $40
|
|
000000r 2 CurrentObjectArrayOffset= $42
|
|
000000r 2 SelectionState = $43
|
|
000000r 2 PlayerSelectionActive = $44
|
|
000000r 2 MatchCompleteFlag = $45
|
|
000000r 2 StateSequenceActive = $46
|
|
000000r 2
|
|
000000r 2 DelayCounter = $48
|
|
000000r 2 LoopCounter49 = $49
|
|
000000r 2 QueueDestination = $4A
|
|
000000r 2 ActivePlayerSide = $4B
|
|
000000r 2 HorizontalDirectionMask = $4C
|
|
000000r 2
|
|
000000r 2 RandomState0 = $4D
|
|
000000r 2 RandomState1 = $4E
|
|
000000r 2 RandomBits0 = $4F
|
|
000000r 2 RandomBits1 = $50
|
|
000000r 2 Counter51 = $51
|
|
000000r 2 Counter52 = $52
|
|
000000r 2
|
|
000000r 2 SavedBaseXLo = $53
|
|
000000r 2 SavedBaseXHi = $54
|
|
000000r 2 SavedBaseYLo = $55
|
|
000000r 2 SavedBaseYHi = $56
|
|
000000r 2
|
|
000000r 2 BaseMotionActive = $5C
|
|
000000r 2 BaseMotionPhase = $5D
|
|
000000r 2 BaseMotionEventCount = $5E
|
|
000000r 2 TrajectoryResult = $5F
|
|
000000r 2
|
|
000000r 2 PendingStateTransition = $60
|
|
000000r 2 UpdateCounter = $61
|
|
000000r 2 PrimarySequenceState = $62
|
|
000000r 2 TransitionSequenceState = $63
|
|
000000r 2 SecondarySequenceState = $64
|
|
000000r 2 PendingScoreIncrement = $65
|
|
000000r 2 InningOrSharedScore = $66
|
|
000000r 2 PlayerOneScore = $67
|
|
000000r 2 PlayerTwoScore = $68
|
|
000000r 2 EventWriteIndex = $69
|
|
000000r 2 EventReadIndex = $6A
|
|
000000r 2 TextCopyCount = $6B
|
|
000000r 2 SpecialSequenceState = $6D
|
|
000000r 2 ObjectTransitionState = $6E
|
|
000000r 2 PendingEvent = $6F
|
|
000000r 2
|
|
000000r 2 TableCopyIndex = $70
|
|
000000r 2 DisplayCounterValue = $71
|
|
000000r 2 StateSelector = $72
|
|
000000r 2 WindupLoopCounter = $73
|
|
000000r 2 MotionSettledCountdown = $76
|
|
000000r 2 StateTimer78 = $78
|
|
000000r 2
|
|
000000r 2 ActionSequenceCounter = $7E
|
|
000000r 2 SelectedStateCount = $7F
|
|
000000r 2 RandomValue81 = $81
|
|
000000r 2 ActorActionComplete = $82
|
|
000000r 2 ObjectApproachCount = $83
|
|
000000r 2 ObjectApproachDirectionFlag = $84
|
|
000000r 2 TrajectoryEvaluationEnabled = $86
|
|
000000r 2 ObjectProximityState = $87
|
|
000000r 2 MotionDirectionState = $88
|
|
000000r 2
|
|
000000r 2 FielderAnimationCountdown = $8C
|
|
000000r 2 FielderInputBalance = $8D
|
|
000000r 2 RandomHorizontalMotion = $8E
|
|
000000r 2 CalculatedVerticalMotion= $8F
|
|
000000r 2 RandomVerticalMotion = $90
|
|
000000r 2 PitchDirectionDecision = $91
|
|
000000r 2 ActionDelayCounter = $92
|
|
000000r 2 PitchUpdateDelay = $94
|
|
000000r 2
|
|
000000r 2 CurrentActionState = $9D
|
|
000000r 2 SecondaryActorState0 = $9F
|
|
000000r 2 SecondaryActorState1 = $A0
|
|
000000r 2 SecondaryActorState2 = $A1
|
|
000000r 2 ObjectSequenceState = $A2
|
|
000000r 2 ObjectSelectionLowerBound= $A5
|
|
000000r 2
|
|
000000r 2 CalculatedCoordinateLow = $AE
|
|
000000r 2 CalculatedCoordinateHigh= $AF
|
|
000000r 2
|
|
000000r 2 PositionSignState = $B7
|
|
000000r 2 ObjectListFlag = $C7
|
|
000000r 2 SpriteSortBaseIndex = $C9
|
|
000000r 2 SpriteArrayEnd = $CA
|
|
000000r 2
|
|
000000r 2 MathShiftCount = $DB
|
|
000000r 2
|
|
000000r 2 PpuCtrlShadow = $DD
|
|
000000r 2 PpuMaskShadow = $DE
|
|
000000r 2 ScrollX = $DF
|
|
000000r 2 ScrollY = $E0
|
|
000000r 2
|
|
000000r 2 CurrentObjectIndex = $E1
|
|
000000r 2 ScriptDepth = $E2
|
|
000000r 2 FrameCounter = $E3
|
|
000000r 2
|
|
000000r 2 GameplaySuspended = $EF
|
|
000000r 2 SoundPtrLo = $F6
|
|
000000r 2 SoundPtrHi = $F7
|
|
000000r 2
|
|
000000r 2 PendingAudioFlags = $FE
|
|
000000r 2 RenderStateFlags = $FF
|
|
000000r 2
|
|
000000r 1
|
|
000000r 1 ; ============================================================================
|
|
000000r 1 ; Zero-page scratch policy
|
|
000000r 1 ;
|
|
000000r 1 ; $00-$0C are intentionally left numeric. Their meanings vary between pointer
|
|
000000r 1 ; decoding, arithmetic, OAM construction, geometry, PPU streaming, and audio.
|
|
000000r 1 ; Routine contracts describe the local role when it can be inferred safely.
|
|
000000r 1 ; ============================================================================
|
|
000000r 1 .segment "PRG"
|
|
000000r 1 .org $C000
|
|
00C000 1
|
|
00C000 1 ; ============================================================================
|
|
00C000 1 ; $C000-$C023
|
|
00C000 1 ; Title-screen copyright PPU stream.
|
|
00C000 1 ; ============================================================================
|
|
00C000 1
|
|
00C000 1 TitleCopyrightPpuStream: ; $C000
|
|
00C000 1 23 45 05 .byte $23,$45,$05
|
|
00C003 1 AF 01 09 08 .byte $AF,$01,$09,$08,$04
|
|
00C007 1 04
|
|
00C008 1
|
|
00C008 1 23 65 18 .byte $23,$65,$18
|
|
00C00B 1 17 12 17 1D .byte $17,$12,$17,$1D,$0E,$17,$0D,$18
|
|
00C00F 1 0E 17 0D 18
|
|
00C013 1 25 18 0F 25 .byte $25,$18,$0F,$25,$0A,$16,$0E,$1B
|
|
00C017 1 0A 16 0E 1B
|
|
00C01B 1 12 0C 0A 25 .byte $12,$0C,$0A,$25,$12,$17,$0C,$AC
|
|
00C01F 1 12 17 0C AC
|
|
00C023 1
|
|
00C023 1 00 .byte $00
|
|
00C024 1
|
|
00C024 1 ; ============================================================================
|
|
00C024 1 ; $C024-$C029
|
|
00C024 1 ; Tile values for the six selectable team initials: A, C, D, P, R, Y.
|
|
00C024 1 ; ============================================================================
|
|
00C024 1
|
|
00C024 1 TeamInitialTileTable: ; $C024
|
|
00C024 1 0A 0C 0D 19 .byte $0A,$0C,$0D,$19,$1B,$22
|
|
00C028 1 1B 22
|
|
00C02A 1
|
|
00C02A 1 ; ============================================================================
|
|
00C02A 1 ; $C02A-$C02F
|
|
00C02A 1 ; Sprite tile selected for each team-selection marker.
|
|
00C02A 1 ; ============================================================================
|
|
00C02A 1
|
|
00C02A 1 TeamSelectionSpriteTileTable: ; $C02A
|
|
00C02A 1 0C 16 12 16 .byte $0C,$16,$12,$16,$03,$0F
|
|
00C02E 1 03 0F
|
|
00C030 1
|
|
00C030 1 ; ============================================================================
|
|
00C030 1 ; $C030-$C035
|
|
00C030 1 ; X coordinate used for each team-selection marker sprite.
|
|
00C030 1 ; ============================================================================
|
|
00C030 1
|
|
00C030 1 TeamSelectionSpriteXTable: ; $C030
|
|
00C030 1 30 21 10 30 .byte $30,$21,$10,$30,$21,$10
|
|
00C034 1 21 10
|
|
00C036 1
|
|
00C036 1 ; ============================================================================
|
|
00C036 1 ; $C036-$C045
|
|
00C036 1 ; Calculate randomized signed pitch motion.
|
|
00C036 1 ; ============================================================================
|
|
00C036 1
|
|
00C036 1 CalculateRandomizedPitchMotion: ; $C036
|
|
00C036 1 A9 E2 lda #$E2 ; $C036: A9 E2
|
|
00C038 1 ED 39 05 sbc $0539 ; $C038: ED 39 05
|
|
00C03B 1
|
|
00C03B 1 C9 80 cmp #$80 ; $C03B: C9 80
|
|
00C03D 1 6A ror ; $C03D: 6A
|
|
00C03E 1
|
|
00C03E 1 C9 80 cmp #$80 ; $C03E: C9 80
|
|
00C040 1 6A ror ; $C040: 6A
|
|
00C041 1
|
|
00C041 1 38 sec ; $C041: 38
|
|
00C042 1 ED 39 05 sbc $0539 ; $C042: ED 39 05
|
|
00C045 1
|
|
00C045 1 60 rts ; $C045: 60
|
|
00C046 1
|
|
00C046 1 ; ============================================================================
|
|
00C046 1 ; $C046-$C122
|
|
00C046 1 ; NMI handler
|
|
00C046 1 ; ============================================================================
|
|
00C046 1
|
|
00C046 1 NMI: ; $C046
|
|
00C046 1 48 pha ; $C046: 48
|
|
00C047 1 86 0D stx NmiSavedX ; $C047: 86 0D
|
|
00C049 1 84 0E sty NmiSavedY ; $C049: 84 0E
|
|
00C04B 1
|
|
00C04B 1 AD 02 20 lda PPUSTATUS ; $C04B: AD 02 20
|
|
00C04E 1
|
|
00C04E 1 A9 02 lda #$02 ; $C04E: A9 02
|
|
00C050 1 8D 14 40 sta OAMDMA ; $C050: 8D 14 40
|
|
00C053 1
|
|
00C053 1 A0 00 ldy #$00 ; $C053: A0 00
|
|
00C055 1
|
|
00C055 1 NMI_PacketLoop: ; $C055
|
|
00C055 1 BE 00 03 ldx $0300,y ; $C055: BE 00 03
|
|
00C058 1 F0 33 beq NMI_QueueDone ; $C058: F0 33
|
|
00C05A 1
|
|
00C05A 1 C8 iny ; $C05A: C8
|
|
00C05B 1
|
|
00C05B 1 B9 00 03 lda $0300,y ; $C05B: B9 00 03
|
|
00C05E 1 8D 06 20 sta PPUADDR ; $C05E: 8D 06 20
|
|
00C061 1
|
|
00C061 1 C8 iny ; $C061: C8
|
|
00C062 1
|
|
00C062 1 B9 00 03 lda $0300,y ; $C062: B9 00 03
|
|
00C065 1 8D 06 20 sta PPUADDR ; $C065: 8D 06 20
|
|
00C068 1
|
|
00C068 1 C8 iny ; $C068: C8
|
|
00C069 1 C8 iny ; $C069: C8
|
|
00C06A 1
|
|
00C06A 1 B9 FF 02 lda $02FF,y ; $C06A: B9 FF 02
|
|
00C06D 1 8D 00 20 sta PPUCTRL ; $C06D: 8D 00 20
|
|
00C070 1
|
|
00C070 1 30 0C bmi NMI_ReadPacket ; $C070: 30 0C
|
|
00C072 1
|
|
00C072 1 NMI_WritePacket: ; $C072
|
|
00C072 1 B9 00 03 lda $0300,y ; $C072: B9 00 03
|
|
00C075 1 8D 07 20 sta PPUDATA ; $C075: 8D 07 20
|
|
00C078 1
|
|
00C078 1 C8 iny ; $C078: C8
|
|
00C079 1 CA dex ; $C079: CA
|
|
00C07A 1
|
|
00C07A 1 D0 F6 bne NMI_WritePacket ; $C07A: D0 F6
|
|
00C07C 1 F0 D7 beq NMI_PacketLoop ; $C07C: F0 D7
|
|
00C07E 1
|
|
00C07E 1 NMI_ReadPacket: ; $C07E
|
|
00C07E 1 AD 07 20 lda PPUDATA ; $C07E: AD 07 20
|
|
00C081 1 ; Discard buffered PPU read.
|
|
00C081 1
|
|
00C081 1 NMI_ReadPacketLoop: ; $C081
|
|
00C081 1 AD 07 20 lda PPUDATA ; $C081: AD 07 20
|
|
00C084 1 99 00 03 sta $0300,y ; $C084: 99 00 03
|
|
00C087 1
|
|
00C087 1 C8 iny ; $C087: C8
|
|
00C088 1 CA dex ; $C088: CA
|
|
00C089 1
|
|
00C089 1 D0 F6 bne NMI_ReadPacketLoop ; $C089: D0 F6
|
|
00C08B 1 F0 C8 beq NMI_PacketLoop ; $C08B: F0 C8
|
|
00C08D 1
|
|
00C08D 1 NMI_QueueDone: ; $C08D
|
|
00C08D 1 8E 00 03 stx $0300 ; $C08D: 8E 00 03
|
|
00C090 1
|
|
00C090 1 A5 DF lda ScrollX ; $C090: A5 DF
|
|
00C092 1 8D 05 20 sta PPUSCROLL ; $C092: 8D 05 20
|
|
00C095 1
|
|
00C095 1 A5 E0 lda ScrollY ; $C095: A5 E0
|
|
00C097 1 8D 05 20 sta PPUSCROLL ; $C097: 8D 05 20
|
|
00C09A 1
|
|
00C09A 1 A5 DE lda PpuMaskShadow ; $C09A: A5 DE
|
|
00C09C 1 8D 01 20 sta PPUMASK ; $C09C: 8D 01 20
|
|
00C09F 1
|
|
00C09F 1 A5 DD lda PpuCtrlShadow ; $C09F: A5 DD
|
|
00C0A1 1 8D 00 20 sta PPUCTRL ; $C0A1: 8D 00 20
|
|
00C0A4 1
|
|
00C0A4 1 20 D0 F9 jsr InitializeAudioEngine ; $C0A4: 20 D0 F9
|
|
00C0A7 1
|
|
00C0A7 1 A9 01 lda #$01 ; $C0A7: A9 01
|
|
00C0A9 1 8D 16 40 sta JOY1 ; $C0A9: 8D 16 40
|
|
00C0AC 1
|
|
00C0AC 1 A9 00 lda #$00 ; $C0AC: A9 00
|
|
00C0AE 1 8D 16 40 sta JOY1 ; $C0AE: 8D 16 40
|
|
00C0B1 1
|
|
00C0B1 1 A2 08 ldx #$08 ; $C0B1: A2 08
|
|
00C0B3 1
|
|
00C0B3 1 NMI_ReadControllers: ; $C0B3
|
|
00C0B3 1 AD 16 40 lda JOY1 ; $C0B3: AD 16 40
|
|
00C0B6 1 29 03 and #$03 ; $C0B6: 29 03
|
|
00C0B8 1 C9 01 cmp #$01 ; $C0B8: C9 01
|
|
00C0BA 1 26 15 rol ControllerPressed1 ; $C0BA: 26 15
|
|
00C0BC 1
|
|
00C0BC 1 AD 17 40 lda JOY2 ; $C0BC: AD 17 40
|
|
00C0BF 1 29 03 and #$03 ; $C0BF: 29 03
|
|
00C0C1 1 C9 01 cmp #$01 ; $C0C1: C9 01
|
|
00C0C3 1 26 16 rol ControllerPressed2 ; $C0C3: 26 16
|
|
00C0C5 1
|
|
00C0C5 1 CA dex ; $C0C5: CA
|
|
00C0C6 1 D0 EB bne NMI_ReadControllers ; $C0C6: D0 EB
|
|
00C0C8 1
|
|
00C0C8 1 A2 01 ldx #$01 ; $C0C8: A2 01
|
|
00C0CA 1
|
|
00C0CA 1 NMI_UpdateControllerState: ; $C0CA
|
|
00C0CA 1 B5 15 lda ControllerPressed1,x ; $C0CA: B5 15
|
|
00C0CC 1 A8 tay ; $C0CC: A8
|
|
00C0CD 1
|
|
00C0CD 1 55 11 eor ControllerHeld1,x ; $C0CD: 55 11
|
|
00C0CF 1 35 15 and ControllerPressed1,x ; $C0CF: 35 15
|
|
00C0D1 1
|
|
00C0D1 1 95 15 sta ControllerPressed1,x ; $C0D1: 95 15
|
|
00C0D3 1 94 11 sty ControllerHeld1,x ; $C0D3: 94 11
|
|
00C0D5 1
|
|
00C0D5 1 CA dex ; $C0D5: CA
|
|
00C0D6 1 10 F2 bpl NMI_UpdateControllerState
|
|
00C0D8 1 ; $C0D6: 10 F2
|
|
00C0D8 1
|
|
00C0D8 1 29 10 and #$10 ; $C0D8: 29 10
|
|
00C0DA 1 F0 10 beq NMI_CheckState ; $C0DA: F0 10
|
|
00C0DC 1
|
|
00C0DC 1 A5 1E lda SessionActive ; $C0DC: A5 1E
|
|
00C0DE 1 D0 07 bne NMI_RunCommand0B ; $C0DE: D0 07
|
|
00C0E0 1
|
|
00C0E0 1 85 1D sta TransitionActive ; $C0E0: 85 1D
|
|
00C0E2 1 85 EF sta GameplaySuspended ; $C0E2: 85 EF
|
|
00C0E4 1
|
|
00C0E4 1 4C 9C C4 jmp InitializeNewSession ; $C0E4: 4C 9C C4
|
|
00C0E7 1
|
|
00C0E7 1 NMI_RunCommand0B: ; $C0E7
|
|
00C0E7 1 A2 0B ldx #$0B ; $C0E7: A2 0B
|
|
00C0E9 1 20 2A EB jsr ProcessQueuedObjectEvent; $C0E9: 20 2A EB
|
|
00C0EC 1
|
|
00C0EC 1 NMI_CheckState: ; $C0EC
|
|
00C0EC 1 A5 1F lda NmiStateFlag ; $C0EC: A5 1F
|
|
00C0EE 1 D0 2C bne NMI_RestoreRegisters ; $C0EE: D0 2C
|
|
00C0F0 1
|
|
00C0F0 1 20 0A EB jsr QueueInlineObjectEvent ; $C0F0: 20 0A EB
|
|
00C0F3 1
|
|
00C0F3 1 ; Inline command data consumed by the routine at QueueInlineObjectEvent.
|
|
00C0F3 1 ; These bytes must not be assembled as 6502 instructions.
|
|
00C0F3 1 05 21 C1 .byte $05,$21,$C1 ; $C0F3-$C0F5
|
|
00C0F6 1
|
|
00C0F6 1 A2 00 ldx #$00 ; $C0F6: A2 00
|
|
00C0F8 1 20 2A EB jsr ProcessQueuedObjectEvent ; $C0F8: 20 2A EB
|
|
00C0FB 1
|
|
00C0FB 1 E6 E3 inc FrameCounter ; $C0FB: E6 E3
|
|
00C0FD 1 20 7E C8 jsr CalculateControllerAssignments ; $C0FD: 20 7E C8
|
|
00C100 1
|
|
00C100 1 A6 0F ldx DerivedControl0 ; $C100: A6 0F
|
|
00C102 1 8A txa ; $C102: 8A
|
|
00C103 1 A8 tay ; $C103: A8
|
|
00C104 1
|
|
00C104 1 F0 04 beq NMI_StoreFirstObject ; $C104: F0 04
|
|
00C106 1
|
|
00C106 1 B5 10 lda $10,x ; $C106: B5 10
|
|
00C108 1 B4 14 ldy InputState2,x ; $C108: B4 14
|
|
00C10A 1
|
|
00C10A 1 NMI_StoreFirstObject: ; $C10A
|
|
00C10A 1 85 13 sta InputState1 ; $C10A: 85 13
|
|
00C10C 1 84 17 sty InputAux1 ; $C10C: 84 17
|
|
00C10E 1
|
|
00C10E 1 A6 10 ldx $10 ; $C10E: A6 10
|
|
00C110 1 8A txa ; $C110: 8A
|
|
00C111 1 A8 tay ; $C111: A8
|
|
00C112 1
|
|
00C112 1 F0 04 beq NMI_StoreSecondObject ; $C112: F0 04
|
|
00C114 1
|
|
00C114 1 B5 10 lda $10,x ; $C114: B5 10
|
|
00C116 1 B4 14 ldy InputState2,x ; $C116: B4 14
|
|
00C118 1
|
|
00C118 1 NMI_StoreSecondObject: ; $C118
|
|
00C118 1 85 14 sta InputState2 ; $C118: 85 14
|
|
00C11A 1 84 18 sty InputAux2 ; $C11A: 84 18
|
|
00C11C 1
|
|
00C11C 1 NMI_RestoreRegisters: ; $C11C
|
|
00C11C 1 A4 0E ldy NmiSavedY ; $C11C: A4 0E
|
|
00C11E 1 A6 0D ldx NmiSavedX ; $C11E: A6 0D
|
|
00C120 1
|
|
00C120 1 68 pla ; $C120: 68
|
|
00C121 1 40 rti ; $C121: 40
|
|
00C122 1
|
|
00C122 1 ; ============================================================================
|
|
00C122 1 ; $C122-$C18C
|
|
00C122 1 ; Main-frame initialization, timer updates, and 16-bit position updates
|
|
00C122 1 ; ============================================================================
|
|
00C122 1
|
|
00C122 1 UpdateFrameObjectsAndTimers: ; $C122
|
|
00C122 1 A2 00 ldx #$00 ; $C122: A2 00
|
|
00C124 1
|
|
00C124 1 86 3E stx PpuQueueOffset ; $C124: 86 3E
|
|
00C126 1 86 3F stx OamWriteOffset ; $C126: 86 3F
|
|
00C128 1 86 20 stx FrameState20 ; $C128: 86 20
|
|
00C12A 1
|
|
00C12A 1 20 0A EB jsr QueueInlineObjectEvent ; $C12A: 20 0A EB
|
|
00C12D 1
|
|
00C12D 1 ; Inline command data consumed by the routine at QueueInlineObjectEvent.
|
|
00C12D 1 07 64 C2 .byte $07,$64,$C2 ; $C12D-$C12F
|
|
00C130 1
|
|
00C130 1 A2 01 ldx #$01 ; $C130: A2 01
|
|
00C132 1 20 2A EB jsr ProcessQueuedObjectEvent ; $C132: 20 2A EB
|
|
00C135 1
|
|
00C135 1 A2 30 ldx #$30 ; $C135: A2 30
|
|
00C137 1
|
|
00C137 1 UpdateObjectTimerLoop: ; $C137
|
|
00C137 1 BD 3F 06 lda $063F,x ; $C137: BD 3F 06
|
|
00C13A 1 F0 08 beq UpdateNextObjectTimer ; $C13A: F0 08
|
|
00C13C 1
|
|
00C13C 1 DE 3F 06 dec $063F,x ; $C13C: DE 3F 06
|
|
00C13F 1 D0 03 bne UpdateNextObjectTimer ; $C13F: D0 03
|
|
00C141 1
|
|
00C141 1 20 15 EB jsr QueueDecodedObjectEventSelectIndex ; $C141: 20 15 EB
|
|
00C144 1
|
|
00C144 1 UpdateNextObjectTimer: ; $C144
|
|
00C144 1 CA dex ; $C144: CA
|
|
00C145 1 D0 F0 bne UpdateObjectTimerLoop ; $C145: D0 F0
|
|
00C147 1
|
|
00C147 1 A2 03 ldx #$03 ; $C147: A2 03
|
|
00C149 1
|
|
00C149 1 UpdateShortCountdowns: ; $C149
|
|
00C149 1 DE AD 05 dec $05AD,x ; $C149: DE AD 05
|
|
00C14C 1 10 03 bpl UpdateNextShortCountdown
|
|
00C14E 1 ; $C14C: 10 03
|
|
00C14E 1
|
|
00C14E 1 FE AD 05 inc $05AD,x ; $C14E: FE AD 05
|
|
00C151 1
|
|
00C151 1 UpdateNextShortCountdown: ; $C151
|
|
00C151 1 CA dex ; $C151: CA
|
|
00C152 1 10 F5 bpl UpdateShortCountdowns
|
|
00C154 1 ; $C152: 10 F5
|
|
00C154 1
|
|
00C154 1 A5 1D lda TransitionActive ; $C154: A5 1D
|
|
00C156 1 F0 03 beq IntegrateAllObjectPositions
|
|
00C158 1 ; $C156: F0 03
|
|
00C158 1
|
|
00C158 1 4C 6A EB jmp CommonEngineExit ; $C158: 4C 6A EB
|
|
00C15B 1
|
|
00C15B 1 IntegrateAllObjectPositions: ; $C15B
|
|
00C15B 1 A2 24 ldx #$24 ; $C15B: A2 24
|
|
00C15D 1
|
|
00C15D 1 ; Each logical object occupies two adjacent indices.
|
|
00C15D 1 ; X advances by two after both coordinate pairs are updated.
|
|
00C15D 1
|
|
00C15D 1 IntegrateObjectPositionLoop: ; $C15D
|
|
00C15D 1 A0 00 ldy #$00 ; $C15D: A0 00
|
|
00C15F 1
|
|
00C15F 1 BD 6F 05 lda $056F,x ; $C15F: BD 6F 05
|
|
00C162 1 10 01 bpl AddObjectHorizontalDelta ; $C162: 10 01
|
|
00C164 1
|
|
00C164 1 88 dey ; $C164: 88
|
|
00C165 1 ; Sign-extend the low-byte delta.
|
|
00C165 1
|
|
00C165 1 AddObjectHorizontalDelta: ; $C165
|
|
00C165 1 18 clc ; $C165: 18
|
|
00C166 1
|
|
00C166 1 7D 0B 05 adc $050B,x ; $C166: 7D 0B 05
|
|
00C169 1 9D 0B 05 sta $050B,x ; $C169: 9D 0B 05
|
|
00C16C 1
|
|
00C16C 1 98 tya ; $C16C: 98
|
|
00C16D 1 7D 0C 05 adc $050C,x ; $C16D: 7D 0C 05
|
|
00C170 1 9D 0C 05 sta $050C,x ; $C170: 9D 0C 05
|
|
00C173 1
|
|
00C173 1 A0 00 ldy #$00 ; $C173: A0 00
|
|
00C175 1
|
|
00C175 1 BD 70 05 lda $0570,x ; $C175: BD 70 05
|
|
00C178 1 10 01 bpl AddObjectVerticalDelta ; $C178: 10 01
|
|
00C17A 1
|
|
00C17A 1 88 dey ; $C17A: 88
|
|
00C17B 1 ; Sign-extend the second delta.
|
|
00C17B 1
|
|
00C17B 1 AddObjectVerticalDelta: ; $C17B
|
|
00C17B 1 18 clc ; $C17B: 18
|
|
00C17C 1
|
|
00C17C 1 7D 3C 05 adc $053C,x ; $C17C: 7D 3C 05
|
|
00C17F 1 9D 3C 05 sta $053C,x ; $C17F: 9D 3C 05
|
|
00C182 1
|
|
00C182 1 98 tya ; $C182: 98
|
|
00C183 1 7D 3D 05 adc $053D,x ; $C183: 7D 3D 05
|
|
00C186 1 9D 3D 05 sta $053D,x ; $C186: 9D 3D 05
|
|
00C189 1
|
|
00C189 1 CA dex ; $C189: CA
|
|
00C18A 1 CA dex ; $C18A: CA
|
|
00C18B 1
|
|
00C18B 1 10 D0 bpl IntegrateObjectPositionLoop
|
|
00C18D 1 ; $C18B: 10 D0
|
|
00C18D 1
|
|
00C18D 1 ; ============================================================================
|
|
00C18D 1 ; $C18D-$C264
|
|
00C18D 1 ; Object processing, signed coordinate adjustment, and state handling
|
|
00C18D 1 ; ============================================================================
|
|
00C18D 1
|
|
00C18D 1 UpdateBaseMotionSequence: ; $C18D
|
|
00C18D 1 A2 00 ldx #$00 ; $C18D: A2 00
|
|
00C18F 1 20 CA C3 jsr IntegrateObjectVelocityAndPosition ; $C18F: 20 CA C3
|
|
00C192 1
|
|
00C192 1 A2 31 ldx #$31 ; $C192: A2 31
|
|
00C194 1 20 CA C3 jsr IntegrateObjectVelocityAndPosition ; $C194: 20 CA C3
|
|
00C197 1
|
|
00C197 1 A2 62 ldx #$62 ; $C197: A2 62
|
|
00C199 1 20 CA C3 jsr IntegrateObjectVelocityAndPosition ; $C199: 20 CA C3
|
|
00C19C 1
|
|
00C19C 1 AD 6C 05 lda $056C ; $C19C: AD 6C 05
|
|
00C19F 1 30 03 bmi ReflectBaseMotionValues
|
|
00C1A1 1 ; $C19F: 30 03
|
|
00C1A1 1
|
|
00C1A1 1 4C 28 C2 jmp UpdatePositionSignState ; $C1A1: 4C 28 C2
|
|
00C1A4 1
|
|
00C1A4 1 ; ----------------------------------------------------------------------------
|
|
00C1A4 1 ; Negate the signed values at $056B/$056C and $0569/$056A.
|
|
00C1A4 1 ; The second result is divided by two using LSR/ROR.
|
|
00C1A4 1 ; ----------------------------------------------------------------------------
|
|
00C1A4 1
|
|
00C1A4 1 ReflectBaseMotionValues: ; $C1A4
|
|
00C1A4 1 A0 00 ldy #$00 ; $C1A4: A0 00
|
|
00C1A6 1 38 sec ; $C1A6: 38
|
|
00C1A7 1
|
|
00C1A7 1 98 tya ; $C1A7: 98
|
|
00C1A8 1 ED 6B 05 sbc $056B ; $C1A8: ED 6B 05
|
|
00C1AB 1 8D 6B 05 sta $056B ; $C1AB: 8D 6B 05
|
|
00C1AE 1
|
|
00C1AE 1 98 tya ; $C1AE: 98
|
|
00C1AF 1 ED 6C 05 sbc $056C ; $C1AF: ED 6C 05
|
|
00C1B2 1 8D 6C 05 sta $056C ; $C1B2: 8D 6C 05
|
|
00C1B5 1
|
|
00C1B5 1 38 sec ; $C1B5: 38
|
|
00C1B6 1
|
|
00C1B6 1 98 tya ; $C1B6: 98
|
|
00C1B7 1 ED 69 05 sbc $0569 ; $C1B7: ED 69 05
|
|
00C1BA 1 8D 69 05 sta $0569 ; $C1BA: 8D 69 05
|
|
00C1BD 1
|
|
00C1BD 1 98 tya ; $C1BD: 98
|
|
00C1BE 1 ED 6A 05 sbc $056A ; $C1BE: ED 6A 05
|
|
00C1C1 1
|
|
00C1C1 1 4A lsr ; $C1C1: 4A
|
|
00C1C2 1 8D 6A 05 sta $056A ; $C1C2: 8D 6A 05
|
|
00C1C5 1 6E 69 05 ror $0569 ; $C1C5: 6E 69 05
|
|
00C1C8 1
|
|
00C1C8 1 ; ----------------------------------------------------------------------------
|
|
00C1C8 1 ; Subtract twice the signed value in $0508 from $0507/$0508.
|
|
00C1C8 1 ; ----------------------------------------------------------------------------
|
|
00C1C8 1
|
|
00C1C8 1 A0 00 ldy #$00 ; $C1C8: A0 00
|
|
00C1CA 1
|
|
00C1CA 1 AD 08 05 lda $0508 ; $C1CA: AD 08 05
|
|
00C1CD 1 10 01 bpl DoubleHorizontalVelocity
|
|
00C1CF 1 ; $C1CD: 10 01
|
|
00C1CF 1
|
|
00C1CF 1 88 dey ; $C1CF: 88
|
|
00C1D0 1
|
|
00C1D0 1 DoubleHorizontalVelocity: ; $C1D0
|
|
00C1D0 1 0A asl ; $C1D0: 0A
|
|
00C1D1 1 85 07 sta $07 ; $C1D1: 85 07
|
|
00C1D3 1
|
|
00C1D3 1 98 tya ; $C1D3: 98
|
|
00C1D4 1 2A rol ; $C1D4: 2A
|
|
00C1D5 1 85 08 sta $08 ; $C1D5: 85 08
|
|
00C1D7 1
|
|
00C1D7 1 38 sec ; $C1D7: 38
|
|
00C1D8 1
|
|
00C1D8 1 AD 07 05 lda $0507 ; $C1D8: AD 07 05
|
|
00C1DB 1 E5 07 sbc $07 ; $C1DB: E5 07
|
|
00C1DD 1 8D 07 05 sta $0507 ; $C1DD: 8D 07 05
|
|
00C1E0 1
|
|
00C1E0 1 AD 08 05 lda $0508 ; $C1E0: AD 08 05
|
|
00C1E3 1 E5 08 sbc $08 ; $C1E3: E5 08
|
|
00C1E5 1 8D 08 05 sta $0508 ; $C1E5: 8D 08 05
|
|
00C1E8 1
|
|
00C1E8 1 ; ----------------------------------------------------------------------------
|
|
00C1E8 1 ; Repeat the signed adjustment for $0538/$0539.
|
|
00C1E8 1 ; ----------------------------------------------------------------------------
|
|
00C1E8 1
|
|
00C1E8 1 A0 00 ldy #$00 ; $C1E8: A0 00
|
|
00C1EA 1
|
|
00C1EA 1 AD 39 05 lda $0539 ; $C1EA: AD 39 05
|
|
00C1ED 1 10 01 bpl DoubleVerticalVelocity
|
|
00C1EF 1 ; $C1ED: 10 01
|
|
00C1EF 1
|
|
00C1EF 1 88 dey ; $C1EF: 88
|
|
00C1F0 1
|
|
00C1F0 1 DoubleVerticalVelocity: ; $C1F0
|
|
00C1F0 1 0A asl ; $C1F0: 0A
|
|
00C1F1 1 85 07 sta $07 ; $C1F1: 85 07
|
|
00C1F3 1
|
|
00C1F3 1 98 tya ; $C1F3: 98
|
|
00C1F4 1 2A rol ; $C1F4: 2A
|
|
00C1F5 1 85 08 sta $08 ; $C1F5: 85 08
|
|
00C1F7 1
|
|
00C1F7 1 38 sec ; $C1F7: 38
|
|
00C1F8 1
|
|
00C1F8 1 AD 38 05 lda $0538 ; $C1F8: AD 38 05
|
|
00C1FB 1 E5 07 sbc $07 ; $C1FB: E5 07
|
|
00C1FD 1 8D 38 05 sta $0538 ; $C1FD: 8D 38 05
|
|
00C200 1
|
|
00C200 1 AD 39 05 lda $0539 ; $C200: AD 39 05
|
|
00C203 1 E5 08 sbc $08 ; $C203: E5 08
|
|
00C205 1 8D 39 05 sta $0539 ; $C205: 8D 39 05
|
|
00C208 1
|
|
00C208 1 20 D2 CA jsr EvaluateTrajectoryResult ; $C208: 20 D2 CA
|
|
00C20B 1
|
|
00C20B 1 ; ----------------------------------------------------------------------------
|
|
00C20B 1 ; Advance state and refresh coordinate-related values.
|
|
00C20B 1 ; ----------------------------------------------------------------------------
|
|
00C20B 1
|
|
00C20B 1 A5 5D lda BaseMotionPhase ; $C20B: A5 5D
|
|
00C20D 1 C9 03 cmp #$03 ; $C20D: C9 03
|
|
00C20F 1 B0 04 bcs AdvanceBaseMotionPhase
|
|
00C211 1 ; $C20F: B0 04
|
|
00C211 1
|
|
00C211 1 A9 10 lda #$10 ; $C211: A9 10
|
|
00C213 1 85 FF sta RenderStateFlags ; $C213: 85 FF
|
|
00C215 1
|
|
00C215 1 AdvanceBaseMotionPhase: ; $C215
|
|
00C215 1 E6 5D inc BaseMotionPhase ; $C215: E6 5D
|
|
00C217 1
|
|
00C217 1 AD 08 05 lda $0508 ; $C217: AD 08 05
|
|
00C21A 1 0D 39 05 ora $0539 ; $C21A: 0D 39 05
|
|
00C21D 1 0D 6A 05 ora $056A ; $C21D: 0D 6A 05
|
|
00C220 1 D0 06 bne UpdatePositionSignState ; $C220: D0 06
|
|
00C222 1
|
|
00C222 1 20 43 C9 jsr ClearBaseAccelerationFields ; $C222: 20 43 C9
|
|
00C225 1 20 4F C9 jsr ClearBasePositionFields ; $C225: 20 4F C9
|
|
00C228 1
|
|
00C228 1 ; ----------------------------------------------------------------------------
|
|
00C228 1 ; Calculate a signed magnitude from the current position.
|
|
00C228 1 ; ----------------------------------------------------------------------------
|
|
00C228 1
|
|
00C228 1 UpdatePositionSignState: ; $C228
|
|
00C228 1 38 sec ; $C228: 38
|
|
00C229 1
|
|
00C229 1 AD 3B 05 lda $053B ; $C229: AD 3B 05
|
|
00C22C 1 E9 0A sbc #$0A ; $C22C: E9 0A
|
|
00C22E 1 10 0A bpl SaveSignedPositionDelta ; $C22E: 10 0A
|
|
00C230 1
|
|
00C230 1 AD 0A 05 lda $050A ; $C230: AD 0A 05
|
|
00C233 1 10 02 bpl SubtractPositionThreshold ; $C233: 10 02
|
|
00C235 1
|
|
00C235 1 49 FF eor #$FF ; $C235: 49 FF
|
|
00C237 1
|
|
00C237 1 SubtractPositionThreshold: ; $C237
|
|
00C237 1 38 sec ; $C237: 38
|
|
00C238 1 E9 0A sbc #$0A ; $C238: E9 0A
|
|
00C23A 1
|
|
00C23A 1 SaveSignedPositionDelta: ; $C23A
|
|
00C23A 1 48 pha ; $C23A: 48
|
|
00C23B 1
|
|
00C23B 1 45 B7 eor PositionSignState ; $C23B: 45 B7
|
|
00C23D 1 10 0A bpl CommitSignedPositionDelta
|
|
00C23F 1 ; $C23D: 10 0A
|
|
00C23F 1
|
|
00C23F 1 A5 42 lda CurrentObjectArrayOffset ; $C23F: A5 42
|
|
00C241 1 D0 06 bne CommitSignedPositionDelta
|
|
00C243 1 ; $C241: D0 06
|
|
00C243 1
|
|
00C243 1 20 0A EB jsr QueueInlineObjectEvent ; $C243: 20 0A EB
|
|
00C246 1
|
|
00C246 1 ; Inline command data consumed by the routine at QueueInlineObjectEvent.
|
|
00C246 1 23 52 C2 .byte $23,$52,$C2 ; $C246-$C248
|
|
00C249 1
|
|
00C249 1 CommitSignedPositionDelta: ; $C249
|
|
00C249 1 68 pla ; $C249: 68
|
|
00C24A 1 85 B7 sta PositionSignState ; $C24A: 85 B7
|
|
00C24C 1
|
|
00C24C 1 0A asl ; $C24C: 0A
|
|
00C24D 1 20 46 E7 jsr InitializeRenderingStateFromCarry ; $C24D: 20 46 E7
|
|
00C250 1
|
|
00C250 1 4C 6A EB jmp CommonEngineExit ; $C250: 4C 6A EB
|
|
00C253 1
|
|
00C253 1 ; ----------------------------------------------------------------------------
|
|
00C253 1 ; Alternate object/state path.
|
|
00C253 1 ; ----------------------------------------------------------------------------
|
|
00C253 1
|
|
00C253 1 UpdateAllGameplayObjects: ; $C253
|
|
00C253 1 A2 26 ldx #$26 ; $C253: A2 26
|
|
00C255 1
|
|
00C255 1 UpdateNextGameplayObject: ; $C255
|
|
00C255 1 86 42 stx CurrentObjectArrayOffset ; $C255: 86 42
|
|
00C257 1 20 B7 E6 jsr ClearMovementTransforms ; $C257: 20 B7 E6
|
|
00C25A 1
|
|
00C25A 1 A6 42 ldx CurrentObjectArrayOffset ; $C25A: A6 42
|
|
00C25C 1 CA dex ; $C25C: CA
|
|
00C25D 1 CA dex ; $C25D: CA
|
|
00C25E 1 D0 F5 bne UpdateNextGameplayObject ; $C25E: D0 F5
|
|
00C260 1
|
|
00C260 1 86 42 stx CurrentObjectArrayOffset ; $C260: 86 42
|
|
00C262 1 4C 6A EB jmp CommonEngineExit ; $C262: 4C 6A EB
|
|
00C265 1
|
|
00C265 1 ; ============================================================================
|
|
00C265 1 ; $C265-$C2DD
|
|
00C265 1 ; Select object sprite attributes and animation tiles.
|
|
00C265 1 ; ============================================================================
|
|
00C265 1
|
|
00C265 1 UpdateBaseObjectSprites: ; $C265
|
|
00C265 1 A5 5C lda BaseMotionActive ; $C265: A5 5C
|
|
00C267 1 F0 67 beq SetDefaultBaseObjectTile
|
|
00C269 1 ; $C267: F0 67
|
|
00C269 1
|
|
00C269 1 A5 FF lda RenderStateFlags ; $C269: A5 FF
|
|
00C26B 1 AE 6C 05 ldx $056C ; $C26B: AE 6C 05
|
|
00C26E 1
|
|
00C26E 1 E0 03 cpx #$03 ; $C26E: E0 03
|
|
00C270 1 90 09 bcc SaveBaseObjectRenderFlags ; $C270: 90 09
|
|
00C272 1
|
|
00C272 1 09 20 ora #$20 ; $C272: 09 20
|
|
00C274 1
|
|
00C274 1 AE 6A 05 ldx $056A ; $C274: AE 6A 05
|
|
00C277 1 10 02 bpl SaveBaseObjectRenderFlags ; $C277: 10 02
|
|
00C279 1
|
|
00C279 1 09 40 ora #$40 ; $C279: 09 40
|
|
00C27B 1
|
|
00C27B 1 SaveBaseObjectRenderFlags: ; $C27B
|
|
00C27B 1 85 FF sta RenderStateFlags ; $C27B: 85 FF
|
|
00C27D 1
|
|
00C27D 1 20 73 E6 jsr BuildCurrentMovementTransforms ; $C27D: 20 73 E6
|
|
00C280 1 B0 21 bcs SelectSecondaryAnimationTile
|
|
00C282 1 ; $C280: B0 21
|
|
00C282 1
|
|
00C282 1 9D DD 03 sta $03DD,x ; $C282: 9D DD 03
|
|
00C285 1
|
|
00C285 1 A5 36 lda ObjectScreenX ; $C285: A5 36
|
|
00C287 1 9D BB 03 sta $03BB,x ; $C287: 9D BB 03
|
|
00C28A 1
|
|
00C28A 1 ; ----------------------------------------------------------------------------
|
|
00C28A 1 ; Select the first animation tile according to the value in $2E.
|
|
00C28A 1 ; ----------------------------------------------------------------------------
|
|
00C28A 1
|
|
00C28A 1 A4 2E ldy $2E ; $C28A: A4 2E
|
|
00C28C 1
|
|
00C28C 1 A9 76 lda #$76 ; $C28C: A9 76
|
|
00C28E 1 C0 20 cpy #$20 ; $C28E: C0 20
|
|
00C290 1 B0 0E bcs StorePrimaryAnimationTile
|
|
00C292 1 ; $C290: B0 0E
|
|
00C292 1
|
|
00C292 1 A9 77 lda #$77 ; $C292: A9 77
|
|
00C294 1 C0 12 cpy #$12 ; $C294: C0 12
|
|
00C296 1 B0 08 bcs StorePrimaryAnimationTile
|
|
00C298 1 ; $C296: B0 08
|
|
00C298 1
|
|
00C298 1 A9 78 lda #$78 ; $C298: A9 78
|
|
00C29A 1 C0 08 cpy #$08 ; $C29A: C0 08
|
|
00C29C 1 B0 02 bcs StorePrimaryAnimationTile
|
|
00C29E 1 ; $C29C: B0 02
|
|
00C29E 1
|
|
00C29E 1 A9 79 lda #$79 ; $C29E: A9 79
|
|
00C2A0 1
|
|
00C2A0 1 StorePrimaryAnimationTile: ; $C2A0
|
|
00C2A0 1 9D 99 03 sta $0399,x ; $C2A0: 9D 99 03
|
|
00C2A3 1
|
|
00C2A3 1 ; ----------------------------------------------------------------------------
|
|
00C2A3 1 ; Select the second animation tile.
|
|
00C2A3 1 ; ----------------------------------------------------------------------------
|
|
00C2A3 1
|
|
00C2A3 1 SelectSecondaryAnimationTile: ; $C2A3
|
|
00C2A3 1 20 95 E6 jsr BuildBaseMovementTransforms ; $C2A3: 20 95 E6
|
|
00C2A6 1 B0 2F bcs SetFinalBaseObjectTile
|
|
00C2A8 1 ; $C2A6: B0 2F
|
|
00C2A8 1
|
|
00C2A8 1 A4 2E ldy $2E ; $C2A8: A4 2E
|
|
00C2AA 1
|
|
00C2AA 1 A9 7A lda #$7A ; $C2AA: A9 7A
|
|
00C2AC 1 C0 20 cpy #$20 ; $C2AC: C0 20
|
|
00C2AE 1 B0 1A bcs StoreSecondaryAnimationTile
|
|
00C2B0 1 ; $C2AE: B0 1A
|
|
00C2B0 1
|
|
00C2B0 1 A9 71 lda #$71 ; $C2B0: A9 71
|
|
00C2B2 1 C0 12 cpy #$12 ; $C2B2: C0 12
|
|
00C2B4 1 B0 14 bcs StoreSecondaryAnimationTile
|
|
00C2B6 1 ; $C2B4: B0 14
|
|
00C2B6 1
|
|
00C2B6 1 A9 72 lda #$72 ; $C2B6: A9 72
|
|
00C2B8 1 C0 08 cpy #$08 ; $C2B8: C0 08
|
|
00C2BA 1 B0 0E bcs StoreSecondaryAnimationTile
|
|
00C2BC 1 ; $C2BA: B0 0E
|
|
00C2BC 1
|
|
00C2BC 1 A9 73 lda #$73 ; $C2BC: A9 73
|
|
00C2BE 1 C0 05 cpy #$05 ; $C2BE: C0 05
|
|
00C2C0 1 B0 08 bcs StoreSecondaryAnimationTile
|
|
00C2C2 1 ; $C2C0: B0 08
|
|
00C2C2 1
|
|
00C2C2 1 A9 74 lda #$74 ; $C2C2: A9 74
|
|
00C2C4 1 C0 03 cpy #$03 ; $C2C4: C0 03
|
|
00C2C6 1 B0 02 bcs StoreSecondaryAnimationTile
|
|
00C2C8 1 ; $C2C6: B0 02
|
|
00C2C8 1
|
|
00C2C8 1 A9 75 lda #$75 ; $C2C8: A9 75
|
|
00C2CA 1
|
|
00C2CA 1 StoreSecondaryAnimationTile: ; $C2CA
|
|
00C2CA 1 9D 9A 03 sta $039A,x ; $C2CA: 9D 9A 03
|
|
00C2CD 1
|
|
00C2CD 1 4C DE C2 jmp BuildFrameOam ; $C2CD: 4C DE C2
|
|
00C2D0 1
|
|
00C2D0 1 ; ----------------------------------------------------------------------------
|
|
00C2D0 1 ; Default tile path when $5C is zero.
|
|
00C2D0 1 ; ----------------------------------------------------------------------------
|
|
00C2D0 1
|
|
00C2D0 1 SetDefaultBaseObjectTile: ; $C2D0
|
|
00C2D0 1 A6 C9 ldx SpriteSortBaseIndex ; $C2D0: A6 C9
|
|
00C2D2 1
|
|
00C2D2 1 A9 7A lda #$7A ; $C2D2: A9 7A
|
|
00C2D4 1 9D 9A 03 sta $039A,x ; $C2D4: 9D 9A 03
|
|
00C2D7 1
|
|
00C2D7 1 SetFinalBaseObjectTile: ; $C2D7
|
|
00C2D7 1 A6 C9 ldx SpriteSortBaseIndex ; $C2D7: A6 C9
|
|
00C2D9 1
|
|
00C2D9 1 A9 7A lda #$7A ; $C2D9: A9 7A
|
|
00C2DB 1 9D 9B 03 sta $039B,x ; $C2DB: 9D 9B 03
|
|
00C2DE 1
|
|
00C2DE 1 ; ============================================================================
|
|
00C2DE 1 ; $C2DE-$C330
|
|
00C2DE 1 ; Initialize OAM entries for the current game state.
|
|
00C2DE 1 ; ============================================================================
|
|
00C2DE 1
|
|
00C2DE 1 BuildFrameOam: ; $C2DE
|
|
00C2DE 1 A5 1D lda TransitionActive ; $C2DE: A5 1D
|
|
00C2E0 1 F0 13 beq CheckOamBuildMode ; $C2E0: F0 13
|
|
00C2E2 1
|
|
00C2E2 1 ; ----------------------------------------------------------------------------
|
|
00C2E2 1 ; Copy a 88-byte sprite/OAM template from $F94D into shadow OAM at $0200.
|
|
00C2E2 1 ; ----------------------------------------------------------------------------
|
|
00C2E2 1
|
|
00C2E2 1 A2 00 ldx #$00 ; $C2E2: A2 00
|
|
00C2E4 1 A0 58 ldy #$58 ; $C2E4: A0 58
|
|
00C2E6 1
|
|
00C2E6 1 CopyTransitionOamTemplate: ; $C2E6
|
|
00C2E6 1 BD 4D F9 lda FrameOamTemplate_F94D,x ; $C2E6: BD 4D F9
|
|
00C2E9 1 9D 00 02 sta $0200,x ; $C2E9: 9D 00 02
|
|
00C2EC 1
|
|
00C2EC 1 E8 inx ; $C2EC: E8
|
|
00C2ED 1 88 dey ; $C2ED: 88
|
|
00C2EE 1 D0 F6 bne CopyTransitionOamTemplate
|
|
00C2F0 1 ; $C2EE: D0 F6
|
|
00C2F0 1
|
|
00C2F0 1 86 3F stx OamWriteOffset ; $C2F0: 86 3F
|
|
00C2F2 1 4C AA C3 jmp TerminatePpuUpdateQueue
|
|
00C2F5 1 ; $C2F2: 4C AA C3
|
|
00C2F5 1
|
|
00C2F5 1 ; ----------------------------------------------------------------------------
|
|
00C2F5 1 ; Alternate path used when $1D is zero.
|
|
00C2F5 1 ; ----------------------------------------------------------------------------
|
|
00C2F5 1
|
|
00C2F5 1 CheckOamBuildMode: ; $C2F5
|
|
00C2F5 1 A5 44 lda PlayerSelectionActive ; $C2F5: A5 44
|
|
00C2F7 1 F0 40 beq SortObjectsByY ; $C2F7: F0 40
|
|
00C2F9 1
|
|
00C2F9 1 ; ----------------------------------------------------------------------------
|
|
00C2F9 1 ; Copy an eight-byte OAM template from $C331 into $0200-$0207.
|
|
00C2F9 1 ; The table itself remains in the following .incbin region for now.
|
|
00C2F9 1 ; ----------------------------------------------------------------------------
|
|
00C2F9 1
|
|
00C2F9 1 A2 07 ldx #$07 ; $C2F9: A2 07
|
|
00C2FB 1
|
|
00C2FB 1 CopySelectionOamTemplate: ; $C2FB
|
|
00C2FB 1 BD 31 C3 lda $C331,x ; $C2FB: BD 31 C3
|
|
00C2FE 1 9D 00 02 sta $0200,x ; $C2FE: 9D 00 02
|
|
00C301 1
|
|
00C301 1 CA dex ; $C301: CA
|
|
00C302 1 10 F7 bpl CopySelectionOamTemplate
|
|
00C304 1 ; $C302: 10 F7
|
|
00C304 1
|
|
00C304 1 ; ----------------------------------------------------------------------------
|
|
00C304 1 ; Position the first sprite using the selected player's coordinate.
|
|
00C304 1 ; Each value is multiplied by 16 and offset by $50.
|
|
00C304 1 ; ----------------------------------------------------------------------------
|
|
00C304 1
|
|
00C304 1 A6 4B ldx ActivePlayerSide ; $C304: A6 4B
|
|
00C306 1
|
|
00C306 1 B5 34 lda PlayerOneSelection,x ; $C306: B5 34
|
|
00C308 1 0A asl ; $C308: 0A
|
|
00C309 1 0A asl ; $C309: 0A
|
|
00C30A 1 0A asl ; $C30A: 0A
|
|
00C30B 1 0A asl ; $C30B: 0A
|
|
00C30C 1
|
|
00C30C 1 69 50 adc #$50 ; $C30C: 69 50
|
|
00C30E 1 8D 03 02 sta $0203 ; $C30E: 8D 03 02
|
|
00C311 1
|
|
00C311 1 ; ----------------------------------------------------------------------------
|
|
00C311 1 ; Position the second sprite using the opposite player's coordinate.
|
|
00C311 1 ; ----------------------------------------------------------------------------
|
|
00C311 1
|
|
00C311 1 8A txa ; $C311: 8A
|
|
00C312 1 49 01 eor #$01 ; $C312: 49 01
|
|
00C314 1 AA tax ; $C314: AA
|
|
00C315 1
|
|
00C315 1 B5 34 lda PlayerOneSelection,x ; $C315: B5 34
|
|
00C317 1 0A asl ; $C317: 0A
|
|
00C318 1 0A asl ; $C318: 0A
|
|
00C319 1 0A asl ; $C319: 0A
|
|
00C31A 1 0A asl ; $C31A: 0A
|
|
00C31B 1
|
|
00C31B 1 69 50 adc #$50 ; $C31B: 69 50
|
|
00C31D 1 8D 07 02 sta $0207 ; $C31D: 8D 07 02
|
|
00C320 1
|
|
00C320 1 ; ----------------------------------------------------------------------------
|
|
00C320 1 ; Choose the tile used by the second sprite.
|
|
00C320 1 ; ----------------------------------------------------------------------------
|
|
00C320 1
|
|
00C320 1 A5 40 lda ModeFlags ; $C320: A5 40
|
|
00C322 1 4A lsr ; $C322: 4A
|
|
00C323 1 B0 05 bcs FinishSelectionOam ; $C323: B0 05
|
|
00C325 1
|
|
00C325 1 A9 AC lda #$AC ; $C325: A9 AC
|
|
00C327 1 8D 05 02 sta $0205 ; $C327: 8D 05 02
|
|
00C32A 1
|
|
00C32A 1 FinishSelectionOam: ; $C32A
|
|
00C32A 1 A2 08 ldx #$08 ; $C32A: A2 08
|
|
00C32C 1 86 3F stx OamWriteOffset ; $C32C: 86 3F
|
|
00C32E 1
|
|
00C32E 1 4C 86 C3 jmp FinalizeOamAndPpuQueue ; $C32E: 4C 86 C3
|
|
00C331 1
|
|
00C331 1 ; ============================================================================
|
|
00C331 1 ; $C331-$C338
|
|
00C331 1 ; Eight-byte OAM template referenced by the code at $C2FB.
|
|
00C331 1 ; ============================================================================
|
|
00C331 1
|
|
00C331 1 OAMTemplate_C331: ; $C331
|
|
00C331 1 77 A2 03 00 .byte $77,$A2,$03,$00 ; $C331-$C334
|
|
00C335 1 77 A4 03 00 .byte $77,$A4,$03,$00 ; $C335-$C338
|
|
00C339 1
|
|
00C339 1 ; ============================================================================
|
|
00C339 1 ; $C339-$C385
|
|
00C339 1 ; Sort object indices by their signed 16-bit coordinates, then emit sprite
|
|
00C339 1 ; information in the resulting order.
|
|
00C339 1 ; ============================================================================
|
|
00C339 1
|
|
00C339 1 SortObjectsByY: ; $C339
|
|
00C339 1 A4 C9 ldy SpriteSortBaseIndex ; $C339: A4 C9
|
|
00C33B 1
|
|
00C33B 1 C8 iny ; $C33B: C8
|
|
00C33C 1
|
|
00C33C 1 SortNextObjectPair: ; $C33C
|
|
00C33C 1 84 22 sty $22 ; $C33C: 84 22
|
|
00C33E 1
|
|
00C33E 1 BE 78 03 ldx $0378,y ; $C33E: BE 78 03
|
|
00C341 1 B9 77 03 lda $0377,y ; $C341: B9 77 03
|
|
00C344 1 A8 tay ; $C344: A8
|
|
00C345 1
|
|
00C345 1 ; ----------------------------------------------------------------------------
|
|
00C345 1 ; Compare the signed 16-bit values at:
|
|
00C345 1 ;
|
|
00C345 1 ; $0538,X / $0539,X
|
|
00C345 1 ; $0538,Y / $0539,Y
|
|
00C345 1 ;
|
|
00C345 1 ; The subtraction is used only for ordering. If the X entry sorts before the
|
|
00C345 1 ; Y entry, their indices in $0377/$0378 are exchanged.
|
|
00C345 1 ; ----------------------------------------------------------------------------
|
|
00C345 1
|
|
00C345 1 BD 38 05 lda $0538,x ; $C345: BD 38 05
|
|
00C348 1 D9 38 05 cmp $0538,y ; $C348: D9 38 05
|
|
00C34B 1
|
|
00C34B 1 BD 39 05 lda $0539,x ; $C34B: BD 39 05
|
|
00C34E 1 F9 39 05 sbc $0539,y ; $C34E: F9 39 05
|
|
00C351 1
|
|
00C351 1 10 0A bpl ContinueObjectDepthSort
|
|
00C353 1 ; $C351: 10 0A
|
|
00C353 1
|
|
00C353 1 98 tya ; $C353: 98
|
|
00C354 1
|
|
00C354 1 A4 22 ldy $22 ; $C354: A4 22
|
|
00C356 1 99 78 03 sta $0378,y ; $C356: 99 78 03
|
|
00C359 1
|
|
00C359 1 8A txa ; $C359: 8A
|
|
00C35A 1 99 77 03 sta $0377,y ; $C35A: 99 77 03
|
|
00C35D 1
|
|
00C35D 1 ContinueObjectDepthSort: ; $C35D
|
|
00C35D 1 A4 22 ldy $22 ; $C35D: A4 22
|
|
00C35F 1 C8 iny ; $C35F: C8
|
|
00C360 1
|
|
00C360 1 C4 CA cpy $CA ; $C360: C4 CA
|
|
00C362 1 90 D8 bcc SortNextObjectPair ; $C362: 90 D8
|
|
00C364 1
|
|
00C364 1 A4 C9 ldy SpriteSortBaseIndex ; $C364: A4 C9
|
|
00C366 1
|
|
00C366 1 RenderNextSortedObject: ; $C366
|
|
00C366 1 B9 78 03 lda $0378,y ; $C366: B9 78 03
|
|
00C369 1 4A lsr ; $C369: 4A
|
|
00C36A 1 65 C9 adc SpriteSortBaseIndex ; $C36A: 65 C9
|
|
00C36C 1 AA tax ; $C36C: AA
|
|
00C36D 1
|
|
00C36D 1 BD BC 03 lda $03BC,x ; $C36D: BD BC 03
|
|
00C370 1 85 36 sta ObjectScreenX ; $C370: 85 36
|
|
00C372 1
|
|
00C372 1 BD DE 03 lda $03DE,x ; $C372: BD DE 03
|
|
00C375 1 85 38 sta ObjectScreenY ; $C375: 85 38
|
|
00C377 1
|
|
00C377 1 BD 9A 03 lda $039A,x ; $C377: BD 9A 03
|
|
00C37A 1
|
|
00C37A 1 84 22 sty $22 ; $C37A: 84 22
|
|
00C37C 1 20 7B E7 jsr RenderSpriteRecordList ; $C37C: 20 7B E7
|
|
00C37F 1 A4 22 ldy $22 ; $C37F: A4 22
|
|
00C381 1
|
|
00C381 1 C4 CA cpy $CA ; $C381: C4 CA
|
|
00C383 1 C8 iny ; $C383: C8
|
|
00C384 1 90 E0 bcc RenderNextSortedObject
|
|
00C386 1 ; $C384: 90 E0
|
|
00C386 1
|
|
00C386 1 ; ============================================================================
|
|
00C386 1 ; $C386-$C3C9
|
|
00C386 1 ; Copy additional OAM entries, terminate the PPU command queue, hide unused
|
|
00C386 1 ; sprites, and finish the frame.
|
|
00C386 1 ; ============================================================================
|
|
00C386 1
|
|
00C386 1 FinalizeOamAndPpuQueue: ; $C386
|
|
00C386 1 A5 C7 lda ObjectListFlag ; $C386: A5 C7
|
|
00C388 1 D0 20 bne TerminatePpuUpdateQueue
|
|
00C38A 1 ; $C388: D0 20
|
|
00C38A 1
|
|
00C38A 1 ; ----------------------------------------------------------------------------
|
|
00C38A 1 ; Copy twenty bytes from $EBC2 into available shadow OAM space.
|
|
00C38A 1 ; ----------------------------------------------------------------------------
|
|
00C38A 1
|
|
00C38A 1 A6 3F ldx OamWriteOffset ; $C38A: A6 3F
|
|
00C38C 1 A0 13 ldy #$13 ; $C38C: A0 13
|
|
00C38E 1
|
|
00C38E 1 CopyStatusOamData: ; $C38E
|
|
00C38E 1 B9 C2 EB lda $EBC2,y ; $C38E: B9 C2 EB
|
|
00C391 1 9D 00 02 sta $0200,x ; $C391: 9D 00 02
|
|
00C394 1
|
|
00C394 1 E8 inx ; $C394: E8
|
|
00C395 1 88 dey ; $C395: 88
|
|
00C396 1 10 F6 bpl CopyStatusOamData
|
|
00C398 1 ; $C396: 10 F6
|
|
00C398 1
|
|
00C398 1 ; ----------------------------------------------------------------------------
|
|
00C398 1 ; Select two additional bytes from a table beginning at $EBBC.
|
|
00C398 1 ; ----------------------------------------------------------------------------
|
|
00C398 1
|
|
00C398 1 A4 34 ldy PlayerOneSelection ; $C398: A4 34
|
|
00C39A 1 B9 BC EB lda $EBBC,y ; $C39A: B9 BC EB
|
|
00C39D 1 9D F9 01 sta $01F9,x ; $C39D: 9D F9 01
|
|
00C3A0 1
|
|
00C3A0 1 A4 35 ldy PlayerTwoSelection ; $C3A0: A4 35
|
|
00C3A2 1 B9 BC EB lda $EBBC,y ; $C3A2: B9 BC EB
|
|
00C3A5 1 9D FD 01 sta $01FD,x ; $C3A5: 9D FD 01
|
|
00C3A8 1
|
|
00C3A8 1 86 3F stx OamWriteOffset ; $C3A8: 86 3F
|
|
00C3AA 1
|
|
00C3AA 1 ; ----------------------------------------------------------------------------
|
|
00C3AA 1 ; Terminate the PPU command queue.
|
|
00C3AA 1 ; ----------------------------------------------------------------------------
|
|
00C3AA 1
|
|
00C3AA 1 TerminatePpuUpdateQueue: ; $C3AA
|
|
00C3AA 1 A9 00 lda #$00 ; $C3AA: A9 00
|
|
00C3AC 1 A4 3E ldy PpuQueueOffset ; $C3AC: A4 3E
|
|
00C3AE 1 99 00 03 sta $0300,y ; $C3AE: 99 00 03
|
|
00C3B1 1
|
|
00C3B1 1 ; ----------------------------------------------------------------------------
|
|
00C3B1 1 ; Hide all unused sprites by writing $F0 to each remaining OAM Y coordinate.
|
|
00C3B1 1 ; ----------------------------------------------------------------------------
|
|
00C3B1 1
|
|
00C3B1 1 A6 3F ldx OamWriteOffset ; $C3B1: A6 3F
|
|
00C3B3 1 D0 04 bne HideUnusedOamSprites
|
|
00C3B5 1 ; $C3B3: D0 04
|
|
00C3B5 1
|
|
00C3B5 1 A5 20 lda FrameState20 ; $C3B5: A5 20
|
|
00C3B7 1 D0 0E bne FinishFrameRendering ; $C3B7: D0 0E
|
|
00C3B9 1
|
|
00C3B9 1 HideUnusedOamSprites: ; $C3B9
|
|
00C3B9 1 A9 F0 lda #$F0 ; $C3B9: A9 F0
|
|
00C3BB 1
|
|
00C3BB 1 HideUnusedOamSpriteLoop: ; $C3BB
|
|
00C3BB 1 9D 00 02 sta $0200,x ; $C3BB: 9D 00 02
|
|
00C3BE 1
|
|
00C3BE 1 E8 inx ; $C3BE: E8
|
|
00C3BF 1 E8 inx ; $C3BF: E8
|
|
00C3C0 1 E8 inx ; $C3C0: E8
|
|
00C3C1 1 E8 inx ; $C3C1: E8
|
|
00C3C2 1
|
|
00C3C2 1 D0 F7 bne HideUnusedOamSpriteLoop
|
|
00C3C4 1 ; $C3C2: D0 F7
|
|
00C3C4 1
|
|
00C3C4 1 20 F5 E5 jsr AdvanceRandomState ; $C3C4: 20 F5 E5
|
|
00C3C7 1
|
|
00C3C7 1 FinishFrameRendering: ; $C3C7
|
|
00C3C7 1 4C 6A EB jmp CommonEngineExit ; $C3C7: 4C 6A EB
|
|
00C3CA 1
|
|
00C3CA 1 ; ============================================================================
|
|
00C3CA 1 ; $C3CA-$C40A
|
|
00C3CA 1 ; Update one object's signed fixed-point position.
|
|
00C3CA 1 ;
|
|
00C3CA 1 ; Entry:
|
|
00C3CA 1 ; X = object-array offset
|
|
00C3CA 1 ;
|
|
00C3CA 1 ; Fields used relative to X:
|
|
00C3CA 1 ; $0506,X = fractional movement component
|
|
00C3CA 1 ; $0507,X = position low byte
|
|
00C3CA 1 ; $0508,X = position high byte / signed movement component
|
|
00C3CA 1 ; $0509,X = second position low byte
|
|
00C3CA 1 ; $050A,X = second position high byte
|
|
00C3CA 1 ;
|
|
00C3CA 1 ; Called earlier with X = $00, $31, and $62.
|
|
00C3CA 1 ; ============================================================================
|
|
00C3CA 1
|
|
00C3CA 1 ; ----------------------------------------------------------------------------
|
|
00C3CA 1 ; Contract:
|
|
00C3CA 1 ; Description: Implements Integrate Object Velocity And Position.
|
|
00C3CA 1 ; Entry: Registers: A, Y; Memory: $0506, $0508, mathtemp05, $0507, $0509, $050a
|
|
00C3CA 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00C3CA 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C3CA 1 ; Memory effects: mathtemp05, $0507, $0508, $0509, $050a
|
|
00C3CA 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C3CA 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C3CA 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00C3CA 1 ; ----------------------------------------------------------------------------
|
|
00C3CA 1 IntegrateObjectVelocityAndPosition: ; $C3CA
|
|
00C3CA 1 BC 06 05 ldy $0506,x ; $C3CA: BC 06 05
|
|
00C3CD 1
|
|
00C3CD 1 BD 08 05 lda $0508,x ; $C3CD: BD 08 05
|
|
00C3D0 1 10 01 bpl CalculateSignedVelocityDelta ; $C3D0: 10 01
|
|
00C3D2 1
|
|
00C3D2 1 C8 iny ; $C3D2: C8
|
|
00C3D3 1 ; Adjust the high-byte sign value.
|
|
00C3D3 1
|
|
00C3D3 1 CalculateSignedVelocityDelta: ; $C3D3
|
|
00C3D3 1 38 sec ; $C3D3: 38
|
|
00C3D4 1
|
|
00C3D4 1 A9 00 lda #$00 ; $C3D4: A9 00
|
|
00C3D6 1 FD 08 05 sbc $0508,x ; $C3D6: FD 08 05
|
|
00C3D9 1 B0 01 bcs SaveVelocitySignExtension ; $C3D9: B0 01
|
|
00C3DB 1
|
|
00C3DB 1 88 dey ; $C3DB: 88
|
|
00C3DC 1
|
|
00C3DC 1 SaveVelocitySignExtension: ; $C3DC
|
|
00C3DC 1 84 05 sty MathTemp05 ; $C3DC: 84 05
|
|
00C3DE 1
|
|
00C3DE 1 ; ----------------------------------------------------------------------------
|
|
00C3DE 1 ; Arithmetic shift the signed 16-bit value in $05:A right twice.
|
|
00C3DE 1 ;
|
|
00C3DE 1 ; CMP #$80 places bit 7 of Y into carry:
|
|
00C3DE 1 ; Y >= $80 sets carry
|
|
00C3DE 1 ; Y < $80 clears carry
|
|
00C3DE 1 ;
|
|
00C3DE 1 ; ROR $05 followed by ROR A therefore performs a sign-preserving shift.
|
|
00C3DE 1 ; ----------------------------------------------------------------------------
|
|
00C3DE 1
|
|
00C3DE 1 C0 80 cpy #$80 ; $C3DE: C0 80
|
|
00C3E0 1 66 05 ror MathTemp05 ; $C3E0: 66 05
|
|
00C3E2 1 6A ror ; $C3E2: 6A
|
|
00C3E3 1
|
|
00C3E3 1 C0 80 cpy #$80 ; $C3E3: C0 80
|
|
00C3E5 1 66 05 ror MathTemp05 ; $C3E5: 66 05
|
|
00C3E7 1 6A ror ; $C3E7: 6A
|
|
00C3E8 1
|
|
00C3E8 1 ; ----------------------------------------------------------------------------
|
|
00C3E8 1 ; Add the shifted signed value to $0507,X/$0508,X.
|
|
00C3E8 1 ; ----------------------------------------------------------------------------
|
|
00C3E8 1
|
|
00C3E8 1 A4 05 ldy MathTemp05 ; $C3E8: A4 05
|
|
00C3EA 1
|
|
00C3EA 1 7D 07 05 adc $0507,x ; $C3EA: 7D 07 05
|
|
00C3ED 1 9D 07 05 sta $0507,x ; $C3ED: 9D 07 05
|
|
00C3F0 1
|
|
00C3F0 1 98 tya ; $C3F0: 98
|
|
00C3F1 1
|
|
00C3F1 1 A0 00 ldy #$00 ; $C3F1: A0 00
|
|
00C3F3 1
|
|
00C3F3 1 7D 08 05 adc $0508,x ; $C3F3: 7D 08 05
|
|
00C3F6 1 9D 08 05 sta $0508,x ; $C3F6: 9D 08 05
|
|
00C3F9 1
|
|
00C3F9 1 10 01 bpl AddIntegratedPosition
|
|
00C3FB 1 ; $C3F9: 10 01
|
|
00C3FB 1
|
|
00C3FB 1 88 dey ; $C3FB: 88
|
|
00C3FC 1 ; Sign-extend the high result.
|
|
00C3FC 1
|
|
00C3FC 1 ; ----------------------------------------------------------------------------
|
|
00C3FC 1 ; Add the resulting signed value to $0509,X/$050A,X.
|
|
00C3FC 1 ; ----------------------------------------------------------------------------
|
|
00C3FC 1
|
|
00C3FC 1 AddIntegratedPosition: ; $C3FC
|
|
00C3FC 1 18 clc ; $C3FC: 18
|
|
00C3FD 1
|
|
00C3FD 1 7D 09 05 adc $0509,x ; $C3FD: 7D 09 05
|
|
00C400 1 9D 09 05 sta $0509,x ; $C400: 9D 09 05
|
|
00C403 1
|
|
00C403 1 98 tya ; $C403: 98
|
|
00C404 1
|
|
00C404 1 7D 0A 05 adc $050A,x ; $C404: 7D 0A 05
|
|
00C407 1 9D 0A 05 sta $050A,x ; $C407: 9D 0A 05
|
|
00C40A 1
|
|
00C40A 1 60 rts ; $C40A: 60
|
|
00C40B 1
|
|
00C40B 1 ; ============================================================================
|
|
00C40B 1 ; $C40B-$C43D
|
|
00C40B 1 ; RESET handler
|
|
00C40B 1 ;
|
|
00C40B 1 ; Initializes the CPU, clears RAM and PPU state, initializes engine systems,
|
|
00C40B 1 ; disables APU channels/frame IRQs, and transfers control to $C74A.
|
|
00C40B 1 ; ============================================================================
|
|
00C40B 1
|
|
00C40B 1 Reset: ; $C40B
|
|
00C40B 1 78 sei ; $C40B: 78
|
|
00C40C 1 ; Disable maskable interrupts.
|
|
00C40C 1
|
|
00C40C 1 D8 cld ; $C40C: D8
|
|
00C40D 1 ; Clear decimal mode.
|
|
00C40D 1
|
|
00C40D 1 ; ----------------------------------------------------------------------------
|
|
00C40D 1 ; Clear CPU RAM at $0000-$07FF.
|
|
00C40D 1 ;
|
|
00C40D 1 ; $01 is used as the high byte of the indirect pointer $00/$01.
|
|
00C40D 1 ; Each pass clears one 256-byte page. The loop also repeatedly writes zero to
|
|
00C40D 1 ; PPUCTRL at $2000.
|
|
00C40D 1 ; ----------------------------------------------------------------------------
|
|
00C40D 1
|
|
00C40D 1 A9 07 lda #$07 ; $C40D: A9 07
|
|
00C40F 1 85 01 sta IndirectPtrHi ; $C40F: 85 01
|
|
00C411 1
|
|
00C411 1 A0 00 ldy #$00 ; $C411: A0 00
|
|
00C413 1 84 00 sty IndirectPtrLo ; $C413: 84 00
|
|
00C415 1
|
|
00C415 1 98 tya ; $C415: 98
|
|
00C416 1 ; A = $00
|
|
00C416 1
|
|
00C416 1 Reset_ClearPageLoop: ; $C416
|
|
00C416 1 91 00 sta (IndirectPtrLo),y ; $C416: 91 00
|
|
00C418 1 8D 00 20 sta PPUCTRL ; $C418: 8D 00 20
|
|
00C41B 1
|
|
00C41B 1 88 dey ; $C41B: 88
|
|
00C41C 1 D0 F8 bne Reset_ClearPageLoop ; $C41C: D0 F8
|
|
00C41E 1
|
|
00C41E 1 C6 01 dec IndirectPtrHi ; $C41E: C6 01
|
|
00C420 1 10 F4 bpl Reset_ClearPageLoop ; $C420: 10 F4
|
|
00C422 1
|
|
00C422 1 ; ----------------------------------------------------------------------------
|
|
00C422 1 ; Initialize game and PPU-related systems.
|
|
00C422 1 ; ----------------------------------------------------------------------------
|
|
00C422 1
|
|
00C422 1 20 B1 C7 jsr InitializeSpriteSortTables ; $C422: 20 B1 C7
|
|
00C425 1 20 6C E9 jsr DisablePpuRendering ; $C425: 20 6C E9
|
|
00C428 1
|
|
00C428 1 ; ----------------------------------------------------------------------------
|
|
00C428 1 ; Disable APU channels and inhibit frame-counter IRQ generation.
|
|
00C428 1 ; ----------------------------------------------------------------------------
|
|
00C428 1
|
|
00C428 1 A2 00 ldx #$00 ; $C428: A2 00
|
|
00C42A 1 8E 15 40 stx APUSTATUS ; $C42A: 8E 15 40
|
|
00C42D 1 ; Disable all APU sound channels.
|
|
00C42D 1
|
|
00C42D 1 CA dex ; $C42D: CA
|
|
00C42E 1 ; X = $FF
|
|
00C42E 1
|
|
00C42E 1 8E 17 40 stx JOY2 ; $C42E: 8E 17 40
|
|
00C431 1 ; Select five-step frame-counter mode and
|
|
00C431 1 ; inhibit frame IRQ generation.
|
|
00C431 1
|
|
00C431 1 ; ----------------------------------------------------------------------------
|
|
00C431 1 ; Invoke the routine at $C8BB.
|
|
00C431 1 ;; The three bytes immediately following the JSR are inline data interpreted by
|
|
00C431 1 ; that routine. They must not be assembled as 6502 instructions.
|
|
00C431 1 ; ----------------------------------------------------------------------------
|
|
00C431 1
|
|
00C431 1 20 BB C8 jsr ExpandRecordPointerList ; $C431: 20 BB C8
|
|
00C434 1
|
|
00C434 1 22 9C EE .byte $22,$9C,$EE ; $C434-$C436
|
|
00C437 1 ; Inline command/parameter data.
|
|
00C437 1
|
|
00C437 1 ; ----------------------------------------------------------------------------
|
|
00C437 1 ; Set the initial PPU mask shadow value, then enter the main initialization
|
|
00C437 1 ; path. This JMP does not return to RESET.
|
|
00C437 1 ; ----------------------------------------------------------------------------
|
|
00C437 1
|
|
00C437 1 A9 1A lda #$1A ; $C437: A9 1A
|
|
00C439 1 85 DE sta PpuMaskShadow ; $C439: 85 DE
|
|
00C43B 1
|
|
00C43B 1 4C 4A C7 jmp InitializeTitleScreen ; $C43B: 4C 4A C7
|
|
00C43E 1
|
|
00C43E 1 ; ============================================================================
|
|
00C43E 1 ; $C43E
|
|
00C43E 1 ; IRQ/BRK handler
|
|
00C43E 1 ; ============================================================================
|
|
00C43E 1
|
|
00C43E 1 IRQ: ; $C43E
|
|
00C43E 1 40 rti ; $C43E: 40
|
|
00C43F 1
|
|
00C43F 1 ; ============================================================================
|
|
00C43F 1 ; $C43F-$C488
|
|
00C43F 1 ; Display/update loop
|
|
00C43F 1 ; ============================================================================
|
|
00C43F 1
|
|
00C43F 1 RunAttractMessageLoop: ; $C43F
|
|
00C43F 1 A9 00 lda #$00 ; $C43F: A9 00
|
|
00C441 1 85 1F sta NmiStateFlag ; $C441: 85 1F
|
|
00C443 1
|
|
00C443 1 20 48 EB jsr SelectObjectEventBank1 ; $C443: 20 48 EB
|
|
00C446 1
|
|
00C446 1 ; ----------------------------------------------------------------------------
|
|
00C446 1 ; Draw six blank characters.
|
|
00C446 1 ; The routine at $EA17 consumes the inline bytes following the JSR.
|
|
00C446 1 ; ----------------------------------------------------------------------------
|
|
00C446 1
|
|
00C446 1 A5 C7 lda ObjectListFlag ; $C446: A5 C7
|
|
00C448 1 18 clc ; $C448: 18
|
|
00C449 1 09 23 ora #$23 ; $C449: 09 23
|
|
00C44B 1
|
|
00C44B 1 A2 37 ldx #$37 ; $C44B: A2 37
|
|
00C44D 1 A0 06 ldy #$06 ; $C44D: A0 06
|
|
00C44F 1
|
|
00C44F 1 20 17 EA jsr CopyInlineDisplayRecord ; $C44F: 20 17 EA
|
|
00C452 1
|
|
00C452 1 06 .byte $06 ; $C452
|
|
00C453 1 25 25 25 .byte $25,$25,$25 ; $C453-$C455
|
|
00C456 1 25 25 25 .byte $25,$25,$25 ; $C456-$C458
|
|
00C459 1
|
|
00C459 1 ; ----------------------------------------------------------------------------
|
|
00C459 1 ; Wait or process an engine command.
|
|
00C459 1 ; ----------------------------------------------------------------------------
|
|
00C459 1
|
|
00C459 1 A2 0B ldx #$0B ; $C459: A2 0B
|
|
00C45B 1 20 4E EB jsr UpdateObjectEventBank_Exchange ; $C45B: 20 4E EB
|
|
00C45E 1
|
|
00C45E 1 20 48 EB jsr SelectObjectEventBank1 ; $C45E: 20 48 EB
|
|
00C461 1
|
|
00C461 1 A9 10 lda #$10 ; $C461: A9 10
|
|
00C463 1 85 FD sta $FD ; $C463: 85 FD
|
|
00C465 1
|
|
00C465 1 ; ----------------------------------------------------------------------------
|
|
00C465 1 ; Draw the second six-character encoded message.
|
|
00C465 1 ; ----------------------------------------------------------------------------
|
|
00C465 1
|
|
00C465 1 A5 C7 lda ObjectListFlag ; $C465: A5 C7
|
|
00C467 1 18 clc ; $C467: 18
|
|
00C468 1 09 23 ora #$23 ; $C468: 09 23
|
|
00C46A 1
|
|
00C46A 1 A2 37 ldx #$37 ; $C46A: A2 37
|
|
00C46C 1 A0 06 ldy #$06 ; $C46C: A0 06
|
|
00C46E 1
|
|
00C46E 1 20 17 EA jsr CopyInlineDisplayRecord ; $C46E: 20 17 EA
|
|
00C471 1
|
|
00C471 1 06 .byte $06 ; $C471
|
|
00C472 1 19 0A 1E .byte $19,$0A,$1E ; $C472-$C474
|
|
00C475 1 1C 0E 25 .byte $1C,$0E,$25 ; $C475-$C477
|
|
00C478 1
|
|
00C478 1 ; ----------------------------------------------------------------------------
|
|
00C478 1 ; Complete the update, increment $1F, and repeat.
|
|
00C478 1 ; ----------------------------------------------------------------------------
|
|
00C478 1
|
|
00C478 1 20 48 EB jsr SelectObjectEventBank1 ; $C478: 20 48 EB
|
|
00C47B 1
|
|
00C47B 1 E6 1F inc NmiStateFlag ; $C47B: E6 1F
|
|
00C47D 1
|
|
00C47D 1 A2 0B ldx #$0B ; $C47D: A2 0B
|
|
00C47F 1 20 4E EB jsr UpdateObjectEventBank_Exchange ; $C47F: 20 4E EB
|
|
00C482 1
|
|
00C482 1 A9 10 lda #$10 ; $C482: A9 10
|
|
00C484 1 85 FD sta $FD ; $C484: 85 FD
|
|
00C486 1
|
|
00C486 1 4C 3F C4 jmp RunAttractMessageLoop ; $C486: 4C 3F C4
|
|
00C489 1
|
|
00C489 1 ; ============================================================================
|
|
00C489 1 ; $C489-$C4B8
|
|
00C489 1 ; Wait for controller input, initialize game state, and configure the PPU.
|
|
00C489 1 ; ============================================================================
|
|
00C489 1
|
|
00C489 1 WaitForStartInput: ; $C489
|
|
00C489 1 20 4C EB jsr SelectObjectEventBank0 ; $C489: 20 4C EB
|
|
00C48C 1
|
|
00C48C 1 A5 15 lda ControllerPressed1 ; $C48C: A5 15
|
|
00C48E 1 0A asl ; $C48E: 0A
|
|
00C48F 1 0A asl ; $C48F: 0A
|
|
00C490 1 0A asl ; $C490: 0A
|
|
00C491 1
|
|
00C491 1 90 03 bcc CheckStartInputSign ; $C491: 90 03
|
|
00C493 1
|
|
00C493 1 4C 4A C7 jmp InitializeTitleScreen ; $C493: 4C 4A C7
|
|
00C496 1
|
|
00C496 1 CheckStartInputSign: ; $C496
|
|
00C496 1 10 F1 bpl WaitForStartInput ; $C496: 10 F1
|
|
00C498 1
|
|
00C498 1 ; ----------------------------------------------------------------------------
|
|
00C498 1 ; Initialize state variables.
|
|
00C498 1 ; ----------------------------------------------------------------------------
|
|
00C498 1
|
|
00C498 1 A9 00 lda #$00 ; $C498: A9 00
|
|
00C49A 1 85 EF sta GameplaySuspended ; $C49A: 85 EF
|
|
00C49C 1
|
|
00C49C 1 InitializeNewSession: ; $C49C
|
|
00C49C 1 A9 00 lda #$00 ; $C49C: A9 00
|
|
00C49E 1 85 60 sta PendingStateTransition ; $C49E: 85 60
|
|
00C4A0 1 8D 96 05 sta $0596 ; $C4A0: 8D 96 05
|
|
00C4A3 1 85 33 sta RoundStateIndex ; $C4A3: 85 33
|
|
00C4A5 1
|
|
00C4A5 1 E6 1E inc SessionActive ; $C4A5: E6 1E
|
|
00C4A7 1
|
|
00C4A7 1 20 9D EB jsr InitializeQueuedEventSystem ; $C4A7: 20 9D EB
|
|
00C4AA 1
|
|
00C4AA 1 ; ----------------------------------------------------------------------------
|
|
00C4AA 1 ; Set the PPUCTRL shadow value and initialize PPU-related state.
|
|
00C4AA 1 ; ----------------------------------------------------------------------------
|
|
00C4AA 1 InitializeSessionDisplay:
|
|
00C4AA 1 A9 88 lda #$88 ; $C4AA: A9 88
|
|
00C4AC 1 85 DD sta PpuCtrlShadow ; $C4AC: 85 DD
|
|
00C4AE 1
|
|
00C4AE 1 20 6C E9 jsr DisablePpuRendering ; $C4AE: 20 6C E9
|
|
00C4B1 1 20 83 E9 jsr FillPpuMemoryWith26 ; $C4B1: 20 83 E9
|
|
00C4B4 1
|
|
00C4B4 1 ; ----------------------------------------------------------------------------
|
|
00C4B4 1 ; The routine at $EA63 consumes the two inline bytes following the JSR.
|
|
00C4B4 1 ; They must remain raw data rather than being decoded as 6502 opcodes.
|
|
00C4B4 1 ; ----------------------------------------------------------------------------
|
|
00C4B4 1
|
|
00C4B4 1 20 63 EA jsr ProcessInlinePpuStream ; $C4B4: 20 63 EA
|
|
00C4B7 1
|
|
00C4B7 1 F2 F4 .byte $F2,$F4 ; $C4B7-$C4B8
|
|
00C4B9 1 ; Inline command/pointer data.
|
|
00C4B9 1
|
|
00C4B9 1 ; ============================================================================
|
|
00C4B9 1 ; $C4B9-$C51D
|
|
00C4B9 1 ; Initialize play state, choose player values, and invoke setup routines.
|
|
00C4B9 1 ; ============================================================================
|
|
00C4B9 1
|
|
00C4B9 1 InitializeMatchState: ; $C4B9
|
|
00C4B9 1 20 4F C9 jsr ClearBasePositionFields ; $C4B9: 20 4F C9
|
|
00C4BC 1 20 43 C9 jsr ClearBaseAccelerationFields ; $C4BC: 20 43 C9
|
|
00C4BF 1
|
|
00C4BF 1 ; ----------------------------------------------------------------------------
|
|
00C4BF 1 ; Initialize signed position/state values.
|
|
00C4BF 1 ; ----------------------------------------------------------------------------
|
|
00C4BF 1
|
|
00C4BF 1 A9 80 lda #$80 ; $C4BF: A9 80
|
|
00C4C1 1 8D 3B 05 sta $053B ; $C4C1: 8D 3B 05
|
|
00C4C4 1 85 B7 sta PositionSignState ; $C4C4: 85 B7
|
|
00C4C6 1
|
|
00C4C6 1 20 78 E9 jsr EnableNmiAndWaitForFrame ; $C4C6: 20 78 E9
|
|
00C4C9 1
|
|
00C4C9 1 ; ----------------------------------------------------------------------------
|
|
00C4C9 1 ; Obtain two different values from $C850.
|
|
00C4C9 1 ; The first is saved in $34 and the second in $35.
|
|
00C4C9 1 ; ----------------------------------------------------------------------------
|
|
00C4C9 1
|
|
00C4C9 1 20 50 C8 jsr Random0To5 ; $C4C9: 20 50 C8
|
|
00C4CC 1 85 34 sta PlayerOneSelection ; $C4CC: 85 34
|
|
00C4CE 1
|
|
00C4CE 1 SelectDistinctSecondPlayerValue: ; $C4CE
|
|
00C4CE 1 20 50 C8 jsr Random0To5 ; $C4CE: 20 50 C8
|
|
00C4D1 1 C5 34 cmp PlayerOneSelection ; $C4D1: C5 34
|
|
00C4D3 1 F0 F9 beq SelectDistinctSecondPlayerValue
|
|
00C4D5 1 ; $C4D3: F0 F9
|
|
00C4D5 1
|
|
00C4D5 1 85 35 sta PlayerTwoSelection ; $C4D5: 85 35
|
|
00C4D7 1
|
|
00C4D7 1 ; ----------------------------------------------------------------------------
|
|
00C4D7 1 ; If $EF is nonzero, skip the player/control selection logic.
|
|
00C4D7 1 ; ----------------------------------------------------------------------------
|
|
00C4D7 1
|
|
00C4D7 1 A5 EF lda GameplaySuspended ; $C4D7: A5 EF
|
|
00C4D9 1 D0 31 bne CompleteMatchSetup ; $C4D9: D0 31
|
|
00C4DB 1
|
|
00C4DB 1 A5 40 lda ModeFlags ; $C4DB: A5 40
|
|
00C4DD 1 29 01 and #$01 ; $C4DD: 29 01
|
|
00C4DF 1 85 43 sta $43 ; $C4DF: 85 43
|
|
00C4E1 1
|
|
00C4E1 1 D0 09 bne DeriveSelectedSideFromMode
|
|
00C4E3 1 ; $C4E1: D0 09
|
|
00C4E3 1
|
|
00C4E3 1 ; ----------------------------------------------------------------------------
|
|
00C4E3 1 ; Choose a random low-bit value for $4B.
|
|
00C4E3 1 ; ----------------------------------------------------------------------------
|
|
00C4E3 1
|
|
00C4E3 1 20 F5 E5 jsr AdvanceRandomState ; $C4E3: 20 F5 E5
|
|
00C4E6 1 29 01 and #$01 ; $C4E6: 29 01
|
|
00C4E8 1 85 4B sta ActivePlayerSide ; $C4E8: 85 4B
|
|
00C4EA 1
|
|
00C4EA 1 10 09 bpl StartPlayerSelection ; $C4EA: 10 09
|
|
00C4EC 1 ; Always taken after AND #$01.
|
|
00C4EC 1
|
|
00C4EC 1 ; ----------------------------------------------------------------------------
|
|
00C4EC 1 ; Derive $4B from $43 when $43 is nonzero.
|
|
00C4EC 1 ; ----------------------------------------------------------------------------
|
|
00C4EC 1
|
|
00C4EC 1 DeriveSelectedSideFromMode: ; $C4EC
|
|
00C4EC 1 4A lsr ; $C4EC: 4A
|
|
00C4ED 1 85 4B sta ActivePlayerSide ; $C4ED: 85 4B
|
|
00C4EF 1
|
|
00C4EF 1 20 0A EB jsr QueueInlineObjectEvent ; $C4EF: 20 0A EB
|
|
00C4F2 1
|
|
00C4F2 1 ; Inline command data consumed by QueueInlineObjectEvent.
|
|
00C4F2 1 03 19 C8 .byte $03,$19,$C8 ; $C4F2-$C4F4
|
|
00C4F5 1
|
|
00C4F5 1 StartPlayerSelection: ; $C4F5
|
|
00C4F5 1 20 0A EB jsr QueueInlineObjectEvent ; $C4F5: 20 0A EB
|
|
00C4F8 1
|
|
00C4F8 1 ; Inline command data consumed by QueueInlineObjectEvent.
|
|
00C4F8 1 02 19 C8 .byte $02,$19,$C8 ; $C4F8-$C4FA
|
|
00C4FB 1
|
|
00C4FB 1 A9 01 lda #$01 ; $C4FB: A9 01
|
|
00C4FD 1 85 44 sta PlayerSelectionActive ; $C4FD: 85 44
|
|
00C4FF 1
|
|
00C4FF 1 ; ----------------------------------------------------------------------------
|
|
00C4FF 1 ; Wait while $43 remains nonnegative.
|
|
00C4FF 1 ;
|
|
00C4FF 1 ; $EB48 presumably updates asynchronous state, including $43.
|
|
00C4FF 1 ; ----------------------------------------------------------------------------
|
|
00C4FF 1
|
|
00C4FF 1 WaitForPlayerSelection: ; $C4FF
|
|
00C4FF 1 20 48 EB jsr SelectObjectEventBank1 ; $C4FF: 20 48 EB
|
|
00C502 1
|
|
00C502 1 A5 43 lda $43 ; $C502: A5 43
|
|
00C504 1 10 F9 bpl WaitForPlayerSelection
|
|
00C506 1 ; $C504: 10 F9
|
|
00C506 1
|
|
00C506 1 20 0A EB jsr QueueInlineObjectEvent ; $C506: 20 0A EB
|
|
00C509 1
|
|
00C509 1 ; Inline command data consumed by QueueInlineObjectEvent.
|
|
00C509 1 03 3E C4 .byte $03,$3E,$C4 ; $C509-$C50B
|
|
00C50C 1
|
|
00C50C 1 ; ----------------------------------------------------------------------------
|
|
00C50C 1 ; Run the main setup sequence.
|
|
00C50C 1 ; ----------------------------------------------------------------------------
|
|
00C50C 1
|
|
00C50C 1 CompleteMatchSetup: ; $C50C
|
|
00C50C 1 20 5A C8 jsr FillSelectionBackgroundBlocks ; $C50C: 20 5A C8
|
|
00C50F 1 20 DD C7 jsr QueuePlayerSelectionDisplay ; $C50F: 20 DD C7
|
|
00C512 1 20 E8 C8 jsr InitializeRandomBitfields ; $C512: 20 E8 C8
|
|
00C515 1 20 8B CF jsr QueuePlayerValueDisplay ; $C515: 20 8B CF
|
|
00C518 1
|
|
00C518 1 20 0A EB jsr QueueInlineObjectEvent ; $C518: 20 0A EB
|
|
00C51B 1
|
|
00C51B 1 ; Inline command data consumed by QueueInlineObjectEvent.
|
|
00C51B 1 09 37 CE .byte $09,$37,$CE ; $C51B-$C51D
|
|
00C51E 1
|
|
00C51E 1 ; ============================================================================
|
|
00C51E 1 ; $C51E-$C57E
|
|
00C51E 1 ; Conditional state initialization and message display.
|
|
00C51E 1 ; ============================================================================
|
|
00C51E 1
|
|
00C51E 1 InitializeRoundState: ; $C51E
|
|
00C51E 1 A5 EF lda GameplaySuspended ; $C51E: A5 EF
|
|
00C520 1 F0 08 beq EnableRoundAudio
|
|
00C522 1 ; $C520: F0 08
|
|
00C522 1
|
|
00C522 1 A5 33 lda RoundStateIndex ; $C522: A5 33
|
|
00C524 1 C9 12 cmp #$12 ; $C524: C9 12
|
|
00C526 1 90 3E bcc SelectRoundMusicCue
|
|
00C528 1 ; $C526: 90 3E
|
|
00C528 1
|
|
00C528 1 B0 0C bcs ResetRoundCounters ; $C528: B0 0C
|
|
00C52A 1 ; Effectively unconditional because either
|
|
00C52A 1 ; CMP result not taken by BCC has carry set.
|
|
00C52A 1
|
|
00C52A 1 ; ----------------------------------------------------------------------------
|
|
00C52A 1 ; Configure the APU and initialize a delay value.
|
|
00C52A 1 ; ----------------------------------------------------------------------------
|
|
00C52A 1
|
|
00C52A 1 EnableRoundAudio: ; $C52A
|
|
00C52A 1 A9 0F lda #$0F ; $C52A: A9 0F
|
|
00C52C 1 8D 00 01 sta $0100 ; $C52C: 8D 00 01
|
|
00C52F 1 8D 15 40 sta $4015 ; $C52F: 8D 15 40
|
|
00C532 1 ; Enable the four standard APU channels.
|
|
00C532 1
|
|
00C532 1 A9 08 lda #$08 ; $C532: A9 08
|
|
00C534 1 85 FD sta $FD ; $C534: 85 FD
|
|
00C536 1
|
|
00C536 1 ; ----------------------------------------------------------------------------
|
|
00C536 1 ; Clear game-state values and call the setup routine at $D06B.
|
|
00C536 1 ; A is zero after TXA.
|
|
00C536 1 ; ----------------------------------------------------------------------------
|
|
00C536 1
|
|
00C536 1 ResetRoundCounters: ; $C536
|
|
00C536 1 A2 00 ldx #$00 ; $C536: A2 00
|
|
00C538 1
|
|
00C538 1 86 67 stx PlayerOneScore ; $C538: 86 67
|
|
00C53A 1 86 68 stx PlayerTwoScore ; $C53A: 86 68
|
|
00C53C 1 86 33 stx RoundStateIndex ; $C53C: 86 33
|
|
00C53E 1
|
|
00C53E 1 8A txa ; $C53E: 8A
|
|
00C53F 1 20 6B D0 jsr InitializeObjectsFromTable ; $C53F: 20 6B D0
|
|
00C542 1
|
|
00C542 1 ; ----------------------------------------------------------------------------
|
|
00C542 1 ; Initialize position/state values and wait for $3C frames or ticks.
|
|
00C542 1 ; ----------------------------------------------------------------------------
|
|
00C542 1
|
|
00C542 1 A9 80 lda #$80 ; $C542: A9 80
|
|
00C544 1 8D 3B 05 sta $053B ; $C544: 8D 3B 05
|
|
00C547 1 85 B7 sta PositionSignState ; $C547: 85 B7
|
|
00C549 1
|
|
00C549 1 A9 3C lda #$3C ; $C549: A9 3C
|
|
00C54B 1 20 41 EB jsr StoreObjectEventBankValue ; $C54B: 20 41 EB
|
|
00C54E 1
|
|
00C54E 1 ; ----------------------------------------------------------------------------
|
|
00C54E 1 ; Draw an eight-character encoded message.
|
|
00C54E 1 ;
|
|
00C54E 1 ; The routine at $EA17 consumes the inline bytes immediately following
|
|
00C54E 1 ; the JSR. The first byte is the character count.
|
|
00C54E 1 ; ----------------------------------------------------------------------------
|
|
00C54E 1
|
|
00C54E 1 18 clc ; $C54E: 18
|
|
00C54F 1
|
|
00C54F 1 A9 20 lda #$20 ; $C54F: A9 20
|
|
00C551 1 A2 EC ldx #$EC ; $C551: A2 EC
|
|
00C553 1 A0 08 ldy #$08 ; $C553: A0 08
|
|
00C555 1
|
|
00C555 1 20 17 EA jsr CopyInlineDisplayRecord ; $C555: 20 17 EA
|
|
00C558 1
|
|
00C558 1 08 .byte $08 ; $C558: character count
|
|
00C559 1 19 15 0A 22 .byte $19,$15,$0A,$22 ; $C559-$C55C
|
|
00C55D 1 0B 0A 15 15 .byte $0B,$0A,$15,$15 ; $C55D-$C560
|
|
00C561 1
|
|
00C561 1 ; ----------------------------------------------------------------------------
|
|
00C561 1 ; Wait for another $3C frames or ticks.
|
|
00C561 1 ; ----------------------------------------------------------------------------
|
|
00C561 1
|
|
00C561 1 A9 3C lda #$3C ; $C561: A9 3C
|
|
00C563 1 20 41 EB jsr StoreObjectEventBankValue ; $C563: 20 41 EB
|
|
00C566 1
|
|
00C566 1 ; ----------------------------------------------------------------------------
|
|
00C566 1 ; Select a delay or mode value in $FD from the current value of $33.
|
|
00C566 1 ; ----------------------------------------------------------------------------
|
|
00C566 1
|
|
00C566 1 SelectRoundMusicCue: ; $C566
|
|
00C566 1 A5 33 lda RoundStateIndex ; $C566: A5 33
|
|
00C568 1 F0 09 beq PrepareRoundObjects ; $C568: F0 09
|
|
00C56A 1
|
|
00C56A 1 A2 20 ldx #$20 ; $C56A: A2 20
|
|
00C56C 1
|
|
00C56C 1 4A lsr ; $C56C: 4A
|
|
00C56D 1 90 02 bcc StoreRoundMusicCue ; $C56D: 90 02
|
|
00C56F 1
|
|
00C56F 1 A2 40 ldx #$40 ; $C56F: A2 40
|
|
00C571 1
|
|
00C571 1 StoreRoundMusicCue: ; $C571
|
|
00C571 1 86 FD stx $FD ; $C571: 86 FD
|
|
00C573 1
|
|
00C573 1 ; ----------------------------------------------------------------------------
|
|
00C573 1 ; Continue engine initialization.
|
|
00C573 1 ; ----------------------------------------------------------------------------
|
|
00C573 1
|
|
00C573 1 PrepareRoundObjects: ; $C573
|
|
00C573 1 20 DD C7 jsr QueuePlayerSelectionDisplay ; $C573: 20 DD C7
|
|
00C576 1 20 04 C9 jsr QueueRandomStateRecord ; $C576: 20 04 C9
|
|
00C579 1
|
|
00C579 1 A2 00 ldx #$00 ; $C579: A2 00
|
|
00C57B 1 86 45 stx MatchCompleteFlag ; $C57B: 86 45
|
|
00C57D 1 86 64 stx SecondarySequenceState ; $C57D: 86 64
|
|
00C57F 1
|
|
00C57F 1 ; ============================================================================
|
|
00C57F 1 ; $C57F-$C5FD
|
|
00C57F 1 ; Clear gameplay state, initialize object data, and prepare the next state.
|
|
00C57F 1 ;
|
|
00C57F 1 ; Entry:
|
|
00C57F 1 ; X = $00 from the preceding block at $C579.
|
|
00C57F 1 ; ============================================================================
|
|
00C57F 1
|
|
00C57F 1 ResetGameplayState: ; $C57F
|
|
00C57F 1 86 66 stx InningOrSharedScore ; $C57F: 86 66
|
|
00C581 1 86 5C stx BaseMotionActive ; $C581: 86 5C
|
|
00C583 1
|
|
00C583 1 CA dex ; $C583: CA
|
|
00C584 1 ; X = $FF
|
|
00C584 1
|
|
00C584 1 ; ----------------------------------------------------------------------------
|
|
00C584 1 ; Mark four state entries as inactive using $FF.
|
|
00C584 1 ; ----------------------------------------------------------------------------
|
|
00C584 1
|
|
00C584 1 8E 98 05 stx $0598 ; $C584: 8E 98 05
|
|
00C587 1 8E 99 05 stx $0599 ; $C587: 8E 99 05
|
|
00C58A 1 8E 9A 05 stx $059A ; $C58A: 8E 9A 05
|
|
00C58D 1 8E 9B 05 stx $059B ; $C58D: 8E 9B 05
|
|
00C590 1
|
|
00C590 1 ; ----------------------------------------------------------------------------
|
|
00C590 1 ; Initialize additional game-state structures.
|
|
00C590 1 ; ----------------------------------------------------------------------------
|
|
00C590 1
|
|
00C590 1 20 67 CF jsr QueueRoundNumberDisplay ; $C590: 20 67 CF
|
|
00C593 1
|
|
00C593 1 A9 00 lda #$00 ; $C593: A9 00
|
|
00C595 1 20 6B D0 jsr InitializeObjectsFromTable ; $C595: 20 6B D0
|
|
00C598 1
|
|
00C598 1 ; ----------------------------------------------------------------------------
|
|
00C598 1 ; Initialize signed position/state values.
|
|
00C598 1 ; ----------------------------------------------------------------------------
|
|
00C598 1
|
|
00C598 1 A9 80 lda #$80 ; $C598: A9 80
|
|
00C59A 1 8D 3B 05 sta $053B ; $C59A: 8D 3B 05
|
|
00C59D 1 85 B7 sta PositionSignState ; $C59D: 85 B7
|
|
00C59F 1
|
|
00C59F 1 ; ----------------------------------------------------------------------------
|
|
00C59F 1 ; Wait for or process $B4 ticks.
|
|
00C59F 1 ; ----------------------------------------------------------------------------
|
|
00C59F 1
|
|
00C59F 1 A9 B4 lda #$B4 ; $C59F: A9 B4
|
|
00C5A1 1 20 41 EB jsr StoreObjectEventBankValue ; $C5A1: 20 41 EB
|
|
00C5A4 1
|
|
00C5A4 1 ; ----------------------------------------------------------------------------
|
|
00C5A4 1 ; Contract:
|
|
00C5A4 1 ; Description: Internal round-setup continuation at random-direction initialization.
|
|
00C5A4 1 ; Entry: Parent routine state already initialized.
|
|
00C5A4 1 ; Returns/products: Continues round setup; no independent return contract.
|
|
00C5A4 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C5A4 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00C5A4 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C5A4 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C5A4 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00C5A4 1 ; ----------------------------------------------------------------------------
|
|
00C5A4 1 ResumeRoundSetupAtRandomDirection:
|
|
00C5A4 1 20 1B C9 jsr QueueRandomDirectionRecord ; $C5A4: 20 1B C9
|
|
00C5A7 1
|
|
00C5A7 1 ; ----------------------------------------------------------------------------
|
|
00C5A7 1 ; Clear two state variables and initialize $46 to one.
|
|
00C5A7 1 ; ----------------------------------------------------------------------------
|
|
00C5A7 1
|
|
00C5A7 1 A2 00 ldx #$00 ; $C5A7: A2 00
|
|
00C5A9 1
|
|
00C5A9 1 86 62 stx PrimarySequenceState ; $C5A9: 86 62
|
|
00C5AB 1 86 63 stx TransitionSequenceState ; $C5AB: 86 63
|
|
00C5AD 1
|
|
00C5AD 1 E8 inx ; $C5AD: E8
|
|
00C5AE 1 ; X = $01
|
|
00C5AE 1
|
|
00C5AE 1 86 46 stx StateSequenceActive ; $C5AE: 86 46
|
|
00C5B0 1
|
|
00C5B0 1 ; ----------------------------------------------------------------------------
|
|
00C5B0 1 ; Invoke $CF51 with two different values.
|
|
00C5B0 1 ; ----------------------------------------------------------------------------
|
|
00C5B0 1
|
|
00C5B0 1 A9 03 lda #$03 ; $C5B0: A9 03
|
|
00C5B2 1 20 51 CF jsr ClearStateFieldPair ; $C5B2: 20 51 CF
|
|
00C5B5 1
|
|
00C5B5 1 A9 23 lda #$23 ; $C5B5: A9 23
|
|
00C5B7 1 20 51 CF jsr ClearStateFieldPair ; $C5B7: 20 51 CF
|
|
00C5BA 1
|
|
00C5BA 1 ; ----------------------------------------------------------------------------
|
|
00C5BA 1 ; Contract:
|
|
00C5BA 1 ; Description: Internal round-setup continuation at selection-display initialization.
|
|
00C5BA 1 ; Entry: Parent routine state already initialized.
|
|
00C5BA 1 ; Returns/products: Continues round setup; no independent return contract.
|
|
00C5BA 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C5BA 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00C5BA 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C5BA 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C5BA 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00C5BA 1 ; ----------------------------------------------------------------------------
|
|
00C5BA 1 ResumeRoundSetupAtSelectionDisplay:
|
|
00C5BA 1 20 C9 C7 jsr ClearEightCharacterField ; $C5BA: 20 C9 C7
|
|
00C5BD 1
|
|
00C5BD 1 ; ----------------------------------------------------------------------------
|
|
00C5BD 1 ; Clear individual state entries.
|
|
00C5BD 1 ; ----------------------------------------------------------------------------
|
|
00C5BD 1
|
|
00C5BD 1 A9 00 lda #$00 ; $C5BD: A9 00
|
|
00C5BF 1
|
|
00C5BF 1 8D 97 05 sta $0597 ; $C5BF: 8D 97 05
|
|
00C5C2 1
|
|
00C5C2 1 8D 9C 05 sta $059C ; $C5C2: 8D 9C 05
|
|
00C5C5 1 8D 9D 05 sta $059D ; $C5C5: 8D 9D 05
|
|
00C5C8 1 8D 9E 05 sta $059E ; $C5C8: 8D 9E 05
|
|
00C5CB 1 8D 9F 05 sta $059F ; $C5CB: 8D 9F 05
|
|
00C5CE 1 8D A0 05 sta $05A0 ; $C5CE: 8D A0 05
|
|
00C5D1 1
|
|
00C5D1 1 8D A4 05 sta $05A4 ; $C5D1: 8D A4 05
|
|
00C5D4 1 8D A5 05 sta $05A5 ; $C5D4: 8D A5 05
|
|
00C5D7 1 8D A6 05 sta $05A6 ; $C5D7: 8D A6 05
|
|
00C5DA 1
|
|
00C5DA 1 ; ----------------------------------------------------------------------------
|
|
00C5DA 1 ; Clear the 38-byte range $056F-$0594.
|
|
00C5DA 1 ;
|
|
00C5DA 1 ; X counts from $25 down through $00.
|
|
00C5DA 1 ; ----------------------------------------------------------------------------
|
|
00C5DA 1
|
|
00C5DA 1 A2 25 ldx #$25 ; $C5DA: A2 25
|
|
00C5DC 1
|
|
00C5DC 1 ClearObjectMotionFields: ; $C5DC
|
|
00C5DC 1 9D 6F 05 sta $056F,x ; $C5DC: 9D 6F 05
|
|
00C5DF 1
|
|
00C5DF 1 CA dex ; $C5DF: CA
|
|
00C5E0 1 10 FA bpl ClearObjectMotionFields
|
|
00C5E2 1 ; $C5E0: 10 FA
|
|
00C5E2 1
|
|
00C5E2 1 ; ----------------------------------------------------------------------------
|
|
00C5E2 1 ; Conditional transition based on $33 and the comparison of $67 with $68.
|
|
00C5E2 1 ; ----------------------------------------------------------------------------
|
|
00C5E2 1
|
|
00C5E2 1 A5 33 lda RoundStateIndex ; $C5E2: A5 33
|
|
00C5E4 1 C9 11 cmp #$11 ; $C5E4: C9 11
|
|
00C5E6 1 D0 09 bne FinishGameplayReset ; $C5E6: D0 09
|
|
00C5E8 1
|
|
00C5E8 1 A5 67 lda PlayerOneScore ; $C5E8: A5 67
|
|
00C5EA 1 C5 68 cmp PlayerTwoScore ; $C5EA: C5 68
|
|
00C5EC 1 B0 03 bcs FinishGameplayReset ; $C5EC: B0 03
|
|
00C5EE 1
|
|
00C5EE 1 4C F7 C6 jmp CompleteMatchState ; $C5EE: 4C F7 C6
|
|
00C5F1 1
|
|
00C5F1 1 ; ----------------------------------------------------------------------------
|
|
00C5F1 1 ; Complete initialization and synchronize with the frame/update system.
|
|
00C5F1 1 ; ----------------------------------------------------------------------------
|
|
00C5F1 1
|
|
00C5F1 1 FinishGameplayReset: ; $C5F1
|
|
00C5F1 1 20 69 D0 jsr InitializeDefaultObjects ; $C5F1: 20 69 D0
|
|
00C5F4 1
|
|
00C5F4 1 A9 00 lda #$00 ; $C5F4: A9 00
|
|
00C5F6 1 8D 3B 05 sta $053B ; $C5F6: 8D 3B 05
|
|
00C5F9 1 85 B7 sta PositionSignState ; $C5F9: 85 B7
|
|
00C5FB 1
|
|
00C5FB 1 20 48 EB jsr SelectObjectEventBank1 ; $C5FB: 20 48 EB
|
|
00C5FE 1
|
|
00C5FE 1 ; ============================================================================
|
|
00C5FE 1 ; $C5FE-$C6E0
|
|
00C5FE 1 ; Main state initialization and processing loop
|
|
00C5FE 1 ; ============================================================================
|
|
00C5FE 1
|
|
00C5FE 1 RunRoundStateLoop: ; $C5FE
|
|
00C5FE 1 A4 60 ldy PendingStateTransition ; $C5FE: A4 60
|
|
00C600 1 F0 03 beq CheckRoundTransitionState ; $C600: F0 03
|
|
00C602 1
|
|
00C602 1 20 A2 C8 jsr InitializeObjectStateLookup ; $C602: 20 A2 C8
|
|
00C605 1
|
|
00C605 1 ; ----------------------------------------------------------------------------
|
|
00C605 1 ; Dispatch state-specific handlers when either $60 or $46 is nonzero.
|
|
00C605 1 ; ----------------------------------------------------------------------------
|
|
00C605 1
|
|
00C605 1 CheckRoundTransitionState: ; $C605
|
|
00C605 1 A5 60 lda PendingStateTransition ; $C605: A5 60
|
|
00C607 1 05 46 ora StateSequenceActive ; $C607: 05 46
|
|
00C609 1 F0 0E beq RunPrimaryRoundHandlers
|
|
00C60B 1 ; $C609: F0 0E
|
|
00C60B 1
|
|
00C60B 1 46 46 lsr StateSequenceActive ; $C60B: 46 46
|
|
00C60D 1
|
|
00C60D 1 20 0A EB jsr QueueInlineObjectEvent ; $C60D: 20 0A EB
|
|
00C610 1
|
|
00C610 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00C610 1 0D 77 D4 .byte $0D,$77,$D4 ; $C610-$C612
|
|
00C613 1
|
|
00C613 1 20 0A EB jsr QueueInlineObjectEvent ; $C613: 20 0A EB
|
|
00C616 1
|
|
00C616 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00C616 1 0F 81 D3 .byte $0F,$81,$D3 ; $C616-$C618
|
|
00C619 1
|
|
00C619 1 ; ----------------------------------------------------------------------------
|
|
00C619 1 ; Run the primary state handlers.
|
|
00C619 1 ; ----------------------------------------------------------------------------
|
|
00C619 1
|
|
00C619 1 RunPrimaryRoundHandlers: ; $C619
|
|
00C619 1 20 10 D6 jsr InitializeSecondaryActors ; $C619: 20 10 D6
|
|
00C61C 1 20 26 D1 jsr InitializeConditionalObject ; $C61C: 20 26 D1
|
|
00C61F 1
|
|
00C61F 1 ; ----------------------------------------------------------------------------
|
|
00C61F 1 ; Clear working state.
|
|
00C61F 1 ; ----------------------------------------------------------------------------
|
|
00C61F 1
|
|
00C61F 1 A2 00 ldx #$00 ; $C61F: A2 00
|
|
00C621 1
|
|
00C621 1 86 65 stx PendingScoreIncrement ; $C621: 86 65
|
|
00C623 1 86 5D stx BaseMotionPhase ; $C623: 86 5D
|
|
00C625 1 86 5E stx BaseMotionEventCount ; $C625: 86 5E
|
|
00C627 1 86 5F stx TrajectoryResult ; $C627: 86 5F
|
|
00C629 1 86 60 stx PendingStateTransition ; $C629: 86 60
|
|
00C62B 1 86 6D stx SpecialSequenceState ; $C62B: 86 6D
|
|
00C62D 1 86 6E stx ObjectTransitionState ; $C62D: 86 6E
|
|
00C62F 1 86 5C stx BaseMotionActive ; $C62F: 86 5C
|
|
00C631 1 86 7E stx ActionSequenceCounter ; $C631: 86 7E
|
|
00C633 1 86 86 stx TrajectoryEvaluationEnabled ; $C633: 86 86
|
|
00C635 1 86 85 stx $85 ; $C635: 86 85
|
|
00C637 1 86 83 stx ObjectApproachCount ; $C637: 86 83
|
|
00C639 1 86 6F stx PendingEvent ; $C639: 86 6F
|
|
00C63B 1 86 A2 stx ObjectSequenceState ; $C63B: 86 A2
|
|
00C63D 1 86 BC stx $BC ; $C63D: 86 BC
|
|
00C63F 1
|
|
00C63F 1 8E 6E 05 stx $056E ; $C63F: 8E 6E 05
|
|
00C642 1
|
|
00C642 1 86 9E stx $9E ; $C642: 86 9E
|
|
00C644 1
|
|
00C644 1 E8 inx ; $C644: E8
|
|
00C645 1 ; X = $01
|
|
00C645 1
|
|
00C645 1 86 96 stx $96 ; $C645: 86 96
|
|
00C647 1 86 97 stx $97 ; $C647: 86 97
|
|
00C649 1 86 98 stx $98 ; $C649: 86 98
|
|
00C64B 1
|
|
00C64B 1 ; ----------------------------------------------------------------------------
|
|
00C64B 1 ; Reset coordinate-related structures.
|
|
00C64B 1 ; ----------------------------------------------------------------------------
|
|
00C64B 1
|
|
00C64B 1 20 43 C9 jsr ClearBaseAccelerationFields ; $C64B: 20 43 C9
|
|
00C64E 1 20 4F C9 jsr ClearBasePositionFields ; $C64E: 20 4F C9
|
|
00C651 1
|
|
00C651 1 ; ----------------------------------------------------------------------------
|
|
00C651 1 ; Run three inline-command handlers.
|
|
00C651 1 ; ----------------------------------------------------------------------------
|
|
00C651 1
|
|
00C651 1 20 0A EB jsr QueueInlineObjectEvent ; $C651: 20 0A EB
|
|
00C654 1
|
|
00C654 1 25 5A D8 .byte $25,$5A,$D8 ; $C654-$C656
|
|
00C657 1
|
|
00C657 1 20 0A EB jsr QueueInlineObjectEvent ; $C657: 20 0A EB
|
|
00C65A 1
|
|
00C65A 1 0E 66 D1 .byte $0E,$66,$D1 ; $C65A-$C65C
|
|
00C65D 1
|
|
00C65D 1 20 0A EB jsr QueueInlineObjectEvent ; $C65D: 20 0A EB
|
|
00C660 1
|
|
00C660 1 1F 76 CA .byte $1F,$76,$CA ; $C660-$C662
|
|
00C663 1
|
|
00C663 1 ; ----------------------------------------------------------------------------
|
|
00C663 1 ; Process command $08.
|
|
00C663 1 ; ----------------------------------------------------------------------------
|
|
00C663 1
|
|
00C663 1 A2 08 ldx #$08 ; $C663: A2 08
|
|
00C665 1 20 4E EB jsr UpdateObjectEventBank_Exchange ; $C665: 20 4E EB
|
|
00C668 1
|
|
00C668 1 ; ----------------------------------------------------------------------------
|
|
00C668 1 ; Walk a 22-entry table in reverse.
|
|
00C668 1 ;
|
|
00C668 1 ; X begins at $15 and reaches $00. Each byte from $C6E1,X is passed in Y
|
|
00C668 1 ; to the routine at $EB66.
|
|
00C668 1 ; ----------------------------------------------------------------------------
|
|
00C668 1
|
|
00C668 1 A2 15 ldx #$15 ; $C668: A2 15
|
|
00C66A 1
|
|
00C66A 1 ProcessRoundEventSlotTable: ; $C66A
|
|
00C66A 1 BC E1 C6 ldy RoundEventSlotTable,x ; $C66A: BC E1 C6
|
|
00C66D 1 20 66 EB jsr DispatchNextQueuedEvent ; $C66D: 20 66 EB
|
|
00C670 1
|
|
00C670 1 CA dex ; $C670: CA
|
|
00C671 1 10 F7 bpl ProcessRoundEventSlotTable
|
|
00C673 1 ; $C671: 10 F7
|
|
00C673 1
|
|
00C673 1 ; ----------------------------------------------------------------------------
|
|
00C673 1 ; Write one inline character at the selected PPU destination.
|
|
00C673 1 ; ----------------------------------------------------------------------------
|
|
00C673 1
|
|
00C673 1 A9 3F lda #$3F ; $C673: A9 3F
|
|
00C675 1 A2 07 ldx #$07 ; $C675: A2 07
|
|
00C677 1 A0 01 ldy #$01 ; $C677: A0 01
|
|
00C679 1
|
|
00C679 1 20 17 EA jsr CopyInlineDisplayRecord ; $C679: 20 17 EA
|
|
00C67C 1
|
|
00C67C 1 01 28 .byte $01,$28 ; $C67C-$C67D
|
|
00C67E 1 ; One encoded character: $28.
|
|
00C67E 1
|
|
00C67E 1 ; ----------------------------------------------------------------------------
|
|
00C67E 1 ; If $60 is zero and $65 is nonzero, run the helper at $CFA6 and clear $65.
|
|
00C67E 1 ; ----------------------------------------------------------------------------
|
|
00C67E 1
|
|
00C67E 1 ApplyPendingScoreUpdate: ; $C67E
|
|
00C67E 1 A5 60 lda PendingStateTransition ; $C67E: A5 60
|
|
00C680 1 D0 0B bne StartPostRoundDelay ; $C680: D0 0B
|
|
00C682 1
|
|
00C682 1 A5 65 lda PendingScoreIncrement ; $C682: A5 65
|
|
00C684 1 F0 07 beq StartPostRoundDelay ; $C684: F0 07
|
|
00C686 1
|
|
00C686 1 20 A6 CF jsr UpdateCountersAndDisplay ; $C686: 20 A6 CF
|
|
00C689 1
|
|
00C689 1 A9 00 lda #$00 ; $C689: A9 00
|
|
00C68B 1 85 65 sta PendingScoreIncrement ; $C68B: 85 65
|
|
00C68D 1
|
|
00C68D 1 ; ----------------------------------------------------------------------------
|
|
00C68D 1 ; Wait for $6F to become zero, then count down $48.
|
|
00C68D 1 ; ----------------------------------------------------------------------------
|
|
00C68D 1
|
|
00C68D 1 StartPostRoundDelay: ; $C68D
|
|
00C68D 1 A9 1E lda #$1E ; $C68D: A9 1E
|
|
00C68F 1 85 48 sta $48 ; $C68F: 85 48
|
|
00C691 1
|
|
00C691 1 WaitPostRoundFrame: ; $C691
|
|
00C691 1 20 48 EB jsr SelectObjectEventBank1 ; $C691: 20 48 EB
|
|
00C694 1
|
|
00C694 1 A5 6F lda PendingEvent ; $C694: A5 6F
|
|
00C696 1 D0 F5 bne StartPostRoundDelay ; $C696: D0 F5
|
|
00C698 1
|
|
00C698 1 C6 48 dec $48 ; $C698: C6 48
|
|
00C69A 1 D0 F5 bne WaitPostRoundFrame ; $C69A: D0 F5
|
|
00C69C 1
|
|
00C69C 1 ; ----------------------------------------------------------------------------
|
|
00C69C 1 ; If both $45 and $46 are zero, return to the initialization point at $C5BA.
|
|
00C69C 1 ; ----------------------------------------------------------------------------
|
|
00C69C 1
|
|
00C69C 1 A5 45 lda MatchCompleteFlag ; $C69C: A5 45
|
|
00C69E 1 05 46 ora StateSequenceActive ; $C69E: 05 46
|
|
00C6A0 1 D0 03 bne ProcessPostRoundEvents
|
|
00C6A2 1 ; $C6A0: D0 03
|
|
00C6A2 1
|
|
00C6A2 1 4C BA C5 jmp ResumeRoundSetupAtSelectionDisplay ; $C6A2: 4C BA C5
|
|
00C6A5 1
|
|
00C6A5 1 ; ----------------------------------------------------------------------------
|
|
00C6A5 1 ; Process two indexed event slots and wait ten ticks.
|
|
00C6A5 1 ; ----------------------------------------------------------------------------
|
|
00C6A5 1
|
|
00C6A5 1 ProcessPostRoundEvents: ; $C6A5
|
|
00C6A5 1 A0 0D ldy #$0D ; $C6A5: A0 0D
|
|
00C6A7 1 20 66 EB jsr DispatchNextQueuedEvent ; $C6A7: 20 66 EB
|
|
00C6AA 1
|
|
00C6AA 1 A0 0F ldy #$0F ; $C6AA: A0 0F
|
|
00C6AC 1 20 66 EB jsr DispatchNextQueuedEvent ; $C6AC: 20 66 EB
|
|
00C6AF 1
|
|
00C6AF 1 A9 0A lda #$0A ; $C6AF: A9 0A
|
|
00C6B1 1 20 41 EB jsr StoreObjectEventBankValue ; $C6B1: 20 41 EB
|
|
00C6B4 1
|
|
00C6B4 1 ; ----------------------------------------------------------------------------
|
|
00C6B4 1 ; If $46 is active, decrement one of the two counters at $51/$52.
|
|
00C6B4 1 ; The selected counter depends on the low bit of $33.
|
|
00C6B4 1 ; ----------------------------------------------------------------------------
|
|
00C6B4 1
|
|
00C6B4 1 A5 46 lda StateSequenceActive ; $C6B4: A5 46
|
|
00C6B6 1 F0 0D beq CheckPostRoundContinuation ; $C6B6: F0 0D
|
|
00C6B8 1
|
|
00C6B8 1 A5 33 lda RoundStateIndex ; $C6B8: A5 33
|
|
00C6BA 1 29 01 and #$01 ; $C6BA: 29 01
|
|
00C6BC 1 AA tax ; $C6BC: AA
|
|
00C6BD 1
|
|
00C6BD 1 D6 51 dec Counter51,x ; $C6BD: D6 51
|
|
00C6BF 1 10 04 bpl CheckPostRoundContinuation ; $C6BF: 10 04
|
|
00C6C1 1
|
|
00C6C1 1 A9 08 lda #$08 ; $C6C1: A9 08
|
|
00C6C3 1 95 51 sta Counter51,x ; $C6C3: 95 51
|
|
00C6C5 1
|
|
00C6C5 1 ; ----------------------------------------------------------------------------
|
|
00C6C5 1 ; If $45 is zero, return to the setup point at $C5A4.
|
|
00C6C5 1 ; Otherwise, update state and advance $33.
|
|
00C6C5 1 ; ----------------------------------------------------------------------------
|
|
00C6C5 1
|
|
00C6C5 1 CheckPostRoundContinuation: ; $C6C5
|
|
00C6C5 1 A5 45 lda MatchCompleteFlag ; $C6C5: A5 45
|
|
00C6C7 1 D0 03 bne AdvanceRoundNumber ; $C6C7: D0 03
|
|
00C6C9 1
|
|
00C6C9 1 4C A4 C5 jmp ResumeRoundSetupAtRandomDirection ; $C6C9: 4C A4 C5
|
|
00C6CC 1
|
|
00C6CC 1 AdvanceRoundNumber: ; $C6CC
|
|
00C6CC 1 20 A6 CF jsr UpdateCountersAndDisplay ; $C6CC: 20 A6 CF
|
|
00C6CF 1
|
|
00C6CF 1 E6 33 inc RoundStateIndex ; $C6CF: E6 33
|
|
00C6D1 1
|
|
00C6D1 1 A5 33 lda RoundStateIndex ; $C6D1: A5 33
|
|
00C6D3 1 C9 12 cmp #$12 ; $C6D3: C9 12
|
|
00C6D5 1 F0 31 beq InitializeResultsPosition ; $C6D5: F0 31
|
|
00C6D7 1
|
|
00C6D7 1 20 48 EB jsr SelectObjectEventBank1 ; $C6D7: 20 48 EB
|
|
00C6DA 1
|
|
00C6DA 1 A5 EF lda GameplaySuspended ; $C6DA: A5 EF
|
|
00C6DC 1 D0 6C bne InitializeTitleScreen ; $C6DC: D0 6C
|
|
00C6DE 1
|
|
00C6DE 1 4C 66 C5 jmp SelectRoundMusicCue ; $C6DE: 4C 66 C5
|
|
00C6E1 1
|
|
00C6E1 1 ; ============================================================================
|
|
00C6E1 1 ; Table referenced by the loop at $C66A.
|
|
00C6E1 1 ;
|
|
00C6E1 1 ; The table begins at CPU $C6E1 and remains in the untouched ROM for the next
|
|
00C6E1 1 ; pass. Its first bytes are:
|
|
00C6E1 1 ;
|
|
00C6E1 1 ; $04,$06,$08,$0A,$0C,$0E,$10,$12 ...
|
|
00C6E1 1 ; ============================================================================
|
|
00C6E1 1
|
|
00C6E1 1 ; ============================================================================
|
|
00C6E1 1 ; $C6E1-$C6F6
|
|
00C6E1 1 ; Event-slot/index lookup table
|
|
00C6E1 1 ; ============================================================================
|
|
00C6E1 1
|
|
00C6E1 1 RoundEventSlotTable: ; $C6E1
|
|
00C6E1 1 04 06 08 0A .byte $04,$06,$08,$0A
|
|
00C6E5 1 0C 0E 10 12 .byte $0C,$0E,$10,$12
|
|
00C6E9 1 14 16 1E 20 .byte $14,$16,$1E,$20
|
|
00C6ED 1 22 24 26 11 .byte $22,$24,$26,$11
|
|
00C6F1 1 15 17 19 1D .byte $15,$17,$19,$1D
|
|
00C6F5 1 1F 29 .byte $1F,$29
|
|
00C6F7 1
|
|
00C6F7 1 ; ============================================================================
|
|
00C6F7 1 ; $C6F7-$C7B0
|
|
00C6F7 1 ; State completion, message display, PPU setup, and return to the main loop
|
|
00C6F7 1 ; ============================================================================
|
|
00C6F7 1
|
|
00C6F7 1 CompleteMatchState: ; $C6F7
|
|
00C6F7 1 E6 33 inc RoundStateIndex ; $C6F7: E6 33
|
|
00C6F9 1
|
|
00C6F9 1 A5 66 lda InningOrSharedScore ; $C6F9: A5 66
|
|
00C6FB 1 D0 0B bne InitializeResultsPosition
|
|
00C6FD 1 ; $C6FB: D0 0B
|
|
00C6FD 1
|
|
00C6FD 1 ; ----------------------------------------------------------------------------
|
|
00C6FD 1 ; Draw one encoded character.
|
|
00C6FD 1 ; ----------------------------------------------------------------------------
|
|
00C6FD 1
|
|
00C6FD 1 A9 20 lda #$20 ; $C6FD: A9 20
|
|
00C6FF 1 A2 B3 ldx #$B3 ; $C6FF: A2 B3
|
|
00C701 1 A0 01 ldy #$01 ; $C701: A0 01
|
|
00C703 1
|
|
00C703 1 20 17 EA jsr CopyInlineDisplayRecord ; $C703: 20 17 EA
|
|
00C706 1
|
|
00C706 1 01 32 .byte $01,$32 ; $C706-$C707
|
|
00C708 1
|
|
00C708 1 ; ----------------------------------------------------------------------------
|
|
00C708 1 ; Initialize signed position/state values.
|
|
00C708 1 ; ----------------------------------------------------------------------------
|
|
00C708 1
|
|
00C708 1 InitializeResultsPosition: ; $C708
|
|
00C708 1 A9 80 lda #$80 ; $C708: A9 80
|
|
00C70A 1 8D 3B 05 sta $053B ; $C70A: 8D 3B 05
|
|
00C70D 1 85 B7 sta PositionSignState ; $C70D: 85 B7
|
|
00C70F 1
|
|
00C70F 1 ; ----------------------------------------------------------------------------
|
|
00C70F 1 ; Draw a ten-character encoded message.
|
|
00C70F 1 ; ----------------------------------------------------------------------------
|
|
00C70F 1
|
|
00C70F 1 A9 20 lda #$20 ; $C70F: A9 20
|
|
00C711 1 A2 EB ldx #$EB ; $C711: A2 EB
|
|
00C713 1 A0 0A ldy #$0A ; $C713: A0 0A
|
|
00C715 1 18 clc ; $C715: 18
|
|
00C716 1
|
|
00C716 1 20 17 EA jsr CopyInlineDisplayRecord ; $C716: 20 17 EA
|
|
00C719 1
|
|
00C719 1 0A .byte $0A ; $C719
|
|
00C71A 1 25 10 0A 16 .byte $25,$10,$0A,$16,$0E ; $C71A-$C71E
|
|
00C71E 1 0E
|
|
00C71F 1 25 1C 0E 1D .byte $25,$1C,$0E,$1D,$25 ; $C71F-$C723
|
|
00C723 1 25
|
|
00C724 1
|
|
00C724 1 ; ----------------------------------------------------------------------------
|
|
00C724 1 ; Set timing, process event slot two, and invoke an inline command.
|
|
00C724 1 ; ----------------------------------------------------------------------------
|
|
00C724 1
|
|
00C724 1 A9 04 lda #$04 ; $C724: A9 04
|
|
00C726 1 85 FD sta $FD ; $C726: 85 FD
|
|
00C728 1
|
|
00C728 1 A0 02 ldy #$02 ; $C728: A0 02
|
|
00C72A 1 20 66 EB jsr DispatchNextQueuedEvent ; $C72A: 20 66 EB
|
|
00C72D 1
|
|
00C72D 1 20 0A EB jsr QueueInlineObjectEvent ; $C72D: 20 0A EB
|
|
00C730 1
|
|
00C730 1 02 88 C4 .byte $02,$88,$C4 ; $C730-$C732
|
|
00C733 1
|
|
00C733 1 ; ----------------------------------------------------------------------------
|
|
00C733 1 ; Wait for ten iterations of a $3C-tick delay.
|
|
00C733 1 ; ----------------------------------------------------------------------------
|
|
00C733 1
|
|
00C733 1 A9 0A lda #$0A ; $C733: A9 0A
|
|
00C735 1 85 49 sta $49 ; $C735: 85 49
|
|
00C737 1
|
|
00C737 1 ResultsDelayLoop: ; $C737
|
|
00C737 1 A9 3C lda #$3C ; $C737: A9 3C
|
|
00C739 1 20 41 EB jsr StoreObjectEventBankValue ; $C739: 20 41 EB
|
|
00C73C 1
|
|
00C73C 1 C6 49 dec $49 ; $C73C: C6 49
|
|
00C73E 1 D0 F7 bne ResultsDelayLoop ; $C73E: D0 F7
|
|
00C740 1
|
|
00C740 1 ; ----------------------------------------------------------------------------
|
|
00C740 1 ; Disable APU channels and clear state.
|
|
00C740 1 ; ----------------------------------------------------------------------------
|
|
00C740 1
|
|
00C740 1 A9 00 lda #$00 ; $C740: A9 00
|
|
00C742 1 8D 00 01 sta $0100 ; $C742: 8D 00 01
|
|
00C745 1 8D 15 40 sta APUSTATUS ; $C745: 8D 15 40
|
|
00C748 1 85 1E sta SessionActive ; $C748: 85 1E
|
|
00C74A 1
|
|
00C74A 1 ; ----------------------------------------------------------------------------
|
|
00C74A 1 ; Shared entry point used by RESET and other transition paths.
|
|
00C74A 1 ; ----------------------------------------------------------------------------
|
|
00C74A 1
|
|
00C74A 1 InitializeTitleScreen: ; $C74A
|
|
00C74A 1 20 9D EB jsr InitializeQueuedEventSystem ; $C74A: 20 9D EB
|
|
00C74D 1
|
|
00C74D 1 A9 00 lda #$00 ; $C74D: A9 00
|
|
00C74F 1 85 EF sta GameplaySuspended ; $C74F: 85 EF
|
|
00C751 1
|
|
00C751 1 E6 1D inc TransitionActive ; $C751: E6 1D
|
|
00C753 1
|
|
00C753 1 ; ----------------------------------------------------------------------------
|
|
00C753 1 ; Configure PPU shadow state.
|
|
00C753 1 ; ----------------------------------------------------------------------------
|
|
00C753 1
|
|
00C753 1 A9 80 lda #$80 ; $C753: A9 80
|
|
00C755 1 85 DD sta PpuCtrlShadow ; $C755: 85 DD
|
|
00C757 1
|
|
00C757 1 20 6C E9 jsr DisablePpuRendering ; $C757: 20 6C E9
|
|
00C75A 1
|
|
00C75A 1 A9 25 lda #$25 ; $C75A: A9 25
|
|
00C75C 1 20 85 E9 jsr FillPpuMemoryAfterValueSaved ; $C75C: 20 85 E9
|
|
00C75F 1
|
|
00C75F 1 ; ----------------------------------------------------------------------------
|
|
00C75F 1 ; $EA63 consumes the two bytes immediately following each JSR.
|
|
00C75F 1 ; ----------------------------------------------------------------------------
|
|
00C75F 1
|
|
00C75F 1 20 63 EA jsr ProcessInlinePpuStream ; $C75F: 20 63 EA
|
|
00C762 1
|
|
00C762 1 8D F8 .byte $8D,$F8 ; $C762-$C763
|
|
00C764 1
|
|
00C764 1 20 63 EA jsr ProcessInlinePpuStream ; $C764: 20 63 EA
|
|
00C767 1
|
|
00C767 1 00 C0 .byte $00,$C0 ; $C767-$C768
|
|
00C769 1
|
|
00C769 1 20 78 E9 jsr EnableNmiAndWaitForFrame ; $C769: 20 78 E9
|
|
00C76C 1
|
|
00C76C 1 ; ----------------------------------------------------------------------------
|
|
00C76C 1 ; Enable the standard APU channels and initialize timing.
|
|
00C76C 1 ; ----------------------------------------------------------------------------
|
|
00C76C 1
|
|
00C76C 1 A9 0F lda #$0F ; $C76C: A9 0F
|
|
00C76E 1 8D 00 01 sta $0100 ; $C76E: 8D 00 01
|
|
00C771 1 8D 15 40 sta APUSTATUS ; $C771: 8D 15 40
|
|
00C774 1
|
|
00C774 1 A9 08 lda #$08 ; $C774: A9 08
|
|
00C776 1 85 FD sta $FD ; $C776: 85 FD
|
|
00C778 1
|
|
00C778 1 ; ----------------------------------------------------------------------------
|
|
00C778 1 ; Refresh state and wait through three input-release cycles.
|
|
00C778 1 ;
|
|
00C778 1 ; The branch at $C78A targets $C77A, not $C783.
|
|
00C778 1 ; ----------------------------------------------------------------------------
|
|
00C778 1
|
|
00C778 1 C6 40 dec ModeFlags ; $C778: C6 40
|
|
00C77A 1
|
|
00C77A 1 RefreshTitleScreen: ; $C77A
|
|
00C77A 1 E6 40 inc ModeFlags ; $C77A: E6 40
|
|
00C77C 1
|
|
00C77C 1 20 CF E5 jsr QueueModeIndicatorTiles ; $C77C: 20 CF E5
|
|
00C77F 1
|
|
00C77F 1 A9 03 lda #$03 ; $C77F: A9 03
|
|
00C781 1 85 1B sta $1B ; $C781: 85 1B
|
|
00C783 1
|
|
00C783 1 WaitForTitleInputRelease: ; $C783
|
|
00C783 1 20 48 EB jsr SelectObjectEventBank1 ; $C783: 20 48 EB
|
|
00C786 1
|
|
00C786 1 A5 15 lda ControllerPressed1 ; $C786: A5 15
|
|
00C788 1 29 20 and #$20 ; $C788: 29 20
|
|
00C78A 1 D0 EE bne RefreshTitleScreen ; $C78A: D0 EE
|
|
00C78C 1
|
|
00C78C 1 A5 E3 lda FrameCounter ; $C78C: A5 E3
|
|
00C78E 1 D0 F3 bne WaitForTitleInputRelease ; $C78E: D0 F3
|
|
00C790 1
|
|
00C790 1 C6 1B dec $1B ; $C790: C6 1B
|
|
00C792 1 D0 EF bne WaitForTitleInputRelease ; $C792: D0 EF
|
|
00C794 1
|
|
00C794 1 ; ----------------------------------------------------------------------------
|
|
00C794 1 ; Restore transition state and return to the initialization loop.
|
|
00C794 1 ;
|
|
00C794 1 ; A is zero when execution reaches STA $1D because the successful DEC $1B
|
|
00C794 1 ; produced zero.
|
|
00C794 1 ; ----------------------------------------------------------------------------
|
|
00C794 1
|
|
00C794 1 85 1D sta TransitionActive ; $C794: 85 1D
|
|
00C796 1
|
|
00C796 1 A9 01 lda #$01 ; $C796: A9 01
|
|
00C798 1 85 EF sta GameplaySuspended ; $C798: 85 EF
|
|
00C79A 1
|
|
00C79A 1 A9 00 lda #$00 ; $C79A: A9 00
|
|
00C79C 1 8D 96 05 sta $0596 ; $C79C: 8D 96 05
|
|
00C79F 1 8D 00 01 sta $0100 ; $C79F: 8D 00 01
|
|
00C7A2 1 8D 15 40 sta APUSTATUS ; $C7A2: 8D 15 40
|
|
00C7A5 1
|
|
00C7A5 1 20 9D EB jsr InitializeQueuedEventSystem ; $C7A5: 20 9D EB
|
|
00C7A8 1
|
|
00C7A8 1 20 0A EB jsr QueueInlineObjectEvent ; $C7A8: 20 0A EB
|
|
00C7AB 1
|
|
00C7AB 1 03 88 C4 .byte $03,$88,$C4 ; $C7AB-$C7AD
|
|
00C7AE 1
|
|
00C7AE 1 4C AA C4 jmp InitializeSessionDisplay ; $C7AE: 4C AA C4
|
|
00C7B1 1
|
|
00C7B1 1 ; ============================================================================
|
|
00C7B1 1 ; $C7B1-$C7C8
|
|
00C7B1 1 ; Initialize object sorting/index tables.
|
|
00C7B1 1 ;
|
|
00C7B1 1 ; Called by RESET at $C422.
|
|
00C7B1 1 ; ============================================================================
|
|
00C7B1 1
|
|
00C7B1 1 ; ----------------------------------------------------------------------------
|
|
00C7B1 1 ; Contract:
|
|
00C7B1 1 ; Description: Initializes Sprite Sort Tables.
|
|
00C7B1 1 ; Entry: Registers: A, X
|
|
00C7B1 1 ; Returns/products: Registers/clobbers: A, X
|
|
00C7B1 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C7B1 1 ; Memory effects: $0377, $038c, $0399
|
|
00C7B1 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C7B1 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C7B1 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C7B1 1 ; ----------------------------------------------------------------------------
|
|
00C7B1 1 InitializeSpriteSortTables: ; $C7B1
|
|
00C7B1 1 A2 14 ldx #$14 ; $C7B1: A2 14
|
|
00C7B3 1
|
|
00C7B3 1 InitializeSpriteSortIndexLoop: ; $C7B3
|
|
00C7B3 1 8A txa ; $C7B3: 8A
|
|
00C7B4 1 0A asl ; $C7B4: 0A
|
|
00C7B5 1 ; A = X * 2
|
|
00C7B5 1
|
|
00C7B5 1 9D 77 03 sta $0377,x ; $C7B5: 9D 77 03
|
|
00C7B8 1
|
|
00C7B8 1 E0 0D cpx #$0D ; $C7B8: E0 0D
|
|
00C7BA 1 B0 03 bcs InitializeNextSpriteSortIndex ; $C7BA: B0 03
|
|
00C7BC 1
|
|
00C7BC 1 9D 8C 03 sta $038C,x ; $C7BC: 9D 8C 03
|
|
00C7BF 1
|
|
00C7BF 1 InitializeNextSpriteSortIndex: ; $C7BF
|
|
00C7BF 1 CA dex ; $C7BF: CA
|
|
00C7C0 1 D0 F1 bne InitializeSpriteSortIndexLoop
|
|
00C7C2 1 ; $C7C0: D0 F1
|
|
00C7C2 1
|
|
00C7C2 1 ; ----------------------------------------------------------------------------
|
|
00C7C2 1 ; X is zero when the loop terminates.
|
|
00C7C2 1 ; Clear two additional entries.
|
|
00C7C2 1 ; ----------------------------------------------------------------------------
|
|
00C7C2 1
|
|
00C7C2 1 8E 8C 03 stx $038C ; $C7C2: 8E 8C 03
|
|
00C7C5 1 8E 99 03 stx $0399 ; $C7C5: 8E 99 03
|
|
00C7C8 1
|
|
00C7C8 1 60 rts ; $C7C8: 60
|
|
00C7C9 1
|
|
00C7C9 1 ; ============================================================================
|
|
00C7C9 1 ; $C7C9-$C7DC
|
|
00C7C9 1 ; Draw eight blank encoded characters.
|
|
00C7C9 1 ;
|
|
00C7C9 1 ; Called earlier from the state-initialization sequence at $C5BA.
|
|
00C7C9 1 ; ============================================================================
|
|
00C7C9 1
|
|
00C7C9 1 ; ----------------------------------------------------------------------------
|
|
00C7C9 1 ; Contract:
|
|
00C7C9 1 ; Description: Clears or resets Eight Character Field.
|
|
00C7C9 1 ; Entry: No register input inferred
|
|
00C7C9 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00C7C9 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C7C9 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00C7C9 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C7C9 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C7C9 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C7C9 1 ; ----------------------------------------------------------------------------
|
|
00C7C9 1 ClearEightCharacterField: ; $C7C9
|
|
00C7C9 1 18 clc ; $C7C9: 18
|
|
00C7CA 1
|
|
00C7CA 1 A9 20 lda #$20 ; $C7CA: A9 20
|
|
00C7CC 1 A2 EC ldx #$EC ; $C7CC: A2 EC
|
|
00C7CE 1 A0 08 ldy #$08 ; $C7CE: A0 08
|
|
00C7D0 1
|
|
00C7D0 1 20 17 EA jsr CopyInlineDisplayRecord ; $C7D0: 20 17 EA
|
|
00C7D3 1
|
|
00C7D3 1 ; Inline text consumed by $EA17:
|
|
00C7D3 1 ; count $08 followed by eight blank characters ($25).
|
|
00C7D3 1 08 .byte $08 ; $C7D3
|
|
00C7D4 1 25 25 25 25 .byte $25,$25,$25,$25 ; $C7D4-$C7D7
|
|
00C7D8 1 25 25 25 25 .byte $25,$25,$25,$25 ; $C7D8-$C7DB
|
|
00C7DC 1
|
|
00C7DC 1 60 rts ; $C7DC: 60
|
|
00C7DD 1
|
|
00C7DD 1 ; ============================================================================
|
|
00C7DD 1 ; $C7DD-$C819
|
|
00C7DD 1 ; Write a seven-byte PPU data sequence and update two OAM entries.
|
|
00C7DD 1 ; ============================================================================
|
|
00C7DD 1
|
|
00C7DD 1 ; ----------------------------------------------------------------------------
|
|
00C7DD 1 ; Contract:
|
|
00C7DD 1 ; Description: Queues Player Selection Display.
|
|
00C7DD 1 ; Entry: Registers: A, X, Y; Memory: $33, $34, $3e, $c02a, $c030, $e1, $13, $4b
|
|
00C7DD 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00C7DD 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C7DD 1 ; Memory effects: $02fd, $02ff, $32
|
|
00C7DD 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C7DD 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C7DD 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00C7DD 1 ; ----------------------------------------------------------------------------
|
|
00C7DD 1 QueuePlayerSelectionDisplay: ; $C7DD
|
|
00C7DD 1 18 clc ; $C7DD: 18
|
|
00C7DE 1
|
|
00C7DE 1 A9 3F lda #$3F ; $C7DE: A9 3F
|
|
00C7E0 1 A2 11 ldx #$11 ; $C7E0: A2 11
|
|
00C7E2 1 A0 07 ldy #$07 ; $C7E2: A0 07
|
|
00C7E4 1
|
|
00C7E4 1 20 17 EA jsr CopyInlineDisplayRecord ; $C7E4: 20 17 EA
|
|
00C7E7 1
|
|
00C7E7 1 ; ----------------------------------------------------------------------------
|
|
00C7E7 1 ; Inline data consumed by $EA17.
|
|
00C7E7 1 ;
|
|
00C7E7 1 ; The first byte is the length, followed by seven data bytes.
|
|
00C7E7 1 ; ----------------------------------------------------------------------------
|
|
00C7E7 1
|
|
00C7E7 1 07 .byte $07 ; $C7E7: length
|
|
00C7E8 1 00 27 00 30 .byte $00,$27,$00,$30 ; $C7E8-$C7EB
|
|
00C7EC 1 00 27 00 .byte $00,$27,$00 ; $C7EC-$C7EE
|
|
00C7EF 1
|
|
00C7EF 1 ; ----------------------------------------------------------------------------
|
|
00C7EF 1 ; Select one of the values at $34/$35 based on the low bit of $33.
|
|
00C7EF 1 ; Use that value as an index into the tables at $C02A and $C030.
|
|
00C7EF 1 ;
|
|
00C7EF 1 ; The resulting values are written into one pair of OAM entries.
|
|
00C7EF 1 ; ----------------------------------------------------------------------------
|
|
00C7EF 1
|
|
00C7EF 1 A5 33 lda RoundStateIndex ; $C7EF: A5 33
|
|
00C7F1 1 29 01 and #$01 ; $C7F1: 29 01
|
|
00C7F3 1
|
|
00C7F3 1 48 pha ; $C7F3: 48
|
|
00C7F4 1 ; Save the selected side.
|
|
00C7F4 1
|
|
00C7F4 1 AA tax ; $C7F4: AA
|
|
00C7F5 1 B4 34 ldy PlayerOneSelection,x ; $C7F5: B4 34
|
|
00C7F7 1
|
|
00C7F7 1 A6 3E ldx PpuQueueOffset ; $C7F7: A6 3E
|
|
00C7F9 1
|
|
00C7F9 1 B9 2A C0 lda $C02A,y ; $C7F9: B9 2A C0
|
|
00C7FC 1 9D FD 02 sta $02FD,x ; $C7FC: 9D FD 02
|
|
00C7FF 1
|
|
00C7FF 1 B9 30 C0 lda $C030,y ; $C7FF: B9 30 C0
|
|
00C802 1 9D FF 02 sta $02FF,x ; $C802: 9D FF 02
|
|
00C805 1
|
|
00C805 1 ; ----------------------------------------------------------------------------
|
|
00C805 1 ; Select the opposite $34/$35 entry and write the corresponding table values
|
|
00C805 1 ; into the other OAM pair.
|
|
00C805 1 ; ----------------------------------------------------------------------------
|
|
00C805 1
|
|
00C805 1 68 pla
|
|
00C806 1 49 01 eor #$01
|
|
00C808 1 AA tax
|
|
00C809 1
|
|
00C809 1 B4 34 ldy $34,x
|
|
00C80B 1 A6 3E ldx $3E
|
|
00C80D 1
|
|
00C80D 1 B9 2A C0 lda $C02A,y
|
|
00C810 1 9D F9 02 sta $02F9,x
|
|
00C813 1
|
|
00C813 1 B9 30 C0 lda $C030,y
|
|
00C816 1 9D FB 02 sta $02FB,x
|
|
00C819 1
|
|
00C819 1 60 rts
|
|
00C81A 1
|
|
00C81A 1 ; ============================================================================
|
|
00C81A 1 ; $C81A-$C84F
|
|
00C81A 1 ; Update paired selection indices from controller/state input.
|
|
00C81A 1 ;
|
|
00C81A 1 ; The routine works with two entries in the table at $32/$33. It selects an
|
|
00C81A 1 ; entry using $E1, modifies the selected value according to bits shifted from
|
|
00C81A 1 ; A, then verifies that the two entries are not equal.
|
|
00C81A 1 ; ============================================================================
|
|
00C81A 1
|
|
00C81A 1 UpdatePlayerSelections: ; $C81A
|
|
00C81A 1 20 48 EB jsr SelectObjectEventBank1 ; $C81A: 20 48 EB
|
|
00C81D 1
|
|
00C81D 1 SelectPlayerSelectionEntry: ; $C81D
|
|
00C81D 1 A5 E1 lda CurrentObjectIndex ; $C81D: A5 E1
|
|
00C81F 1 AA tax ; $C81F: AA
|
|
00C820 1
|
|
00C820 1 B4 13 ldy InputState1,x ; $C820: B4 13
|
|
00C822 1
|
|
00C822 1 45 4B eor ActivePlayerSide ; $C822: 45 4B
|
|
00C824 1 AA tax ; $C824: AA
|
|
00C825 1
|
|
00C825 1 98 tya ; $C825: 98
|
|
00C826 1 B4 32 ldy SelectionValue0,x ; $C826: B4 32
|
|
00C828 1
|
|
00C828 1 ; ----------------------------------------------------------------------------
|
|
00C828 1 ; Bit 0 selects whether to increment the current value.
|
|
00C828 1 ;
|
|
00C828 1 ; The value wraps from six back to zero.
|
|
00C828 1 ; ----------------------------------------------------------------------------
|
|
00C828 1
|
|
00C828 1 4A lsr ; $C828: 4A
|
|
00C829 1 90 07 bcc ApplySelectionDecrement
|
|
00C82B 1 ; $C829: 90 07
|
|
00C82B 1
|
|
00C82B 1 C8 iny ; $C82B: C8
|
|
00C82C 1
|
|
00C82C 1 C0 06 cpy #$06 ; $C82C: C0 06
|
|
00C82E 1 90 02 bcc ApplySelectionDecrement
|
|
00C830 1 ; $C82E: 90 02
|
|
00C830 1
|
|
00C830 1 A0 00 ldy #$00 ; $C830: A0 00
|
|
00C832 1
|
|
00C832 1 ; ----------------------------------------------------------------------------
|
|
00C832 1 ; Bit 1 selects whether to decrement the current value.
|
|
00C832 1 ;
|
|
00C832 1 ; The value wraps from zero to five.
|
|
00C832 1 ; ----------------------------------------------------------------------------
|
|
00C832 1
|
|
00C832 1 ApplySelectionDecrement: ; $C832
|
|
00C832 1 4A lsr ; $C832: 4A
|
|
00C833 1 90 05 bcc SavePlayerSelection ; $C833: 90 05
|
|
00C835 1
|
|
00C835 1 88 dey ; $C835: 88
|
|
00C836 1 10 02 bpl SavePlayerSelection ; $C836: 10 02
|
|
00C838 1
|
|
00C838 1 A0 05 ldy #$05 ; $C838: A0 05
|
|
00C83A 1
|
|
00C83A 1 SavePlayerSelection: ; $C83A
|
|
00C83A 1 94 32 sty SelectionValue0,x ; $C83A: 94 32
|
|
00C83C 1
|
|
00C83C 1 ; ----------------------------------------------------------------------------
|
|
00C83C 1 ; Select the opposite table entry and ensure both selections differ.
|
|
00C83C 1 ; If they are equal, wait for another update and retry.
|
|
00C83C 1 ; ----------------------------------------------------------------------------
|
|
00C83C 1
|
|
00C83C 1 8A txa ; $C83C: 8A
|
|
00C83D 1 49 01 eor #$01 ; $C83D: 49 01
|
|
00C83F 1 AA tax ; $C83F: AA
|
|
00C840 1
|
|
00C840 1 98 tya ; $C840: 98
|
|
00C841 1 D5 32 cmp SelectionValue0,x ; $C841: D5 32
|
|
00C843 1 F0 D8 beq SelectPlayerSelectionEntry
|
|
00C845 1 ; $C843: F0 D8
|
|
00C845 1
|
|
00C845 1 ; ----------------------------------------------------------------------------
|
|
00C845 1 ; Continue waiting while the selected input/state value is nonnegative.
|
|
00C845 1 ; Otherwise, decrement $43 and leave through the common engine exit.
|
|
00C845 1 ; ----------------------------------------------------------------------------
|
|
00C845 1
|
|
00C845 1 A6 E1 ldx CurrentObjectIndex ; $C845: A6 E1
|
|
00C847 1
|
|
00C847 1 B5 13 lda InputState1,x ; $C847: B5 13
|
|
00C849 1 10 CF bpl UpdatePlayerSelections ; $C849: 10 CF
|
|
00C84B 1
|
|
00C84B 1 C6 43 dec $43 ; $C84B: C6 43
|
|
00C84D 1
|
|
00C84D 1 4C 6A EB jmp CommonEngineExit ; $C84D: 4C 6A EB
|
|
00C850 1
|
|
00C850 1 ; ============================================================================
|
|
00C850 1 ; $C850-$C859
|
|
00C850 1 ; Generate a random value in the range $00-$05.
|
|
00C850 1 ; ============================================================================
|
|
00C850 1
|
|
00C850 1 ; ----------------------------------------------------------------------------
|
|
00C850 1 ; Contract:
|
|
00C850 1 ; Description: Implements Random 0 To 5.
|
|
00C850 1 ; Entry: Registers: A
|
|
00C850 1 ; Returns/products: Registers/clobbers: A; Flags: condition flags may carry result state
|
|
00C850 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C850 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00C850 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C850 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C850 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00C850 1 ; ----------------------------------------------------------------------------
|
|
00C850 1 Random0To5: ; $C850
|
|
00C850 1 20 F5 E5 jsr AdvanceRandomState ; $C850: 20 F5 E5
|
|
00C853 1 29 07 and #$07 ; $C853: 29 07
|
|
00C855 1 C9 06 cmp #$06 ; $C855: C9 06
|
|
00C857 1 B0 F7 bcs Random0To5 ; $C857: B0 F7
|
|
00C859 1
|
|
00C859 1 60 rts ; $C859: 60
|
|
00C85A 1
|
|
00C85A 1 ; ============================================================================
|
|
00C85A 1 ; $C85A-$C87D
|
|
00C85A 1 ; Build four 16-byte PPU command/data blocks in the queue at $0300.
|
|
00C85A 1 ;
|
|
00C85A 1 ; The destination high byte begins at $21. Four blocks are generated for:
|
|
00C85A 1 ;
|
|
00C85A 1 ; $21xx
|
|
00C85A 1 ; $22xx
|
|
00C85A 1 ; $23xx
|
|
00C85A 1 ; $24xx
|
|
00C85A 1 ;
|
|
00C85A 1 ; Each block is filled with sixteen $26 bytes.
|
|
00C85A 1 ; ============================================================================
|
|
00C85A 1
|
|
00C85A 1 ; ----------------------------------------------------------------------------
|
|
00C85A 1 ; Contract:
|
|
00C85A 1 ; Description: Implements Fill Selection Background Blocks.
|
|
00C85A 1 ; Entry: Registers: A, X, Y; Memory: $4a
|
|
00C85A 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00C85A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C85A 1 ; Memory effects: $44, $4a, $0300
|
|
00C85A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C85A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C85A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C85A 1 ; ----------------------------------------------------------------------------
|
|
00C85A 1 FillSelectionBackgroundBlocks: ; $C85A
|
|
00C85A 1 A9 00 lda #$00 ; $C85A: A9 00
|
|
00C85C 1 85 44 sta PlayerSelectionActive ; $C85C: 85 44
|
|
00C85E 1
|
|
00C85E 1 A9 88 lda #$88 ; $C85E: A9 88
|
|
00C860 1
|
|
00C860 1 FillNextBackgroundBlock: ; $C860
|
|
00C860 1 85 4A sta $4A ; $C860: 85 4A
|
|
00C862 1 AA tax ; $C862: AA
|
|
00C863 1
|
|
00C863 1 18 clc ; $C863: 18
|
|
00C864 1
|
|
00C864 1 A9 21 lda #$21 ; $C864: A9 21
|
|
00C866 1 A0 10 ldy #$10 ; $C866: A0 10
|
|
00C868 1 20 3E EA jsr AllocateDisplayBufferRecord ; $C868: 20 3E EA
|
|
00C86B 1
|
|
00C86B 1 ; ----------------------------------------------------------------------------
|
|
00C86B 1 ; Fill sixteen queue bytes with $26.
|
|
00C86B 1 ;
|
|
00C86B 1 ; X is expected to point into the PPU command queue after the setup call above.
|
|
00C86B 1 ; ----------------------------------------------------------------------------
|
|
00C86B 1
|
|
00C86B 1 A0 10 ldy #$10 ; $C86B: A0 10
|
|
00C86D 1 A9 26 lda #$26 ; $C86D: A9 26
|
|
00C86F 1
|
|
00C86F 1 FillBackgroundBlock: ; $C86F
|
|
00C86F 1 9D 00 03 sta $0300,x ; $C86F: 9D 00 03
|
|
00C872 1
|
|
00C872 1 E8 inx ; $C872: E8
|
|
00C873 1 88 dey ; $C873: 88
|
|
00C874 1 D0 F9 bne FillBackgroundBlock ; $C874: D0 F9
|
|
00C876 1
|
|
00C876 1 ; ----------------------------------------------------------------------------
|
|
00C876 1 ; Advance the saved queue/destination value by $20.
|
|
00C876 1 ; Continue until the addition carries.
|
|
00C876 1 ; ----------------------------------------------------------------------------
|
|
00C876 1
|
|
00C876 1 A5 4A lda $4A ; $C876: A5 4A
|
|
00C878 1 18 clc ; $C878: 18
|
|
00C879 1 69 20 adc #$20 ; $C879: 69 20
|
|
00C87B 1 90 E3 bcc FillNextBackgroundBlock ; $C87B: 90 E3
|
|
00C87D 1
|
|
00C87D 1 60 rts ; $C87D: 60
|
|
00C87E 1
|
|
00C87E 1 ; ============================================================================
|
|
00C87E 1 ; $C87E-$C8A1
|
|
00C87E 1 ; Derive paired state values in $0F and $10.
|
|
00C87E 1 ;
|
|
00C87E 1 ; Both outputs are cleared when $EF is nonzero. Otherwise, the routine combines
|
|
00C87E 1 ; bits from $40, $4B, and $33, then stores complementary values in $0F/$10.
|
|
00C87E 1 ; Carry from LSR $40 is used to conditionally increment each result.
|
|
00C87E 1 ; ============================================================================
|
|
00C87E 1
|
|
00C87E 1 ; ----------------------------------------------------------------------------
|
|
00C87E 1 ; Contract:
|
|
00C87E 1 ; Description: Calculates Controller Assignments.
|
|
00C87E 1 ; Entry: Registers: A; Memory: $ef, $40, $4b, $33
|
|
00C87E 1 ; Returns/products: Registers/clobbers: A
|
|
00C87E 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C87E 1 ; Memory effects: $0f, $10
|
|
00C87E 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C87E 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C87E 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C87E 1 ; ----------------------------------------------------------------------------
|
|
00C87E 1 CalculateControllerAssignments: ; $C87E
|
|
00C87E 1 A9 00 lda #$00 ; $C87E: A9 00
|
|
00C880 1 85 0F sta DerivedControl0 ; $C880: 85 0F
|
|
00C882 1 85 10 sta $10 ; $C882: 85 10
|
|
00C884 1
|
|
00C884 1 A5 EF lda GameplaySuspended ; $C884: A5 EF
|
|
00C886 1 D0 19 bne ControllerAssignmentReturn ; $C886: D0 19
|
|
00C888 1
|
|
00C888 1 A5 40 lda ModeFlags ; $C888: A5 40
|
|
00C88A 1 4A lsr ; $C88A: 4A
|
|
00C88B 1 ; Carry receives bit 0 of $40.
|
|
00C88B 1
|
|
00C88B 1 A5 40 lda ModeFlags ; $C88B: A5 40
|
|
00C88D 1 45 4B eor ActivePlayerSide ; $C88D: 45 4B
|
|
00C88F 1 45 33 eor RoundStateIndex ; $C88F: 45 33
|
|
00C891 1 29 01 and #$01 ; $C891: 29 01
|
|
00C893 1 85 10 sta $10 ; $C893: 85 10
|
|
00C895 1
|
|
00C895 1 90 02 bcc CalculateOppositeControllerAssignment ; $C895: 90 02
|
|
00C897 1
|
|
00C897 1 E6 10 inc $10 ; $C897: E6 10
|
|
00C899 1
|
|
00C899 1 CalculateOppositeControllerAssignment: ; $C899
|
|
00C899 1 49 01 eor #$01 ; $C899: 49 01
|
|
00C89B 1 85 0F sta DerivedControl0 ; $C89B: 85 0F
|
|
00C89D 1
|
|
00C89D 1 90 02 bcc ControllerAssignmentReturn ; $C89D: 90 02
|
|
00C89F 1
|
|
00C89F 1 E6 0F inc DerivedControl0 ; $C89F: E6 0F
|
|
00C8A1 1
|
|
00C8A1 1 ControllerAssignmentReturn: ; $C8A1
|
|
00C8A1 1 60 rts ; $C8A1: 60
|
|
00C8A2 1
|
|
00C8A2 1 ; ============================================================================
|
|
00C8A2 1 ; $C8A2-$C8BA
|
|
00C8A2 1 ; Initialize the four-byte table at $0598-$059B.
|
|
00C8A2 1 ;
|
|
00C8A2 1 ; For each Y value from 3 down to 1:
|
|
00C8A2 1 ; 1. Compute A = Y * 2.
|
|
00C8A2 1 ; 2. Search $9F-$A1 for a matching value.
|
|
00C8A2 1 ; 3. Store the matching X index into $0598,Y.
|
|
00C8A2 1 ; 4. Store $FF when no match is found.
|
|
00C8A2 1 ;
|
|
00C8A2 1 ; Finally, clear $0598 because Y is zero when the loop terminates.
|
|
00C8A2 1 ; ============================================================================
|
|
00C8A2 1
|
|
00C8A2 1 ; ----------------------------------------------------------------------------
|
|
00C8A2 1 ; Contract:
|
|
00C8A2 1 ; Description: Initializes Object State Lookup.
|
|
00C8A2 1 ; Entry: Registers: A, X, Y; Memory: $9f
|
|
00C8A2 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00C8A2 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C8A2 1 ; Memory effects: $0598
|
|
00C8A2 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C8A2 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C8A2 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C8A2 1 ; ----------------------------------------------------------------------------
|
|
00C8A2 1 InitializeObjectStateLookup: ; $C8A2
|
|
00C8A2 1 A0 03 ldy #$03 ; $C8A2: A0 03
|
|
00C8A4 1
|
|
00C8A4 1 Routine_C8A4_NextEntry: ; $C8A4
|
|
00C8A4 1 98 tya ; $C8A4: 98
|
|
00C8A5 1 0A asl ; $C8A5: 0A
|
|
00C8A6 1 ; A = Y * 2
|
|
00C8A6 1
|
|
00C8A6 1 A2 02 ldx #$02 ; $C8A6: A2 02
|
|
00C8A8 1
|
|
00C8A8 1 Routine_C8A8_SearchValues: ; $C8A8
|
|
00C8A8 1 D5 9F cmp SecondaryActorState0,x ; $C8A8: D5 9F
|
|
00C8AA 1 F0 05 beq Routine_C8B1_SaveResult ; $C8AA: F0 05
|
|
00C8AC 1
|
|
00C8AC 1 CA dex ; $C8AC: CA
|
|
00C8AD 1 10 F9 bpl Routine_C8A8_SearchValues
|
|
00C8AF 1 ; $C8AD: 10 F9
|
|
00C8AF 1
|
|
00C8AF 1 A9 FF lda #$FF ; $C8AF: A9 FF
|
|
00C8B1 1 ; No matching entry was found.
|
|
00C8B1 1
|
|
00C8B1 1 Routine_C8B1_SaveResult: ; $C8B1
|
|
00C8B1 1 99 98 05 sta $0598,y ; $C8B1: 99 98 05
|
|
00C8B4 1
|
|
00C8B4 1 88 dey ; $C8B4: 88
|
|
00C8B5 1 D0 ED bne Routine_C8A4_NextEntry ; $C8B5: D0 ED
|
|
00C8B7 1
|
|
00C8B7 1 ; ----------------------------------------------------------------------------
|
|
00C8B7 1 ; Y is zero when the loop exits.
|
|
00C8B7 1 ; Clear the first table entry at $0598.
|
|
00C8B7 1 ; ----------------------------------------------------------------------------
|
|
00C8B7 1
|
|
00C8B7 1 8C 98 05 sty $0598 ; $C8B7: 8C 98 05
|
|
00C8BA 1
|
|
00C8BA 1 60 rts ; $C8BA: 60
|
|
00C8BB 1
|
|
00C8BB 1 ; ============================================================================
|
|
00C8BB 1 ; $C8BB-$C8E7
|
|
00C8BB 1 ; Expand a linked or variable-length record list into the buffer at $0400,X.
|
|
00C8BB 1 ;
|
|
00C8BB 1 ; Entry:
|
|
00C8BB 1 ; X appears to be the destination offset into $0400.
|
|
00C8BB 1 ; $00/$01 points to an inline or external pointer record.
|
|
00C8BB 1 ;
|
|
00C8BB 1 ; Operation:
|
|
00C8BB 1 ; 1. $E99A retrieves a pointer and returns its low byte in A.
|
|
00C8BB 1 ; 2. The high byte is read through ($00),Y.
|
|
00C8BB 1 ; 3. Each source record begins with a nonzero size/offset byte.
|
|
00C8BB 1 ; 4. The current source pointer is written to $0400,X as a low/high pair.
|
|
00C8BB 1 ; 5. The source pointer advances by (record byte * 4) + carry adjustment.
|
|
00C8BB 1 ; 6. A zero record byte terminates the list.
|
|
00C8BB 1 ;
|
|
00C8BB 1 ; Exit:
|
|
00C8BB 1 ; Y = $04
|
|
00C8BB 1 ; ============================================================================
|
|
00C8BB 1
|
|
00C8BB 1 ; ----------------------------------------------------------------------------
|
|
00C8BB 1 ; Contract:
|
|
00C8BB 1 ; Description: Implements Expand Record Pointer List.
|
|
00C8BB 1 ; Entry: Registers: A, X; Memory: (indirectptrlo), (recordptrlo), recordptrlo, recordptrhi
|
|
00C8BB 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00C8BB 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C8BB 1 ; Memory effects: recordptrlo, recordptrhi, $0400
|
|
00C8BB 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C8BB 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C8BB 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00C8BB 1 ; ----------------------------------------------------------------------------
|
|
00C8BB 1 ExpandRecordPointerList: ; $C8BB
|
|
00C8BB 1 20 9A E9 jsr DecodeInlineParameters ; $C8BB: 20 9A E9
|
|
00C8BE 1
|
|
00C8BE 1 85 02 sta RecordPtrLo ; $C8BE: 85 02
|
|
00C8C0 1 ; Save source pointer low byte.
|
|
00C8C0 1
|
|
00C8C0 1 B1 00 lda (IndirectPtrLo),y ; $C8C0: B1 00
|
|
00C8C2 1 85 03 sta RecordPtrHi ; $C8C2: 85 03
|
|
00C8C4 1 ; Save source pointer high byte.
|
|
00C8C4 1
|
|
00C8C4 1 A0 00 ldy #$00 ; $C8C4: A0 00
|
|
00C8C6 1
|
|
00C8C6 1 ; ----------------------------------------------------------------------------
|
|
00C8C6 1 ; Read the next record byte through pointer $02/$03.
|
|
00C8C6 1 ; A zero byte terminates the list.
|
|
00C8C6 1 ; ----------------------------------------------------------------------------
|
|
00C8C6 1
|
|
00C8C6 1 Routine_C8C6_ReadRecord: ; $C8C6
|
|
00C8C6 1 B1 02 lda (RecordPtrLo),y ; $C8C6: B1 02
|
|
00C8C8 1 F0 1B beq Routine_C8E5_Done ; $C8C8: F0 1B
|
|
00C8CA 1
|
|
00C8CA 1 ; ----------------------------------------------------------------------------
|
|
00C8CA 1 ; Store the current source pointer into the destination table.
|
|
00C8CA 1 ; Each destination entry is a two-byte pointer.
|
|
00C8CA 1 ; ----------------------------------------------------------------------------
|
|
00C8CA 1
|
|
00C8CA 1 A5 02 lda RecordPtrLo ; $C8CA: A5 02
|
|
00C8CC 1 9D 00 04 sta $0400,x ; $C8CC: 9D 00 04
|
|
00C8CF 1 E8 inx ; $C8CF: E8
|
|
00C8D0 1
|
|
00C8D0 1 A5 03 lda RecordPtrHi ; $C8D0: A5 03
|
|
00C8D2 1 9D 00 04 sta $0400,x ; $C8D2: 9D 00 04
|
|
00C8D5 1 E8 inx ; $C8D5: E8
|
|
00C8D6 1
|
|
00C8D6 1 ; ----------------------------------------------------------------------------
|
|
00C8D6 1 ; Advance the source pointer.
|
|
00C8D6 1 ;
|
|
00C8D6 1 ; Reload the record byte, multiply it by four, then add it to the pointer low
|
|
00C8D6 1 ; byte. SEC means the effective increment is:
|
|
00C8D6 1 ;
|
|
00C8D6 1 ; (record byte * 4) + 1
|
|
00C8D6 1 ;
|
|
00C8D6 1 ; If the low-byte addition carries, increment the pointer high byte.
|
|
00C8D6 1 ; ----------------------------------------------------------------------------
|
|
00C8D6 1
|
|
00C8D6 1 B1 02 lda (RecordPtrLo),y ; $C8D6: B1 02
|
|
00C8D8 1 0A asl ; $C8D8: 0A
|
|
00C8D9 1 0A asl ; $C8D9: 0A
|
|
00C8DA 1
|
|
00C8DA 1 38 sec ; $C8DA: 38
|
|
00C8DB 1 65 02 adc RecordPtrLo ; $C8DB: 65 02
|
|
00C8DD 1 85 02 sta RecordPtrLo ; $C8DD: 85 02
|
|
00C8DF 1
|
|
00C8DF 1 90 E5 bcc Routine_C8C6_ReadRecord ; $C8DF: 90 E5
|
|
00C8E1 1
|
|
00C8E1 1 E6 03 inc RecordPtrHi ; $C8E1: E6 03
|
|
00C8E3 1 B0 E1 bcs Routine_C8C6_ReadRecord ; $C8E3: B0 E1
|
|
00C8E5 1 ; Always taken because INC does not alter carry.
|
|
00C8E5 1
|
|
00C8E5 1 ; ----------------------------------------------------------------------------
|
|
00C8E5 1 ; Return with Y = 4.
|
|
00C8E5 1 ; ----------------------------------------------------------------------------
|
|
00C8E5 1
|
|
00C8E5 1 Routine_C8E5_Done: ; $C8E5
|
|
00C8E5 1 A0 04 ldy #$04 ; $C8E5: A0 04
|
|
00C8E7 1 60 rts ; $C8E7: 60
|
|
00C8E8 1
|
|
00C8E8 1 ; ============================================================================
|
|
00C8E8 1 ; $C8E8-$C903
|
|
00C8E8 1 ; Initialize paired counters and random bitfields.
|
|
00C8E8 1 ;
|
|
00C8E8 1 ; For X = 1 and X = 0:
|
|
00C8E8 1 ; $51,X is initialized to eight.
|
|
00C8E8 1 ; Eight random carry bits are shifted into $4F,X.
|
|
00C8E8 1 ; One additional random carry bit is shifted into $4D,X.
|
|
00C8E8 1 ; ============================================================================
|
|
00C8E8 1
|
|
00C8E8 1 ; ----------------------------------------------------------------------------
|
|
00C8E8 1 ; Contract:
|
|
00C8E8 1 ; Description: Initializes Random Bitfields.
|
|
00C8E8 1 ; Entry: Registers: A, X, Y
|
|
00C8E8 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00C8E8 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C8E8 1 ; Memory effects: counter51
|
|
00C8E8 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C8E8 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C8E8 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C8E8 1 ; ----------------------------------------------------------------------------
|
|
00C8E8 1 InitializeRandomBitfields: ; $C8E8
|
|
00C8E8 1 A2 01 ldx #$01 ; $C8E8: A2 01
|
|
00C8EA 1
|
|
00C8EA 1 Routine_C8EA_NextEntry: ; $C8EA
|
|
00C8EA 1 A0 08 ldy #$08 ; $C8EA: A0 08
|
|
00C8EC 1
|
|
00C8EC 1 98 tya ; $C8EC: 98
|
|
00C8ED 1 95 51 sta Counter51,x ; $C8ED: 95 51
|
|
00C8EF 1
|
|
00C8EF 1 Routine_C8EF_BuildRandomBits: ; $C8EF
|
|
00C8EF 1 20 F5 E5 jsr AdvanceRandomState ; $C8EF: 20 F5 E5
|
|
00C8F2 1 C9 80 cmp #$80 ; $C8F2: C9 80
|
|
00C8F4 1 ; Carry reflects whether random value >= $80.
|
|
00C8F4 1
|
|
00C8F4 1 76 4F ror RandomBits0,x ; $C8F4: 76 4F
|
|
00C8F6 1 ; Shift the random carry bit into $4F,X.
|
|
00C8F6 1
|
|
00C8F6 1 88 dey ; $C8F6: 88
|
|
00C8F7 1 D0 F6 bne Routine_C8EF_BuildRandomBits
|
|
00C8F9 1 ; $C8F7: D0 F6
|
|
00C8F9 1
|
|
00C8F9 1 20 F5 E5 jsr AdvanceRandomState ; $C8F9: 20 F5 E5
|
|
00C8FC 1 C9 80 cmp #$80 ; $C8FC: C9 80
|
|
00C8FE 1
|
|
00C8FE 1 76 4D ror RandomState0,x ; $C8FE: 76 4D
|
|
00C900 1 ; Shift one random carry bit into $4D,X.
|
|
00C900 1
|
|
00C900 1 CA dex ; $C900: CA
|
|
00C901 1 10 E7 bpl Routine_C8EA_NextEntry ; $C901: 10 E7
|
|
00C903 1
|
|
00C903 1 60 rts ; $C903: 60
|
|
00C904 1
|
|
00C904 1 ; ============================================================================
|
|
00C904 1 ; $C904-$C91A
|
|
00C904 1 ; Dispatch one of two inline records according to the sign of $4D,X.
|
|
00C904 1 ;
|
|
00C904 1 ; X is selected from the low bit of $33.
|
|
00C904 1 ; ============================================================================
|
|
00C904 1
|
|
00C904 1 ; ----------------------------------------------------------------------------
|
|
00C904 1 ; Contract:
|
|
00C904 1 ; Description: Queues Random State Record.
|
|
00C904 1 ; Entry: Registers: A; Memory: roundstateindex, randomstate0
|
|
00C904 1 ; Returns/products: Registers/clobbers: A, X
|
|
00C904 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C904 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00C904 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C904 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C904 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C904 1 ; ----------------------------------------------------------------------------
|
|
00C904 1 QueueRandomStateRecord: ; $C904
|
|
00C904 1 A5 33 lda RoundStateIndex ; $C904: A5 33
|
|
00C906 1 29 01 and #$01 ; $C906: 29 01
|
|
00C908 1 AA tax ; $C908: AA
|
|
00C909 1
|
|
00C909 1 B5 4D lda RandomState0,x ; $C909: B5 4D
|
|
00C90B 1 30 07 bmi QueueAlternateRandomStateRecord ; $C90B: 30 07
|
|
00C90D 1
|
|
00C90D 1 20 BB C8 jsr ExpandRecordPointerList ; $C90D: 20 BB C8
|
|
00C910 1 ; Inline pointer/record consumed by $C8BB.
|
|
00C910 1 0C B4 ED .byte $0C,$B4,$ED ; $C910-$C912
|
|
00C913 1
|
|
00C913 1 60 rts ; $C913: 60
|
|
00C914 1
|
|
00C914 1 QueueAlternateRandomStateRecord: ; $C914
|
|
00C914 1 20 BB C8 jsr ExpandRecordPointerList ; $C914: 20 BB C8
|
|
00C917 1
|
|
00C917 1 ; Alternate inline pointer/record consumed by $C8BB.
|
|
00C917 1 0C 51 EC .byte $0C,$51,$EC ; $C917-$C919
|
|
00C91A 1
|
|
00C91A 1 60 rts ; $C91A: 60
|
|
00C91B 1
|
|
00C91B 1 ; ============================================================================
|
|
00C91B 1 ; $C91B-$C942
|
|
00C91B 1 ; Select and dispatch a record from the paired random state.
|
|
00C91B 1 ;
|
|
00C91B 1 ; The low bit of $33 selects X. $51,X determines how many times $4F,X is
|
|
00C91B 1 ; shifted right. If the selected carry is clear, the first record is used.
|
|
00C91B 1 ; If the carry is set, $4C is decremented and the second record is used.
|
|
00C91B 1 ; ============================================================================
|
|
00C91B 1
|
|
00C91B 1 ; ----------------------------------------------------------------------------
|
|
00C91B 1 ; Contract:
|
|
00C91B 1 ; Description: Queues Random Direction Record.
|
|
00C91B 1 ; Entry: Registers: A, Y; Memory: roundstateindex, counter51, randombits0, randomstate0
|
|
00C91B 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00C91B 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C91B 1 ; Memory effects: horizontaldirectionmask
|
|
00C91B 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C91B 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C91B 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C91B 1 ; ----------------------------------------------------------------------------
|
|
00C91B 1 QueueRandomDirectionRecord: ; $C91B
|
|
00C91B 1 A5 33 lda RoundStateIndex ; $C91B: A5 33
|
|
00C91D 1 29 01 and #$01 ; $C91D: 29 01
|
|
00C91F 1 AA tax ; $C91F: AA
|
|
00C920 1
|
|
00C920 1 B4 51 ldy Counter51,x ; $C920: B4 51
|
|
00C922 1 F0 08 beq UseRandomDirectionSignBit ; $C922: F0 08
|
|
00C924 1
|
|
00C924 1 B5 4F lda RandomBits0,x ; $C924: B5 4F
|
|
00C926 1
|
|
00C926 1 SelectRandomDirectionBit: ; $C926
|
|
00C926 1 4A lsr ; $C926: 4A
|
|
00C927 1
|
|
00C927 1 88 dey ; $C927: 88
|
|
00C928 1 D0 FC bne SelectRandomDirectionBit
|
|
00C92A 1 ; $C928: D0 FC
|
|
00C92A 1
|
|
00C92A 1 F0 03 beq SaveDirectionSelection ; $C92A: F0 03
|
|
00C92C 1 ; Always taken because Y is zero.
|
|
00C92C 1 ; Carry from the final LSR is preserved.
|
|
00C92C 1
|
|
00C92C 1 UseRandomDirectionSignBit: ; $C92C
|
|
00C92C 1 B5 4D lda RandomState0,x ; $C92C: B5 4D
|
|
00C92E 1 0A asl ; $C92E: 0A
|
|
00C92F 1 ; Move bit 7 into carry.
|
|
00C92F 1
|
|
00C92F 1 SaveDirectionSelection: ; $C92F
|
|
00C92F 1 84 4C sty HorizontalDirectionMask ; $C92F: 84 4C
|
|
00C931 1
|
|
00C931 1 B0 07 bcs QueueAlternateDirectionRecord ; $C931: B0 07
|
|
00C933 1
|
|
00C933 1 20 BB C8 jsr ExpandRecordPointerList ; $C933: 20 BB C8
|
|
00C936 1
|
|
00C936 1 ; Inline pointer/record consumed by $C8BB.
|
|
00C936 1 00 39 ED .byte $00,$39,$ED ; $C936-$C938
|
|
00C939 1
|
|
00C939 1 60 rts ; $C939: 60
|
|
00C93A 1
|
|
00C93A 1 QueueAlternateDirectionRecord: ; $C93A
|
|
00C93A 1 C6 4C dec HorizontalDirectionMask ; $C93A: C6 4C
|
|
00C93C 1
|
|
00C93C 1 20 BB C8 jsr ExpandRecordPointerList ; $C93C: 20 BB C8
|
|
00C93F 1
|
|
00C93F 1 ; Alternate inline pointer/record consumed by $C8BB.
|
|
00C93F 1 00 D6 EB .byte $00,$D6,$EB ; $C93F-$C941
|
|
00C942 1
|
|
00C942 1 60 rts ; $C942: 60
|
|
00C943 1
|
|
00C943 1
|
|
00C943 1
|
|
00C943 1 ; ============================================================================
|
|
00C943 1 ; $C943-$C94E
|
|
00C943 1 ; Clear the base entries of three object-field arrays.
|
|
00C943 1 ; ============================================================================
|
|
00C943 1
|
|
00C943 1 ; ----------------------------------------------------------------------------
|
|
00C943 1 ; Contract:
|
|
00C943 1 ; Description: Clears or resets Base Acceleration Fields.
|
|
00C943 1 ; Entry: Registers: A
|
|
00C943 1 ; Returns/products: Registers/clobbers: A
|
|
00C943 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C943 1 ; Memory effects: $0506, $0537, $0568
|
|
00C943 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C943 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C943 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 6.
|
|
00C943 1 ; ----------------------------------------------------------------------------
|
|
00C943 1 ClearBaseAccelerationFields: ; $C943
|
|
00C943 1 A9 00 lda #$00 ; $C943: A9 00
|
|
00C945 1
|
|
00C945 1 8D 06 05 sta $0506 ; $C945: 8D 06 05
|
|
00C948 1 8D 37 05 sta $0537 ; $C948: 8D 37 05
|
|
00C94B 1 8D 68 05 sta $0568 ; $C94B: 8D 68 05
|
|
00C94E 1
|
|
00C94E 1 60 rts ; $C94E: 60
|
|
00C94F 1
|
|
00C94F 1 ; ============================================================================
|
|
00C94F 1 ; $C94F-$C958
|
|
00C94F 1 ; Initialize the fields at $0509/$050A, $053A/$053B, and $056B/$056C
|
|
00C94F 1 ; with six inline zero bytes.
|
|
00C94F 1 ;
|
|
00C94F 1 ; Routine $C985 retrieves the address of the inline data and consumes all
|
|
00C94F 1 ; six bytes.
|
|
00C94F 1 ; ============================================================================
|
|
00C94F 1
|
|
00C94F 1 ; ----------------------------------------------------------------------------
|
|
00C94F 1 ; Contract:
|
|
00C94F 1 ; Description: Clears or resets Base Position Fields.
|
|
00C94F 1 ; Entry: No register input inferred
|
|
00C94F 1 ; Returns/products: No direct product inferred
|
|
00C94F 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C94F 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00C94F 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C94F 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C94F 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 6.
|
|
00C94F 1 ; ----------------------------------------------------------------------------
|
|
00C94F 1 ClearBasePositionFields: ; $C94F
|
|
00C94F 1 20 85 C9 jsr LoadBaseMotionFieldsInline ; $C94F: 20 85 C9
|
|
00C952 1
|
|
00C952 1 00 00 .word $0000 ; $C952-$C953
|
|
00C954 1 00 00 .word $0000 ; $C954-$C955
|
|
00C956 1 00 00 .word $0000 ; $C956-$C957
|
|
00C958 1
|
|
00C958 1 60 rts ; $C958: 60
|
|
00C959 1
|
|
00C959 1 ; ============================================================================
|
|
00C959 1 ; $C959-$C962
|
|
00C959 1 ; Initialize the fields at $0507/$0508, $0538/$0539, and $0569/$056A
|
|
00C959 1 ; with six inline zero bytes.
|
|
00C959 1 ;
|
|
00C959 1 ; Routine $C963 retrieves the address of the inline data and consumes all
|
|
00C959 1 ; six bytes.
|
|
00C959 1 ; ============================================================================
|
|
00C959 1
|
|
00C959 1 ClearBaseMotionFields: ; $C959
|
|
00C959 1 20 63 C9 jsr LoadBasePositionFieldsInline ; $C959: 20 63 C9
|
|
00C95C 1
|
|
00C95C 1 00 00 .word $0000 ; $C95C-$C95D
|
|
00C95E 1 00 00 .word $0000 ; $C95E-$C95F
|
|
00C960 1 00 00 .word $0000 ; $C960-$C961
|
|
00C962 1
|
|
00C962 1 60 rts ; $C962: 60
|
|
00C963 1
|
|
00C963 1 ; ============================================================================
|
|
00C963 1 ; $C963-$C984
|
|
00C963 1 ; Load three 16-bit field values from inline data.
|
|
00C963 1 ;
|
|
00C963 1 ; $E99A retrieves the inline-data pointer:
|
|
00C963 1 ; X = first byte
|
|
00C963 1 ; A = second byte
|
|
00C963 1 ; $00/$01 points to the remaining bytes
|
|
00C963 1 ;
|
|
00C963 1 ; The six input bytes are stored as:
|
|
00C963 1 ;
|
|
00C963 1 ; byte 0 -> $0507
|
|
00C963 1 ; byte 1 -> $0508
|
|
00C963 1 ; byte 2 -> $0538
|
|
00C963 1 ; byte 3 -> $0539
|
|
00C963 1 ; byte 4 -> $0569
|
|
00C963 1 ; byte 5 -> $056A
|
|
00C963 1 ;
|
|
00C963 1 ; Exit:
|
|
00C963 1 ; Y = $04
|
|
00C963 1 ; ============================================================================
|
|
00C963 1 ; ============================================================================
|
|
00C963 1 ; $C963-$C984
|
|
00C963 1 ; Load the $09/$0A, $3A/$3B, and $6B/$6C field group.
|
|
00C963 1 ; ============================================================================
|
|
00C963 1
|
|
00C963 1 ; ----------------------------------------------------------------------------
|
|
00C963 1 ; Contract:
|
|
00C963 1 ; Description: Implements Load Base Position Fields Inline.
|
|
00C963 1 ; Entry: Registers: A, X, Y; Memory: (indirectptrlo)
|
|
00C963 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00C963 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C963 1 ; Memory effects: $0509, $050a, $053a, $053b, $056b, $056c
|
|
00C963 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C963 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C963 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00C963 1 ; ----------------------------------------------------------------------------
|
|
00C963 1 LoadBasePositionFieldsInline: ; $C963
|
|
00C963 1 20 9A E9 jsr DecodeInlineParameters ; $C963: 20 9A E9
|
|
00C966 1
|
|
00C966 1 8E 09 05 stx $0509 ; $C966: 8E 09 05
|
|
00C969 1 8D 0A 05 sta $050A ; $C969: 8D 0A 05
|
|
00C96C 1
|
|
00C96C 1 B1 00 lda (IndirectPtrLo),y ; $C96C: B1 00
|
|
00C96E 1 8D 3A 05 sta $053A ; $C96E: 8D 3A 05
|
|
00C971 1
|
|
00C971 1 C8 iny ; $C971: C8
|
|
00C972 1
|
|
00C972 1 B1 00 lda (IndirectPtrLo),y ; $C972: B1 00
|
|
00C974 1 8D 3B 05 sta $053B ; $C974: 8D 3B 05
|
|
00C977 1
|
|
00C977 1 C8 iny ; $C977: C8
|
|
00C978 1
|
|
00C978 1 B1 00 lda (IndirectPtrLo),y ; $C978: B1 00
|
|
00C97A 1 8D 6B 05 sta $056B ; $C97A: 8D 6B 05
|
|
00C97D 1
|
|
00C97D 1 C8 iny ; $C97D: C8
|
|
00C97E 1
|
|
00C97E 1 B1 00 lda (IndirectPtrLo),y ; $C97E: B1 00
|
|
00C980 1 8D 6C 05 sta $056C ; $C980: 8D 6C 05
|
|
00C983 1
|
|
00C983 1 C8 iny ; $C983: C8
|
|
00C984 1 60 rts ; $C984: 60
|
|
00C985 1
|
|
00C985 1 ; ============================================================================
|
|
00C985 1 ; $C985-$C9A6
|
|
00C985 1 ; Load the $07/$08, $38/$39, and $69/$6A field group.
|
|
00C985 1 ; ============================================================================
|
|
00C985 1
|
|
00C985 1 ; ----------------------------------------------------------------------------
|
|
00C985 1 ; Contract:
|
|
00C985 1 ; Description: Implements Load Base Motion Fields Inline.
|
|
00C985 1 ; Entry: Registers: A, X, Y; Memory: (indirectptrlo)
|
|
00C985 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00C985 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C985 1 ; Memory effects: $0507, $0508, $0538, $0539, $0569, $056a
|
|
00C985 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C985 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C985 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00C985 1 ; ----------------------------------------------------------------------------
|
|
00C985 1 LoadBaseMotionFieldsInline: ; $C985
|
|
00C985 1 20 9A E9 jsr DecodeInlineParameters ; $C985: 20 9A E9
|
|
00C988 1
|
|
00C988 1 8E 07 05 stx $0507 ; $C988: 8E 07 05
|
|
00C98B 1 8D 08 05 sta $0508 ; $C98B: 8D 08 05
|
|
00C98E 1
|
|
00C98E 1 B1 00 lda (IndirectPtrLo),y ; $C98E: B1 00
|
|
00C990 1 8D 38 05 sta $0538 ; $C990: 8D 38 05
|
|
00C993 1
|
|
00C993 1 C8 iny ; $C993: C8
|
|
00C994 1
|
|
00C994 1 B1 00 lda (IndirectPtrLo),y ; $C994: B1 00
|
|
00C996 1 8D 39 05 sta $0539 ; $C996: 8D 39 05
|
|
00C999 1
|
|
00C999 1 C8 iny ; $C999: C8
|
|
00C99A 1
|
|
00C99A 1 B1 00 lda (IndirectPtrLo),y ; $C99A: B1 00
|
|
00C99C 1 8D 69 05 sta $0569 ; $C99C: 8D 69 05
|
|
00C99F 1
|
|
00C99F 1 C8 iny ; $C99F: C8
|
|
00C9A0 1
|
|
00C9A0 1 B1 00 lda (IndirectPtrLo),y ; $C9A0: B1 00
|
|
00C9A2 1 8D 6A 05 sta $056A ; $C9A2: 8D 6A 05
|
|
00C9A5 1
|
|
00C9A5 1 C8 iny ; $C9A5: C8
|
|
00C9A6 1 60 rts ; $C9A6: 60
|
|
00C9A7 1
|
|
00C9A7 1 ; ============================================================================
|
|
00C9A7 1 ; $C9A7-$C9BF
|
|
00C9A7 1 ; Load two indexed 16-bit field values from inline data.
|
|
00C9A7 1 ;
|
|
00C9A7 1 ; Entry:
|
|
00C9A7 1 ; X = object-array offset
|
|
00C9A7 1 ;
|
|
00C9A7 1 ; The four input bytes are stored as:
|
|
00C9A7 1 ;
|
|
00C9A7 1 ; byte 0 -> $0509,X
|
|
00C9A7 1 ; byte 1 -> $050A,X
|
|
00C9A7 1 ; byte 2 -> $053A,X
|
|
00C9A7 1 ; byte 3 -> $053B,X
|
|
00C9A7 1 ;
|
|
00C9A7 1 ; Exit:
|
|
00C9A7 1 ; Y = $02
|
|
00C9A7 1 ; ============================================================================
|
|
00C9A7 1
|
|
00C9A7 1 LoadObjectPositionInline: ; $C9A7
|
|
00C9A7 1 20 9A E9 jsr DecodeInlineParameters ; $C9A7: 20 9A E9
|
|
00C9AA 1
|
|
00C9AA 1 9D 09 05 sta $0509,x ; $C9AA: 9D 09 05
|
|
00C9AD 1
|
|
00C9AD 1 B1 00 lda (IndirectPtrLo),y ; $C9AD: B1 00
|
|
00C9AF 1 9D 0A 05 sta $050A,x ; $C9AF: 9D 0A 05
|
|
00C9B2 1
|
|
00C9B2 1 C8 iny ; $C9B2: C8
|
|
00C9B3 1
|
|
00C9B3 1 B1 00 lda (IndirectPtrLo),y ; $C9B3: B1 00
|
|
00C9B5 1 9D 3A 05 sta $053A,x ; $C9B5: 9D 3A 05
|
|
00C9B8 1
|
|
00C9B8 1 C8 iny ; $C9B8: C8
|
|
00C9B9 1
|
|
00C9B9 1 B1 00 lda (IndirectPtrLo),y ; $C9B9: B1 00
|
|
00C9BB 1 9D 3B 05 sta $053B,x ; $C9BB: 9D 3B 05
|
|
00C9BE 1
|
|
00C9BE 1 C8 iny ; $C9BE: C8
|
|
00C9BF 1 60 rts ; $C9BF: 60
|
|
00C9C0 1
|
|
00C9C0 1 ; ============================================================================
|
|
00C9C0 1 ; $C9C0-$CA22
|
|
00C9C0 1 ; Compare an indexed object's position against the base object's position.
|
|
00C9C0 1 ;
|
|
00C9C0 1 ; Entry:
|
|
00C9C0 1 ; X = indexed object-array offset
|
|
00C9C0 1 ;
|
|
00C9C0 1 ; Return:
|
|
00C9C0 1 ; A = $00 when the comparison succeeds and state is updated
|
|
00C9C0 1 ; A = $01 when any comparison fails
|
|
00C9C0 1 ;
|
|
00C9C0 1 ; The routine performs three checks:
|
|
00C9C0 1 ; 1. $056B/$056C must be less than three.
|
|
00C9C0 1 ; 2. The horizontal distance must satisfy the signed threshold test.
|
|
00C9C0 1 ; 3. The vertical distance must satisfy the signed threshold test.
|
|
00C9C0 1 ; ============================================================================
|
|
00C9C0 1
|
|
00C9C0 1 ; ----------------------------------------------------------------------------
|
|
00C9C0 1 ; Contract:
|
|
00C9C0 1 ; Description: Implements Try Merge Object Into Base.
|
|
00C9C0 1 ; Entry: Registers: A, Y; Memory: $056b, $056c, $0509, $050a, $053a
|
|
00C9C0 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00C9C0 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00C9C0 1 ; Memory effects: $050a, $053b, $056c, $056d, $056e, basemotionactive
|
|
00C9C0 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00C9C0 1 ; comparison, load, or store path and are not a stable API product.
|
|
00C9C0 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00C9C0 1 ; ----------------------------------------------------------------------------
|
|
00C9C0 1 TryMergeObjectIntoBase: ; $C9C0
|
|
00C9C0 1 AD 6B 05 lda $056B ; $C9C0: AD 6B 05
|
|
00C9C3 1 C9 00 cmp #$00 ; $C9C3: C9 00
|
|
00C9C5 1
|
|
00C9C5 1 AD 6C 05 lda $056C ; $C9C5: AD 6C 05
|
|
00C9C8 1 E9 03 sbc #$03 ; $C9C8: E9 03
|
|
00C9CA 1 ; Carry from CMP #$00 participates in this
|
|
00C9CA 1 ; subtraction because LDA does not alter carry.
|
|
00C9CA 1
|
|
00C9CA 1 10 54 bpl ObjectMergeFailed ; $C9CA: 10 54
|
|
00C9CC 1
|
|
00C9CC 1 ; ----------------------------------------------------------------------------
|
|
00C9CC 1 ; Calculate the signed difference between the base horizontal position and
|
|
00C9CC 1 ; the indexed object's horizontal position:
|
|
00C9CC 1 ;
|
|
00C9CC 1 ; base: $0509/$050A
|
|
00C9CC 1 ; indexed: $0509,X/$050A,X
|
|
00C9CC 1 ;
|
|
00C9CC 1 ; The low-byte difference is passed in Y and the high-byte difference in A
|
|
00C9CC 1 ; to the helper at $E7CB.
|
|
00C9CC 1 ; ----------------------------------------------------------------------------
|
|
00C9CC 1
|
|
00C9CC 1 38 sec ; $C9CC: 38
|
|
00C9CD 1
|
|
00C9CD 1 AD 09 05 lda $0509 ; $C9CD: AD 09 05
|
|
00C9D0 1 FD 09 05 sbc $0509,x ; $C9D0: FD 09 05
|
|
00C9D3 1 A8 tay ; $C9D3: A8
|
|
00C9D4 1
|
|
00C9D4 1 AD 0A 05 lda $050A ; $C9D4: AD 0A 05
|
|
00C9D7 1 FD 0A 05 sbc $050A,x ; $C9D7: FD 0A 05
|
|
00C9DA 1
|
|
00C9DA 1 20 CB E7 jsr AbsoluteValueAY ; $C9DA: 20 CB E7
|
|
00C9DD 1
|
|
00C9DD 1 ; ----------------------------------------------------------------------------
|
|
00C9DD 1 ; Test the normalized horizontal result.
|
|
00C9DD 1 ;
|
|
00C9DD 1 ; CPY #$80 establishes carry for the following SBC #$00. This effectively
|
|
00C9DD 1 ; includes Y's sign/high-bit state in the signed comparison.
|
|
00C9DD 1 ; ----------------------------------------------------------------------------
|
|
00C9DD 1
|
|
00C9DD 1 C0 80 cpy #$80 ; $C9DD: C0 80
|
|
00C9DF 1 E9 00 sbc #$00 ; $C9DF: E9 00
|
|
00C9E1 1
|
|
00C9E1 1 10 3D bpl ObjectMergeFailed ; $C9E1: 10 3D
|
|
00C9E3 1
|
|
00C9E3 1 ; ----------------------------------------------------------------------------
|
|
00C9E3 1 ; Repeat the same signed-distance calculation for the vertical position:
|
|
00C9E3 1 ;
|
|
00C9E3 1 ; base: $053A/$053B
|
|
00C9E3 1 ; indexed: $053A,X/$053B,X
|
|
00C9E3 1 ; ----------------------------------------------------------------------------
|
|
00C9E3 1
|
|
00C9E3 1 38 sec ; $C9E3: 38
|
|
00C9E4 1
|
|
00C9E4 1 AD 3A 05 lda $053A ; $C9E4: AD 3A 05
|
|
00C9E7 1 FD 3A 05 sbc $053A,x ; $C9E7: FD 3A 05
|
|
00C9EA 1 A8 tay ; $C9EA: A8
|
|
00C9EB 1
|
|
00C9EB 1 AD 3B 05 lda $053B ; $C9EB: AD 3B 05
|
|
00C9EE 1 FD 3B 05 sbc $053B,x ; $C9EE: FD 3B 05
|
|
00C9F1 1
|
|
00C9F1 1 20 CB E7 jsr AbsoluteValueAY ; $C9F1: 20 CB E7
|
|
00C9F4 1
|
|
00C9F4 1 C0 80 cpy #$80 ; $C9F4: C0 80
|
|
00C9F6 1 E9 00 sbc #$00 ; $C9F6: E9 00
|
|
00C9F8 1
|
|
00C9F8 1 10 26 bpl ObjectMergeFailed ; $C9F8: 10 26
|
|
00C9FA 1
|
|
00C9FA 1 ; ----------------------------------------------------------------------------
|
|
00C9FA 1 ; The indexed object passed all comparisons.
|
|
00C9FA 1 ;
|
|
00C9FA 1 ; Copy its high position bytes into the base object, set $056C to one,
|
|
00C9FA 1 ; clear the indexed object's values at $056D/$056E, and reset shared fields.
|
|
00C9FA 1 ; ----------------------------------------------------------------------------
|
|
00C9FA 1
|
|
00C9FA 1 BD 0A 05 lda $050A,x ; $C9FA: BD 0A 05
|
|
00C9FD 1 8D 0A 05 sta $050A ; $C9FD: 8D 0A 05
|
|
00CA00 1
|
|
00CA00 1 BD 3B 05 lda $053B,x ; $CA00: BD 3B 05
|
|
00CA03 1 8D 3B 05 sta $053B ; $CA03: 8D 3B 05
|
|
00CA06 1
|
|
00CA06 1 A9 01 lda #$01 ; $CA06: A9 01
|
|
00CA08 1 8D 6C 05 sta $056C ; $CA08: 8D 6C 05
|
|
00CA0B 1
|
|
00CA0B 1 A9 00 lda #$00 ; $CA0B: A9 00
|
|
00CA0D 1 9D 6D 05 sta $056D,x ; $CA0D: 9D 6D 05
|
|
00CA10 1 9D 6E 05 sta $056E,x ; $CA10: 9D 6E 05
|
|
00CA13 1
|
|
00CA13 1 20 43 C9 jsr ClearBaseAccelerationFields ; $CA13: 20 43 C9
|
|
00CA16 1 20 4F C9 jsr ClearBasePositionFields ; $CA16: 20 4F C9
|
|
00CA19 1
|
|
00CA19 1 E6 5E inc BaseMotionEventCount ; $CA19: E6 5E
|
|
00CA1B 1
|
|
00CA1B 1 A9 00 lda #$00 ; $CA1B: A9 00
|
|
00CA1D 1 85 5C sta BaseMotionActive ; $CA1D: 85 5C
|
|
00CA1F 1
|
|
00CA1F 1 60 rts ; $CA1F: 60
|
|
00CA20 1 ; Return A = $00.
|
|
00CA20 1
|
|
00CA20 1 ; ----------------------------------------------------------------------------
|
|
00CA20 1 ; Comparison failed.
|
|
00CA20 1 ; ----------------------------------------------------------------------------
|
|
00CA20 1
|
|
00CA20 1 ObjectMergeFailed: ; $CA20
|
|
00CA20 1 A9 01 lda #$01 ; $CA20: A9 01
|
|
00CA22 1 60 rts ; $CA22: 60
|
|
00CA23 1
|
|
00CA23 1 ; ============================================================================
|
|
00CA23 1 ; $CA23-$CA4B
|
|
00CA23 1 ; Initialize base movement and position fields.
|
|
00CA23 1 ;
|
|
00CA23 1 ; The routine has a secondary entry point at $CA2A. The primary entry at
|
|
00CA23 1 ; $CA23 clears $056A and branches directly to $CA2F because A is zero.
|
|
00CA23 1 ;
|
|
00CA23 1 ; Entry at $CA2A:
|
|
00CA23 1 ; A is stored into $056A before continuing.
|
|
00CA23 1 ;
|
|
00CA23 1 ; Inputs preserved into object fields:
|
|
00CA23 1 ; X -> $0508
|
|
00CA23 1 ; Y -> $0539
|
|
00CA23 1 ;
|
|
00CA23 1 ; Exit:
|
|
00CA23 1 ; $5C is incremented.
|
|
00CA23 1 ; ============================================================================
|
|
00CA23 1
|
|
00CA23 1 ; ----------------------------------------------------------------------------
|
|
00CA23 1 ; Contract:
|
|
00CA23 1 ; Description: Initializes Base Motion Zero.
|
|
00CA23 1 ; Entry: Registers: A, X, Y
|
|
00CA23 1 ; Returns/products: Registers/clobbers: A
|
|
00CA23 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CA23 1 ; Memory effects: $056a, $0568, $0508, $0539, $0507, $0538, $0569
|
|
00CA23 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CA23 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CA23 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CA23 1 ; ----------------------------------------------------------------------------
|
|
00CA23 1 InitializeBaseMotionZero: ; $CA23
|
|
00CA23 1 A9 00 lda #$00 ; $CA23: A9 00
|
|
00CA25 1 8D 6A 05 sta $056A ; $CA25: 8D 6A 05
|
|
00CA28 1
|
|
00CA28 1 F0 05 beq StoreBaseMotionInitialization
|
|
00CA2A 1 ; $CA28: F0 05
|
|
00CA2A 1 ; Always taken because A is zero.
|
|
00CA2A 1
|
|
00CA2A 1 ; ----------------------------------------------------------------------------
|
|
00CA2A 1 ; Alternate entry point.
|
|
00CA2A 1 ;
|
|
00CA2A 1 ; Callers entering at $CA2A can provide a nonzero value in A for $056A.
|
|
00CA2A 1 ; ----------------------------------------------------------------------------
|
|
00CA2A 1
|
|
00CA2A 1 ; ----------------------------------------------------------------------------
|
|
00CA2A 1 ; Contract:
|
|
00CA2A 1 ; Description: Initializes Base Motion.
|
|
00CA2A 1 ; Entry: Registers: A, X, Y
|
|
00CA2A 1 ; Returns/products: Registers/clobbers: A
|
|
00CA2A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CA2A 1 ; Memory effects: $056a, $0568, $0508, $0539, $0507, $0538, $0569, $0506
|
|
00CA2A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CA2A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CA2A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CA2A 1 ; ----------------------------------------------------------------------------
|
|
00CA2A 1 InitializeBaseMotion: ; $CA2A
|
|
00CA2A 1 8D 6A 05 sta $056A ; $CA2A: 8D 6A 05
|
|
00CA2D 1
|
|
00CA2D 1 A9 FF lda #$FF ; $CA2D: A9 FF
|
|
00CA2F 1
|
|
00CA2F 1 ; ----------------------------------------------------------------------------
|
|
00CA2F 1 ; Mark the base entry at $0568 and store the supplied X/Y field values.
|
|
00CA2F 1 ;
|
|
00CA2F 1 ; Primary entry stores $00 at $0568 because it branches directly here with
|
|
00CA2F 1 ; A equal to zero. Alternate entry stores $FF.
|
|
00CA2F 1 ; ----------------------------------------------------------------------------
|
|
00CA2F 1
|
|
00CA2F 1 StoreBaseMotionInitialization: ; $CA2F
|
|
00CA2F 1 8D 68 05 sta $0568 ; $CA2F: 8D 68 05
|
|
00CA32 1
|
|
00CA32 1 8E 08 05 stx $0508 ; $CA32: 8E 08 05
|
|
00CA35 1 8C 39 05 sty $0539 ; $CA35: 8C 39 05
|
|
00CA38 1
|
|
00CA38 1 ; ----------------------------------------------------------------------------
|
|
00CA38 1 ; Clear the remaining base position and movement fields.
|
|
00CA38 1 ; ----------------------------------------------------------------------------
|
|
00CA38 1
|
|
00CA38 1 A9 00 lda #$00 ; $CA38: A9 00
|
|
00CA3A 1
|
|
00CA3A 1 8D 07 05 sta $0507 ; $CA3A: 8D 07 05
|
|
00CA3D 1 8D 38 05 sta $0538 ; $CA3D: 8D 38 05
|
|
00CA40 1 8D 69 05 sta $0569 ; $CA40: 8D 69 05
|
|
00CA43 1
|
|
00CA43 1 8D 06 05 sta $0506 ; $CA43: 8D 06 05
|
|
00CA46 1 8D 37 05 sta $0537 ; $CA46: 8D 37 05
|
|
00CA49 1
|
|
00CA49 1 E6 5C inc BaseMotionActive ; $CA49: E6 5C
|
|
00CA4B 1
|
|
00CA4B 1 60 rts ; $CA4B: 60
|
|
00CA4C 1
|
|
00CA4C 1 ; ============================================================================
|
|
00CA4C 1 ; $CA4C-$CAD1
|
|
00CA4C 1 ; State progression and trajectory/update loop
|
|
00CA4C 1 ; ============================================================================
|
|
00CA4C 1
|
|
00CA4C 1 RunBaseTrajectorySequence: ; $CA4C
|
|
00CA4C 1 A5 5D lda BaseMotionPhase ; $CA4C: A5 5D
|
|
00CA4E 1 D0 04 bne AdvanceTrajectoryPhase
|
|
00CA50 1 ; $CA4E: D0 04
|
|
00CA50 1
|
|
00CA50 1 A9 40 lda #$40 ; $CA50: A9 40
|
|
00CA52 1 85 FE sta PendingAudioFlags ; $CA52: 85 FE
|
|
00CA54 1
|
|
00CA54 1 AdvanceTrajectoryPhase: ; $CA54
|
|
00CA54 1 E6 5D inc BaseMotionPhase ; $CA54: E6 5D
|
|
00CA56 1
|
|
00CA56 1 ; ----------------------------------------------------------------------------
|
|
00CA56 1 ; When the vertical high byte is nonnegative, derive new signed movement
|
|
00CA56 1 ; values from the current position fields.
|
|
00CA56 1 ; ----------------------------------------------------------------------------
|
|
00CA56 1
|
|
00CA56 1 AD 3B 05 lda $053B ; $CA56: AD 3B 05
|
|
00CA59 1 30 1C bmi UpdateTrajectoryFrame ; $CA59: 30 1C
|
|
00CA5B 1
|
|
00CA5B 1 ; ----------------------------------------------------------------------------
|
|
00CA5B 1 ; Derive $0508 from the negated high position at $050A.
|
|
00CA5B 1 ;
|
|
00CA5B 1 ; CMP #$80 followed by ROR is used twice to perform sign-aware shifting.
|
|
00CA5B 1 ; ----------------------------------------------------------------------------
|
|
00CA5B 1
|
|
00CA5B 1 A9 00 lda #$00 ; $CA5B: A9 00
|
|
00CA5D 1 38 sec ; $CA5D: 38
|
|
00CA5E 1 ED 0A 05 sbc $050A ; $CA5E: ED 0A 05
|
|
00CA61 1
|
|
00CA61 1 C9 80 cmp #$80 ; $CA61: C9 80
|
|
00CA63 1 6A ror ; $CA63: 6A
|
|
00CA64 1
|
|
00CA64 1 C9 80 cmp #$80 ; $CA64: C9 80
|
|
00CA66 1 6A ror ; $CA66: 6A
|
|
00CA67 1
|
|
00CA67 1 8D 08 05 sta $0508 ; $CA67: 8D 08 05
|
|
00CA6A 1
|
|
00CA6A 1 ; ----------------------------------------------------------------------------
|
|
00CA6A 1 ; Derive $0539 from $053B.
|
|
00CA6A 1 ; ----------------------------------------------------------------------------
|
|
00CA6A 1
|
|
00CA6A 1 A9 07 lda #$07 ; $CA6A: A9 07
|
|
00CA6C 1 38 sec ; $CA6C: 38
|
|
00CA6D 1 ED 3B 05 sbc $053B ; $CA6D: ED 3B 05
|
|
00CA70 1
|
|
00CA70 1 4A lsr ; $CA70: 4A
|
|
00CA71 1 4A lsr ; $CA71: 4A
|
|
00CA72 1
|
|
00CA72 1 09 C0 ora #$C0 ; $CA72: 09 C0
|
|
00CA74 1 8D 39 05 sta $0539 ; $CA74: 8D 39 05
|
|
00CA77 1
|
|
00CA77 1 ; ----------------------------------------------------------------------------
|
|
00CA77 1 ; Wait for a frame, then call $CBEC repeatedly until it returns carry set.
|
|
00CA77 1 ; ----------------------------------------------------------------------------
|
|
00CA77 1
|
|
00CA77 1 UpdateTrajectoryFrame: ; $CA77
|
|
00CA77 1 20 48 EB jsr SelectObjectEventBank1 ; $CA77: 20 48 EB
|
|
00CA7A 1
|
|
00CA7A 1 A2 00 ldx #$00 ; $CA7A: A2 00
|
|
00CA7C 1 20 EC CB jsr TestObjectCollision ; $CA7C: 20 EC CB
|
|
00CA7F 1 90 F6 bcc UpdateTrajectoryFrame ; $CA7F: 90 F6
|
|
00CA81 1
|
|
00CA81 1 20 D2 CA jsr EvaluateTrajectoryResult ; $CA81: 20 D2 CA
|
|
00CA84 1
|
|
00CA84 1 ; ----------------------------------------------------------------------------
|
|
00CA84 1 ; Continue the state loop until $056C reaches at least three.
|
|
00CA84 1 ; ----------------------------------------------------------------------------
|
|
00CA84 1
|
|
00CA84 1 AD 6C 05 lda $056C ; $CA84: AD 6C 05
|
|
00CA87 1 C9 03 cmp #$03 ; $CA87: C9 03
|
|
00CA89 1 90 C1 bcc RunBaseTrajectorySequence ; $CA89: 90 C1
|
|
00CA8B 1
|
|
00CA8B 1 ; ----------------------------------------------------------------------------
|
|
00CA8B 1 ; Select one of three inline command records.
|
|
00CA8B 1 ; ----------------------------------------------------------------------------
|
|
00CA8B 1
|
|
00CA8B 1 A5 5F lda TrajectoryResult ; $CA8B: A5 5F
|
|
00CA8D 1 30 21 bmi WaitForTrajectoryLimit
|
|
00CA8F 1 ; $CA8D: 30 21
|
|
00CA8F 1
|
|
00CA8F 1 A5 5D lda BaseMotionPhase ; $CA8F: A5 5D
|
|
00CA91 1 D0 17 bne QueueLaterTrajectoryCommand ; $CA91: D0 17
|
|
00CA93 1
|
|
00CA93 1 AD 0A 05 lda $050A ; $CA93: AD 0A 05
|
|
00CA96 1 30 09 bmi QueueNegativeTrajectoryCommand ; $CA96: 30 09
|
|
00CA98 1
|
|
00CA98 1 20 0A EB jsr QueueInlineObjectEvent ; $CA98: 20 0A EB
|
|
00CA9B 1
|
|
00CA9B 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CA9B 1 24 A3 CD .byte $24,$A3,$CD ; $CA9B-$CA9D
|
|
00CA9E 1
|
|
00CA9E 1 4C B0 CA jmp WaitForTrajectoryLimit
|
|
00CAA1 1 ; $CA9E: 4C B0 CA
|
|
00CAA1 1
|
|
00CAA1 1 QueueNegativeTrajectoryCommand: ; $CAA1
|
|
00CAA1 1 20 0A EB jsr QueueInlineObjectEvent ; $CAA1: 20 0A EB
|
|
00CAA4 1
|
|
00CAA4 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CAA4 1 26 A3 CD .byte $26,$A3,$CD ; $CAA4-$CAA6
|
|
00CAA7 1
|
|
00CAA7 1 4C B0 CA jmp WaitForTrajectoryLimit
|
|
00CAAA 1 ; $CAA7: 4C B0 CA
|
|
00CAAA 1
|
|
00CAAA 1 QueueLaterTrajectoryCommand: ; $CAAA
|
|
00CAAA 1 20 0A EB jsr QueueInlineObjectEvent ; $CAAA: 20 0A EB
|
|
00CAAD 1
|
|
00CAAD 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CAAD 1 1A 97 CD .byte $1A,$97,$CD ; $CAAD-$CAAF
|
|
00CAB0 1
|
|
00CAB0 1 ; ----------------------------------------------------------------------------
|
|
00CAB0 1 ; Wait until the value derived by $CBEC reaches either:
|
|
00CAB0 1 ;
|
|
00CAB0 1 ; $056C or greater, or
|
|
00CAB0 1 ; at least $50.
|
|
00CAB0 1 ;
|
|
00CAB0 1 ; The returned A value is reduced by $38 and saved in $056E.
|
|
00CAB0 1 ; ----------------------------------------------------------------------------
|
|
00CAB0 1
|
|
00CAB0 1 WaitForTrajectoryLimit: ; $CAB0
|
|
00CAB0 1 20 48 EB jsr SelectObjectEventBank1 ; $CAB0: 20 48 EB
|
|
00CAB3 1
|
|
00CAB3 1 A2 00 ldx #$00 ; $CAB3: A2 00
|
|
00CAB5 1 20 EC CB jsr TestObjectCollision ; $CAB5: 20 EC CB
|
|
00CAB8 1
|
|
00CAB8 1 38 sec ; $CAB8: 38
|
|
00CAB9 1 E9 38 sbc #$38 ; $CAB9: E9 38
|
|
00CABB 1 8D 6E 05 sta $056E ; $CABB: 8D 6E 05
|
|
00CABE 1
|
|
00CABE 1 CD 6C 05 cmp $056C ; $CABE: CD 6C 05
|
|
00CAC1 1 B0 04 bcs FinishTrajectorySequence ; $CAC1: B0 04
|
|
00CAC3 1
|
|
00CAC3 1 C9 50 cmp #$50 ; $CAC3: C9 50
|
|
00CAC5 1 90 E9 bcc WaitForTrajectoryLimit
|
|
00CAC7 1 ; $CAC5: 90 E9
|
|
00CAC7 1
|
|
00CAC7 1 ; ----------------------------------------------------------------------------
|
|
00CAC7 1 ; Reset position structures and leave through the common engine exit.
|
|
00CAC7 1 ; A is zero after ClearBaseAccelerationFields, so $5C is cleared.
|
|
00CAC7 1 ; ----------------------------------------------------------------------------
|
|
00CAC7 1
|
|
00CAC7 1 FinishTrajectorySequence: ; $CAC7
|
|
00CAC7 1 20 4F C9 jsr ClearBasePositionFields ; $CAC7: 20 4F C9
|
|
00CACA 1 20 43 C9 jsr ClearBaseAccelerationFields ; $CACA: 20 43 C9
|
|
00CACD 1
|
|
00CACD 1 85 5C sta BaseMotionActive ; $CACD: 85 5C
|
|
00CACF 1
|
|
00CACF 1 4C 6A EB jmp CommonEngineExit ; $CACF: 4C 6A EB
|
|
00CAD2 1
|
|
00CAD2 1 ; ============================================================================
|
|
00CAD2 1 ; $CAD2-$CB34
|
|
00CAD2 1 ; Evaluate object state and select a transition based on position-derived data.
|
|
00CAD2 1 ;
|
|
00CAD2 1 ; The routine uses the current base-object coordinates to calculate an index
|
|
00CAD2 1 ; into the four-byte table at $CB35. The selected signed table value is saved
|
|
00CAD2 1 ; in $5F and controls subsequent state transitions.
|
|
00CAD2 1 ; ============================================================================
|
|
00CAD2 1
|
|
00CAD2 1 ; ----------------------------------------------------------------------------
|
|
00CAD2 1 ; Contract:
|
|
00CAD2 1 ; Description: Implements Evaluate Trajectory Result.
|
|
00CAD2 1 ; Entry: Registers: A, X, Y; Memory: trajectoryevaluationenabled, trajectoryresult, basemotioneventcount, $0509, $050a, $053a, $053b
|
|
00CAD2 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CAD2 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CAD2 1 ; Memory effects: trajectoryresult, stateselector, $0598
|
|
00CAD2 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CAD2 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CAD2 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00CAD2 1 ; ----------------------------------------------------------------------------
|
|
00CAD2 1 EvaluateTrajectoryResult: ; $CAD2
|
|
00CAD2 1 A5 86 lda TrajectoryEvaluationEnabled ; $CAD2: A5 86
|
|
00CAD4 1 10 5E bpl TrajectoryResultReturn ; $CAD4: 10 5E
|
|
00CAD6 1
|
|
00CAD6 1 A5 5F lda TrajectoryResult ; $CAD6: A5 5F
|
|
00CAD8 1 05 5E ora BaseMotionEventCount ; $CAD8: 05 5E
|
|
00CADA 1 D0 58 bne TrajectoryResultReturn ; $CADA: D0 58
|
|
00CADC 1
|
|
00CADC 1 ; ----------------------------------------------------------------------------
|
|
00CADC 1 ; Normalize the base horizontal position.
|
|
00CADC 1 ;
|
|
00CADC 1 ; Input:
|
|
00CADC 1 ; Y = $0509
|
|
00CADC 1 ; A = $050A
|
|
00CADC 1 ;
|
|
00CADC 1 ; The helper at $E7CB processes the 16-bit value in A:Y.
|
|
00CADC 1 ; ----------------------------------------------------------------------------
|
|
00CADC 1
|
|
00CADC 1 AC 09 05 ldy $0509 ; $CADC: AC 09 05
|
|
00CADF 1 AD 0A 05 lda $050A ; $CADF: AD 0A 05
|
|
00CAE2 1
|
|
00CAE2 1 20 CB E7 jsr AbsoluteValueAY ; $CAE2: 20 CB E7
|
|
00CAE5 1
|
|
00CAE5 1 ; ----------------------------------------------------------------------------
|
|
00CAE5 1 ; Subtract eight from the normalized high/result byte and preserve it.
|
|
00CAE5 1 ; ----------------------------------------------------------------------------
|
|
00CAE5 1
|
|
00CAE5 1 38 sec ; $CAE5: 38
|
|
00CAE6 1 E9 08 sbc #$08 ; $CAE6: E9 08
|
|
00CAE8 1
|
|
00CAE8 1 48 pha ; $CAE8: 48
|
|
00CAE9 1
|
|
00CAE9 1 ; ----------------------------------------------------------------------------
|
|
00CAE9 1 ; Compare the normalized low result in Y against $053A, then subtract $053B.
|
|
00CAE9 1 ;
|
|
00CAE9 1 ; ASL followed by LDA #$00 / ROL converts the comparison result in carry into
|
|
00CAE9 1 ; a zero-or-one high component, which becomes an index contribution.
|
|
00CAE9 1 ; ----------------------------------------------------------------------------
|
|
00CAE9 1
|
|
00CAE9 1 CC 3A 05 cpy $053A ; $CAE9: CC 3A 05
|
|
00CAEC 1 ED 3B 05 sbc $053B ; $CAEC: ED 3B 05
|
|
00CAEF 1
|
|
00CAEF 1 0A asl ; $CAEF: 0A
|
|
00CAF0 1
|
|
00CAF0 1 A9 00 lda #$00 ; $CAF0: A9 00
|
|
00CAF2 1 2A rol ; $CAF2: 2A
|
|
00CAF3 1 AA tax ; $CAF3: AA
|
|
00CAF4 1
|
|
00CAF4 1 ; ----------------------------------------------------------------------------
|
|
00CAF4 1 ; Add the normalized position to $053A/$053B.
|
|
00CAF4 1 ; ----------------------------------------------------------------------------
|
|
00CAF4 1
|
|
00CAF4 1 98 tya ; $CAF4: 98
|
|
00CAF5 1 6D 3A 05 adc $053A ; $CAF5: 6D 3A 05
|
|
00CAF8 1
|
|
00CAF8 1 68 pla ; $CAF8: 68
|
|
00CAF9 1 6D 3B 05 adc $053B ; $CAF9: 6D 3B 05
|
|
00CAFC 1
|
|
00CAFC 1 ; ----------------------------------------------------------------------------
|
|
00CAFC 1 ; Convert the result and carry state into a table index.
|
|
00CAFC 1 ;
|
|
00CAFC 1 ; X receives a value in the range $00-$03.
|
|
00CAFC 1 ; ----------------------------------------------------------------------------
|
|
00CAFC 1
|
|
00CAFC 1 0A asl ; $CAFC: 0A
|
|
00CAFD 1
|
|
00CAFD 1 8A txa ; $CAFD: 8A
|
|
00CAFE 1 2A rol ; $CAFE: 2A
|
|
00CAFF 1 AA tax ; $CAFF: AA
|
|
00CB00 1
|
|
00CB00 1 BD 35 CB lda TrajectoryResultTable,x ; $CB00: BD 35 CB
|
|
00CB03 1 85 5F sta TrajectoryResult ; $CB03: 85 5F
|
|
00CB05 1
|
|
00CB05 1 10 2D bpl TrajectoryResultReturn ; $CB05: 10 2D
|
|
00CB07 1
|
|
00CB07 1 ; ----------------------------------------------------------------------------
|
|
00CB07 1 ; Handle the negative table-result path.
|
|
00CB07 1 ; ----------------------------------------------------------------------------
|
|
00CB07 1
|
|
00CB07 1 A5 88 lda MotionDirectionState ; $CB07: A5 88
|
|
00CB09 1 D0 13 bne ApplyNegativeTrajectoryResult
|
|
00CB0B 1 ; $CB09: D0 13
|
|
00CB0B 1
|
|
00CB0B 1 A9 02 lda #$02 ; $CB0B: A9 02
|
|
00CB0D 1 C5 62 cmp PrimarySequenceState ; $CB0D: C5 62
|
|
00CB0F 1 D0 0D bne ApplyNegativeTrajectoryResult
|
|
00CB11 1 ; $CB0F: D0 0D
|
|
00CB11 1
|
|
00CB11 1 0A asl ; $CB11: 0A
|
|
00CB12 1 ; A = $04
|
|
00CB12 1
|
|
00CB12 1 85 72 sta StateSelector ; $CB12: 85 72
|
|
00CB14 1
|
|
00CB14 1 A9 FF lda #$FF ; $CB14: A9 FF
|
|
00CB16 1 8D 98 05 sta $0598 ; $CB16: 8D 98 05
|
|
00CB19 1
|
|
00CB19 1 E6 46 inc StateSequenceActive ; $CB19: E6 46
|
|
00CB1B 1
|
|
00CB1B 1 4C E4 CC jmp AdvanceAlternateStateSequence
|
|
00CB1E 1 ; $CB1B: 4C E4 CC
|
|
00CB1E 1
|
|
00CB1E 1 ; ----------------------------------------------------------------------------
|
|
00CB1E 1 ; Update state variables and select one of two inline command records based on
|
|
00CB1E 1 ; the sign of $050A.
|
|
00CB1E 1 ; ----------------------------------------------------------------------------
|
|
00CB1E 1
|
|
00CB1E 1 ApplyNegativeTrajectoryResult: ; $CB1E
|
|
00CB1E 1 E6 60 inc PendingStateTransition ; $CB1E: E6 60
|
|
00CB20 1 C6 46 dec StateSequenceActive ; $CB20: C6 46
|
|
00CB22 1
|
|
00CB22 1 AD 0A 05 lda $050A ; $CB22: AD 0A 05
|
|
00CB25 1 30 07 bmi QueueNegativeResultCommand ; $CB25: 30 07
|
|
00CB27 1
|
|
00CB27 1 20 0A EB jsr QueueInlineObjectEvent ; $CB27: 20 0A EB
|
|
00CB2A 1
|
|
00CB2A 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CB2A 1 18 4C CC .byte $18,$4C,$CC ; $CB2A-$CB2C
|
|
00CB2D 1
|
|
00CB2D 1 60 rts ; $CB2D: 60
|
|
00CB2E 1
|
|
00CB2E 1 QueueNegativeResultCommand: ; $CB2E
|
|
00CB2E 1 20 0A EB jsr QueueInlineObjectEvent ; $CB2E: 20 0A EB
|
|
00CB31 1
|
|
00CB31 1 ; Alternate inline command record consumed by QueueInlineObjectEvent.
|
|
00CB31 1 1C 4C CC .byte $1C,$4C,$CC ; $CB31-$CB33
|
|
00CB34 1
|
|
00CB34 1 TrajectoryResultReturn: ; $CB34
|
|
00CB34 1 60 rts ; $CB34: 60
|
|
00CB35 1
|
|
00CB35 1 ; ============================================================================
|
|
00CB35 1 ; $CB35-$CB38
|
|
00CB35 1 ; Signed state-result lookup table.
|
|
00CB35 1 ;
|
|
00CB35 1 ; Indexed by the two-bit value calculated at $CAFC-$CAFF.
|
|
00CB35 1 ; ============================================================================
|
|
00CB35 1
|
|
00CB35 1 TrajectoryResultTable: ; $CB35
|
|
00CB35 1 FF FF 01 00 .byte $FF,$FF,$01,$00
|
|
00CB39 1
|
|
00CB39 1 ; ============================================================================
|
|
00CB39 1 ; $CB39-$CB7C
|
|
00CB39 1 ; Save base coordinates, prepare three object records, and repeatedly update
|
|
00CB39 1 ; them until the first updated record produces a negative high byte.
|
|
00CB39 1 ; ============================================================================
|
|
00CB39 1
|
|
00CB39 1 SimulateObjectTrajectories: ; $CB39
|
|
00CB39 1 AD 02 05 lda $0502 ; $CB39: AD 02 05
|
|
00CB3C 1 85 53 sta SavedBaseXLo ; $CB3C: 85 53
|
|
00CB3E 1
|
|
00CB3E 1 AD 03 05 lda $0503 ; $CB3E: AD 03 05
|
|
00CB41 1 85 54 sta SavedBaseXHi ; $CB41: 85 54
|
|
00CB43 1
|
|
00CB43 1 AD 33 05 lda $0533 ; $CB43: AD 33 05
|
|
00CB46 1 85 55 sta SavedBaseYLo ; $CB46: 85 55
|
|
00CB48 1
|
|
00CB48 1 AD 34 05 lda $0534 ; $CB48: AD 34 05
|
|
00CB4B 1 85 56 sta SavedBaseYHi ; $CB4B: 85 56
|
|
00CB4D 1
|
|
00CB4D 1 20 4C EB jsr SelectObjectEventBank0 ; $CB4D: 20 4C EB
|
|
00CB50 1
|
|
00CB50 1 ; ----------------------------------------------------------------------------
|
|
00CB50 1 ; Prepare three object records.
|
|
00CB50 1 ;
|
|
00CB50 1 ; The records begin at offsets:
|
|
00CB50 1 ;
|
|
00CB50 1 ; X = $00
|
|
00CB50 1 ; X = $31
|
|
00CB50 1 ; X = $62
|
|
00CB50 1 ; ----------------------------------------------------------------------------
|
|
00CB50 1
|
|
00CB50 1 A2 00 ldx #$00 ; $CB50: A2 00
|
|
00CB52 1 20 7D CB jsr PrepareFixedPointObject
|
|
00CB55 1 ; $CB52: 20 7D CB
|
|
00CB55 1
|
|
00CB55 1 A2 31 ldx #$31 ; $CB55: A2 31
|
|
00CB57 1 20 7D CB jsr PrepareFixedPointObject
|
|
00CB5A 1 ; $CB57: 20 7D CB
|
|
00CB5A 1
|
|
00CB5A 1 A2 62 ldx #$62 ; $CB5A: A2 62
|
|
00CB5C 1 20 7D CB jsr PrepareFixedPointObject
|
|
00CB5F 1 ; $CB5C: 20 7D CB
|
|
00CB5F 1
|
|
00CB5F 1 ; ----------------------------------------------------------------------------
|
|
00CB5F 1 ; Initialize an update counter and enter the frame/update loop.
|
|
00CB5F 1 ; ----------------------------------------------------------------------------
|
|
00CB5F 1
|
|
00CB5F 1 A2 20 ldx #$20 ; $CB5F: A2 20
|
|
00CB61 1 86 61 stx UpdateCounter ; $CB61: 86 61
|
|
00CB63 1
|
|
00CB63 1 Routine_CB63_UpdateLoop: ; $CB63
|
|
00CB63 1 20 4C EB jsr SelectObjectEventBank0 ; $CB63: 20 4C EB
|
|
00CB66 1
|
|
00CB66 1 ; ----------------------------------------------------------------------------
|
|
00CB66 1 ; Update the third record first.
|
|
00CB66 1 ;
|
|
00CB66 1 ; If its resulting high byte is negative, restart the entire routine.
|
|
00CB66 1 ; ----------------------------------------------------------------------------
|
|
00CB66 1
|
|
00CB66 1 A2 62 ldx #$62 ; $CB66: A2 62
|
|
00CB68 1 20 C4 CB jsr IntegrateFixedPointObject
|
|
00CB6B 1 ; $CB68: 20 C4 CB
|
|
00CB6B 1
|
|
00CB6B 1 30 CC bmi SimulateObjectTrajectories ; $CB6B: 30 CC
|
|
00CB6D 1
|
|
00CB6D 1 ; ----------------------------------------------------------------------------
|
|
00CB6D 1 ; Update the remaining two records.
|
|
00CB6D 1 ; ----------------------------------------------------------------------------
|
|
00CB6D 1
|
|
00CB6D 1 A2 31 ldx #$31 ; $CB6D: A2 31
|
|
00CB6F 1 20 C4 CB jsr IntegrateFixedPointObject
|
|
00CB72 1 ; $CB6F: 20 C4 CB
|
|
00CB72 1
|
|
00CB72 1 A2 00 ldx #$00 ; $CB72: A2 00
|
|
00CB74 1 20 C4 CB jsr IntegrateFixedPointObject
|
|
00CB77 1 ; $CB74: 20 C4 CB
|
|
00CB77 1
|
|
00CB77 1 ; ----------------------------------------------------------------------------
|
|
00CB77 1 ; Continue for $20 update cycles, then restart the routine.
|
|
00CB77 1 ; ----------------------------------------------------------------------------
|
|
00CB77 1
|
|
00CB77 1 C6 61 dec UpdateCounter ; $CB77: C6 61
|
|
00CB79 1 D0 E8 bne Routine_CB63_UpdateLoop ; $CB79: D0 E8
|
|
00CB7B 1
|
|
00CB7B 1 F0 BC beq SimulateObjectTrajectories ; $CB7B: F0 BC
|
|
00CB7D 1 ; Always taken because $61 is zero.
|
|
00CB7D 1
|
|
00CB7D 1 ; ============================================================================
|
|
00CB7D 1 ; $CB7D-$CBC3
|
|
00CB7D 1 ; Prepare one fixed-point object record.
|
|
00CB7D 1 ;
|
|
00CB7D 1 ; Entry:
|
|
00CB7D 1 ; X = object-record offset
|
|
00CB7D 1 ;
|
|
00CB7D 1 ; Input fields:
|
|
00CB7D 1 ; $0506,X
|
|
00CB7D 1 ; $0507,X/$0508,X
|
|
00CB7D 1 ; $0509,X/$050A,X
|
|
00CB7D 1 ;
|
|
00CB7D 1 ; Output fields:
|
|
00CB7D 1 ; $0500,X/$0501,X
|
|
00CB7D 1 ; $0502,X/$0503,X
|
|
00CB7D 1 ; $0504,X/$0505,X
|
|
00CB7D 1 ; ============================================================================
|
|
00CB7D 1
|
|
00CB7D 1 PrepareFixedPointObject: ; $CB7D
|
|
00CB7D 1 A0 00 ldy #$00 ; $CB7D: A0 00
|
|
00CB7F 1
|
|
00CB7F 1 ; ----------------------------------------------------------------------------
|
|
00CB7F 1 ; Sign-extend $0506,X, multiply it by four, and store the result in
|
|
00CB7F 1 ; $0500,X/$0501,X.
|
|
00CB7F 1 ; ----------------------------------------------------------------------------
|
|
00CB7F 1
|
|
00CB7F 1 BD 06 05 lda $0506,x ; $CB7F: BD 06 05
|
|
00CB82 1 48 pha ; $CB82: 48
|
|
00CB83 1
|
|
00CB83 1 10 01 bpl Routine_CB86_FirstPositive
|
|
00CB85 1 ; $CB83: 10 01
|
|
00CB85 1
|
|
00CB85 1 88 dey ; $CB85: 88
|
|
00CB86 1 ; Y = $FF for a negative input.
|
|
00CB86 1
|
|
00CB86 1 Routine_CB86_FirstPositive: ; $CB86
|
|
00CB86 1 98 tya ; $CB86: 98
|
|
00CB87 1 9D 01 05 sta $0501,x ; $CB87: 9D 01 05
|
|
00CB8A 1
|
|
00CB8A 1 68 pla ; $CB8A: 68
|
|
00CB8B 1
|
|
00CB8B 1 0A asl ; $CB8B: 0A
|
|
00CB8C 1 3E 01 05 rol $0501,x ; $CB8C: 3E 01 05
|
|
00CB8F 1
|
|
00CB8F 1 0A asl ; $CB8F: 0A
|
|
00CB90 1 3E 01 05 rol $0501,x ; $CB90: 3E 01 05
|
|
00CB93 1
|
|
00CB93 1 9D 00 05 sta $0500,x ; $CB93: 9D 00 05
|
|
00CB96 1
|
|
00CB96 1 ; ----------------------------------------------------------------------------
|
|
00CB96 1 ; Sign-extend and scale $0507,X/$0508,X.
|
|
00CB96 1 ;
|
|
00CB96 1 ; The low byte is initially shifted into $05. The high byte and temporary
|
|
00CB96 1 ; value are then rotated to form the output at $0504,X/$0505,X.
|
|
00CB96 1 ; ----------------------------------------------------------------------------
|
|
00CB96 1
|
|
00CB96 1 A0 00 ldy #$00 ; $CB96: A0 00
|
|
00CB98 1
|
|
00CB98 1 BD 07 05 lda $0507,x ; $CB98: BD 07 05
|
|
00CB9B 1 0A asl ; $CB9B: 0A
|
|
00CB9C 1 85 05 sta MathTemp05 ; $CB9C: 85 05
|
|
00CB9E 1
|
|
00CB9E 1 BD 08 05 lda $0508,x ; $CB9E: BD 08 05
|
|
00CBA1 1 48 pha ; $CBA1: 48
|
|
00CBA2 1
|
|
00CBA2 1 10 01 bpl Routine_CBA5_SecondPositive
|
|
00CBA4 1 ; $CBA2: 10 01
|
|
00CBA4 1
|
|
00CBA4 1 88 dey ; $CBA4: 88
|
|
00CBA5 1 ; Y = $FF for a negative input.
|
|
00CBA5 1
|
|
00CBA5 1 Routine_CBA5_SecondPositive: ; $CBA5
|
|
00CBA5 1 98 tya ; $CBA5: 98
|
|
00CBA6 1 9D 05 05 sta $0505,x ; $CBA6: 9D 05 05
|
|
00CBA9 1
|
|
00CBA9 1 68 pla ; $CBA9: 68
|
|
00CBAA 1
|
|
00CBAA 1 2A rol ; $CBAA: 2A
|
|
00CBAB 1 3E 05 05 rol $0505,x ; $CBAB: 3E 05 05
|
|
00CBAE 1
|
|
00CBAE 1 06 05 asl MathTemp05 ; $CBAE: 06 05
|
|
00CBB0 1
|
|
00CBB0 1 2A rol ; $CBB0: 2A
|
|
00CBB1 1 3E 05 05 rol $0505,x ; $CBB1: 3E 05 05
|
|
00CBB4 1
|
|
00CBB4 1 9D 04 05 sta $0504,x ; $CBB4: 9D 04 05
|
|
00CBB7 1
|
|
00CBB7 1 ; ----------------------------------------------------------------------------
|
|
00CBB7 1 ; Copy the source position into the working position.
|
|
00CBB7 1 ; ----------------------------------------------------------------------------
|
|
00CBB7 1
|
|
00CBB7 1 BD 09 05 lda $0509,x ; $CBB7: BD 09 05
|
|
00CBBA 1 9D 02 05 sta $0502,x ; $CBBA: 9D 02 05
|
|
00CBBD 1
|
|
00CBBD 1 BD 0A 05 lda $050A,x ; $CBBD: BD 0A 05
|
|
00CBC0 1 9D 03 05 sta $0503,x ; $CBC0: 9D 03 05
|
|
00CBC3 1
|
|
00CBC3 1 60 rts ; $CBC3: 60
|
|
00CBC4 1
|
|
00CBC4 1 ; ============================================================================
|
|
00CBC4 1 ; $CBC4-$CBE9
|
|
00CBC4 1 ; Update one fixed-point object record.
|
|
00CBC4 1 ;
|
|
00CBC4 1 ; Entry:
|
|
00CBC4 1 ; X = object-record offset
|
|
00CBC4 1 ;
|
|
00CBC4 1 ; Operation:
|
|
00CBC4 1 ; velocity += acceleration
|
|
00CBC4 1 ; position += velocity
|
|
00CBC4 1 ;
|
|
00CBC4 1 ; The final A value is the updated position high byte, so callers can test its
|
|
00CBC4 1 ; sign immediately after return.
|
|
00CBC4 1 ; ============================================================================
|
|
00CBC4 1
|
|
00CBC4 1 IntegrateFixedPointObject: ; $CBC4
|
|
00CBC4 1 18 clc ; $CBC4: 18
|
|
00CBC5 1
|
|
00CBC5 1 ; ----------------------------------------------------------------------------
|
|
00CBC5 1 ; Add acceleration $0500/$0501 to velocity $0504/$0505.
|
|
00CBC5 1 ; ----------------------------------------------------------------------------
|
|
00CBC5 1
|
|
00CBC5 1 BD 00 05 lda $0500,x ; $CBC5: BD 00 05
|
|
00CBC8 1 7D 04 05 adc $0504,x ; $CBC8: 7D 04 05
|
|
00CBCB 1 9D 04 05 sta $0504,x ; $CBCB: 9D 04 05
|
|
00CBCE 1
|
|
00CBCE 1 BD 01 05 lda $0501,x ; $CBCE: BD 01 05
|
|
00CBD1 1 7D 05 05 adc $0505,x ; $CBD1: 7D 05 05
|
|
00CBD4 1 9D 05 05 sta $0505,x ; $CBD4: 9D 05 05
|
|
00CBD7 1
|
|
00CBD7 1 A8 tay ; $CBD7: A8
|
|
00CBD8 1 ; Preserve the updated velocity high byte.
|
|
00CBD8 1
|
|
00CBD8 1 ; ----------------------------------------------------------------------------
|
|
00CBD8 1 ; Add velocity $0504/$0505 to position $0502/$0503.
|
|
00CBD8 1 ; ----------------------------------------------------------------------------
|
|
00CBD8 1
|
|
00CBD8 1 18 clc ; $CBD8: 18
|
|
00CBD9 1
|
|
00CBD9 1 BD 04 05 lda $0504,x ; $CBD9: BD 04 05
|
|
00CBDC 1 7D 02 05 adc $0502,x ; $CBDC: 7D 02 05
|
|
00CBDF 1 9D 02 05 sta $0502,x ; $CBDF: 9D 02 05
|
|
00CBE2 1
|
|
00CBE2 1 98 tya ; $CBE2: 98
|
|
00CBE3 1
|
|
00CBE3 1 7D 03 05 adc $0503,x ; $CBE3: 7D 03 05
|
|
00CBE6 1 9D 03 05 sta $0503,x ; $CBE6: 9D 03 05
|
|
00CBE9 1
|
|
00CBE9 1 60 rts ; $CBE9: 60
|
|
00CBEA 1
|
|
00CBEA 1 ; ============================================================================
|
|
00CBEA 1 ; $CBEA-$CC00
|
|
00CBEA 1 ; Geometry/collision test helper
|
|
00CBEA 1 ;
|
|
00CBEA 1 ; Entry points:
|
|
00CBEA 1 ; $CBEA loads X from $E1.
|
|
00CBEA 1 ; $CBEC uses the X value supplied by the caller.
|
|
00CBEA 1 ; ============================================================================
|
|
00CBEA 1
|
|
00CBEA 1 ; ----------------------------------------------------------------------------
|
|
00CBEA 1 ; Contract:
|
|
00CBEA 1 ; Description: Implements Test Current Object Collision.
|
|
00CBEA 1 ; Entry: Registers: A; Memory: $e1
|
|
00CBEA 1 ; Returns/products: Registers/clobbers: A, X
|
|
00CBEA 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CBEA 1 ; Memory effects: $b2, $b3, $b4, $b5
|
|
00CBEA 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CBEA 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CBEA 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00CBEA 1 ; ----------------------------------------------------------------------------
|
|
00CBEA 1 TestCurrentObjectCollision: ; $CBEA
|
|
00CBEA 1 A6 E1 ldx CurrentObjectIndex ; $CBEA: A6 E1
|
|
00CBEC 1
|
|
00CBEC 1 ; ----------------------------------------------------------------------------
|
|
00CBEC 1 ; Contract:
|
|
00CBEC 1 ; Description: Implements Test Object Collision.
|
|
00CBEC 1 ; Entry: Registers: A
|
|
00CBEC 1 ; Returns/products: Registers/clobbers: A
|
|
00CBEC 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CBEC 1 ; Memory effects: $b2, $b3, $b4, $b5
|
|
00CBEC 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CBEC 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CBEC 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00CBEC 1 ; ----------------------------------------------------------------------------
|
|
00CBEC 1 TestObjectCollision: ; $CBEC
|
|
00CBEC 1 A9 00 lda #$00 ; $CBEC: A9 00
|
|
00CBEE 1
|
|
00CBEE 1 85 B2 sta $B2 ; $CBEE: 85 B2
|
|
00CBF0 1 85 B3 sta $B3 ; $CBF0: 85 B3
|
|
00CBF2 1 85 B4 sta $B4 ; $CBF2: 85 B4
|
|
00CBF4 1
|
|
00CBF4 1 A9 07 lda #$07 ; $CBF4: A9 07
|
|
00CBF6 1 85 B5 sta $B5 ; $CBF6: 85 B5
|
|
00CBF8 1
|
|
00CBF8 1 20 DD E4 jsr CalculateGeometryDifference ; $CBF8: 20 DD E4
|
|
00CBFB 1 20 02 E5 jsr EvaluateGeometryDifference ; $CBFB: 20 02 E5
|
|
00CBFE 1
|
|
00CBFE 1 C9 42 cmp #$42 ; $CBFE: C9 42
|
|
00CC00 1 60 rts ; $CC00: 60
|
|
00CC01 1
|
|
00CC01 1 ; ============================================================================
|
|
00CC01 1 ; $CC01-$CC3B
|
|
00CC01 1 ; Advance state $63, update display/event slots, and initialize the next
|
|
00CC01 1 ; state-dependent object or animation.
|
|
00CC01 1 ; ============================================================================
|
|
00CC01 1
|
|
00CC01 1 ; ----------------------------------------------------------------------------
|
|
00CC01 1 ; Contract:
|
|
00CC01 1 ; Description: Implements Advance Primary State Sequence.
|
|
00CC01 1 ; Entry: Registers: A; Memory: transitionsequencestate, $0596
|
|
00CC01 1 ; Returns/products: Registers/clobbers: A, Y; Flags: condition flags may carry result state
|
|
00CC01 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CC01 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00CC01 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CC01 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CC01 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CC01 1 ; ----------------------------------------------------------------------------
|
|
00CC01 1 AdvancePrimaryStateSequence: ; $CC01
|
|
00CC01 1 E6 63 inc TransitionSequenceState ; $CC01: E6 63
|
|
00CC03 1
|
|
00CC03 1 A5 63 lda TransitionSequenceState ; $CC03: A5 63
|
|
00CC05 1 C9 04 cmp #$04 ; $CC05: C9 04
|
|
00CC07 1 90 17 bcc HandleEarlyPrimaryState
|
|
00CC09 1 ; $CC07: 90 17
|
|
00CC09 1
|
|
00CC09 1 ; ----------------------------------------------------------------------------
|
|
00CC09 1 ; State $63 is four or greater.
|
|
00CC09 1 ;
|
|
00CC09 1 ; Process event slots $0F and $0D, execute an inline command, then call the
|
|
00CC09 1 ; helper at $CF4A. A delay/count value of $1E is selected.
|
|
00CC09 1 ; ----------------------------------------------------------------------------
|
|
00CC09 1
|
|
00CC09 1 A0 0F ldy #$0F ; $CC09: A0 0F
|
|
00CC0B 1 20 66 EB jsr DispatchNextQueuedEvent ; $CC0B: 20 66 EB
|
|
00CC0E 1
|
|
00CC0E 1 A0 0D ldy #$0D ; $CC0E: A0 0D
|
|
00CC10 1 20 66 EB jsr DispatchNextQueuedEvent ; $CC10: 20 66 EB
|
|
00CC13 1
|
|
00CC13 1 20 0A EB jsr QueueInlineObjectEvent ; $CC13: 20 0A EB
|
|
00CC16 1
|
|
00CC16 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CC16 1 06 ED D9 .byte $06,$ED,$D9 ; $CC16-$CC18
|
|
00CC19 1
|
|
00CC19 1 20 4A CF jsr ClearPrimaryStateField ; $CC19: 20 4A CF
|
|
00CC1C 1
|
|
00CC1C 1 A9 1E lda #$1E ; $CC1C: A9 1E
|
|
00CC1E 1 D0 0A bne QueuePrimaryStateEvent ; $CC1E: D0 0A
|
|
00CC20 1 ; Always taken because A is nonzero.
|
|
00CC20 1
|
|
00CC20 1 ; ----------------------------------------------------------------------------
|
|
00CC20 1 ; State $63 is below four.
|
|
00CC20 1 ;
|
|
00CC20 1 ; Pass A = $63 + 2 to $CF2F, then select a value of $18.
|
|
00CC20 1 ; ----------------------------------------------------------------------------
|
|
00CC20 1
|
|
00CC20 1 HandleEarlyPrimaryState: ; $CC20
|
|
00CC20 1 18 clc ; $CC20: 18
|
|
00CC21 1
|
|
00CC21 1 A5 63 lda TransitionSequenceState ; $CC21: A5 63
|
|
00CC23 1 69 02 adc #$02 ; $CC23: 69 02
|
|
00CC25 1
|
|
00CC25 1 20 2F CF jsr BuildStateMarkerEntries ; $CC25: 20 2F CF
|
|
00CC28 1
|
|
00CC28 1 A9 18 lda #$18 ; $CC28: A9 18
|
|
00CC2A 1
|
|
00CC2A 1 ; ----------------------------------------------------------------------------
|
|
00CC2A 1 ; Pass the selected value, either $18 or $1E, to $CF11.
|
|
00CC2A 1 ; ----------------------------------------------------------------------------
|
|
00CC2A 1
|
|
00CC2A 1 QueuePrimaryStateEvent: ; $CC2A
|
|
00CC2A 1 20 11 CF jsr AddTimedStateEvent ; $CC2A: 20 11 CF
|
|
00CC2D 1
|
|
00CC2D 1 ; ----------------------------------------------------------------------------
|
|
00CC2D 1 ; Perform a one-time inline command when $0596 is zero.
|
|
00CC2D 1 ; ----------------------------------------------------------------------------
|
|
00CC2D 1
|
|
00CC2D 1 AD 96 05 lda $0596 ; $CC2D: AD 96 05
|
|
00CC30 1 D0 09 bne Routine_CC3B_Return ; $CC30: D0 09
|
|
00CC32 1
|
|
00CC32 1 EE 96 05 inc $0596 ; $CC32: EE 96 05
|
|
00CC35 1
|
|
00CC35 1 20 0A EB jsr QueueInlineObjectEvent ; $CC35: 20 0A EB
|
|
00CC38 1
|
|
00CC38 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CC38 1 28 3B CC .byte $28,$3B,$CC ; $CC38-$CC3A
|
|
00CC3B 1
|
|
00CC3B 1 Routine_CC3B_Return: ; $CC3B
|
|
00CC3B 1 60 rts ; $CC3B: 60
|
|
00CC3C 1
|
|
00CC3C 1 ; ============================================================================
|
|
00CC3C 1 ; $CC3C-$CC4C
|
|
00CC3C 1 ; Timed state transition.
|
|
00CC3C 1 ;
|
|
00CC3C 1 ; Increment $03B1, wait for $3C ticks, restore $03B1, clear the one-time flag,
|
|
00CC3C 1 ; and leave through the common engine exit.
|
|
00CC3C 1 ; ============================================================================
|
|
00CC3C 1
|
|
00CC3C 1 RunPrimaryStateDelay: ; $CC3C
|
|
00CC3C 1 EE B1 03 inc $03B1 ; $CC3C: EE B1 03
|
|
00CC3F 1
|
|
00CC3F 1 A9 3C lda #$3C ; $CC3F: A9 3C
|
|
00CC41 1 20 41 EB jsr StoreObjectEventBankValue ; $CC41: 20 41 EB
|
|
00CC44 1
|
|
00CC44 1 CE B1 03 dec $03B1 ; $CC44: CE B1 03
|
|
00CC47 1 CE 96 05 dec $0596 ; $CC47: CE 96 05
|
|
00CC4A 1
|
|
00CC4A 1 4C 6A EB jmp CommonEngineExit ; $CC4A: 4C 6A EB
|
|
00CC4D 1
|
|
00CC4D 1 ; ============================================================================
|
|
00CC4D 1 ; $CC4D-$CC79
|
|
00CC4D 1 ; Advance state $62, update an indexed animation value, wait, restore it,
|
|
00CC4D 1 ; and leave through the common engine exit.
|
|
00CC4D 1 ; ============================================================================
|
|
00CC4D 1
|
|
00CC4D 1 AdvanceSecondaryStateSequence: ; $CC4D
|
|
00CC4D 1 A5 62 lda PrimarySequenceState ; $CC4D: A5 62
|
|
00CC4F 1 C9 02 cmp #$02 ; $CC4F: C9 02
|
|
00CC51 1 B0 05 bcs QueueSecondaryStateEvent ; $CC51: B0 05
|
|
00CC53 1
|
|
00CC53 1 ; ----------------------------------------------------------------------------
|
|
00CC53 1 ; Advance $62 while it is below two and run the associated setup helper.
|
|
00CC53 1 ; ----------------------------------------------------------------------------
|
|
00CC53 1
|
|
00CC53 1 E6 62 inc PrimarySequenceState ; $CC53: E6 62
|
|
00CC55 1 20 23 CF jsr QueuePrimaryStateMarker ; $CC55: 20 23 CF
|
|
00CC58 1
|
|
00CC58 1 ; ----------------------------------------------------------------------------
|
|
00CC58 1 ; Pass state value $06 to the helper at $CF11.
|
|
00CC58 1 ; ----------------------------------------------------------------------------
|
|
00CC58 1
|
|
00CC58 1 QueueSecondaryStateEvent: ; $CC58
|
|
00CC58 1 A9 06 lda #$06 ; $CC58: A9 06
|
|
00CC5A 1 20 11 CF jsr AddTimedStateEvent ; $CC5A: 20 11 CF
|
|
00CC5D 1
|
|
00CC5D 1 ; ----------------------------------------------------------------------------
|
|
00CC5D 1 ; Convert the current object index in $E1 to the corresponding animation-table
|
|
00CC5D 1 ; index, then increment $039A,X.
|
|
00CC5D 1 ; ----------------------------------------------------------------------------
|
|
00CC5D 1
|
|
00CC5D 1 A6 E1 ldx CurrentObjectIndex ; $CC5D: A6 E1
|
|
00CC5F 1 20 38 E7 jsr ConvertObjectOffsetToDisplayIndex ; $CC5F: 20 38 E7
|
|
00CC62 1
|
|
00CC62 1 FE 9A 03 inc $039A,x ; $CC62: FE 9A 03
|
|
00CC65 1
|
|
00CC65 1 ; ----------------------------------------------------------------------------
|
|
00CC65 1 ; Wait for $5A ticks.
|
|
00CC65 1 ; ----------------------------------------------------------------------------
|
|
00CC65 1
|
|
00CC65 1 A9 5A lda #$5A ; $CC65: A9 5A
|
|
00CC67 1 20 41 EB jsr StoreObjectEventBankValue ; $CC67: 20 41 EB
|
|
00CC6A 1
|
|
00CC6A 1 ; ----------------------------------------------------------------------------
|
|
00CC6A 1 ; Recalculate the animation-table index and restore $039A,X.
|
|
00CC6A 1 ; ----------------------------------------------------------------------------
|
|
00CC6A 1
|
|
00CC6A 1 A6 E1 ldx CurrentObjectIndex ; $CC6A: A6 E1
|
|
00CC6C 1 20 38 E7 jsr ConvertObjectOffsetToDisplayIndex ; $CC6C: 20 38 E7
|
|
00CC6F 1
|
|
00CC6F 1 DE 9A 03 dec $039A,x ; $CC6F: DE 9A 03
|
|
00CC72 1
|
|
00CC72 1 ; ----------------------------------------------------------------------------
|
|
00CC72 1 ; Process command $08 and leave through the common engine exit.
|
|
00CC72 1 ; ----------------------------------------------------------------------------
|
|
00CC72 1
|
|
00CC72 1 A2 08 ldx #$08 ; $CC72: A2 08
|
|
00CC74 1 20 2A EB jsr ProcessQueuedObjectEvent ; $CC74: 20 2A EB
|
|
00CC77 1
|
|
00CC77 1 4C 6A EB jmp CommonEngineExit ; $CC77: 4C 6A EB
|
|
00CC7A 1
|
|
00CC7A 1 ; ============================================================================
|
|
00CC7A 1 ; $CC7A-$CCB8
|
|
00CC7A 1 ; Advance states PrimarySequenceState and $64, run state-specific setup, and dispatch a
|
|
00CC7A 1 ; one-time inline command.
|
|
00CC7A 1 ; ============================================================================
|
|
00CC7A 1
|
|
00CC7A 1 AdvanceDualStateSequence: ; $CC7A
|
|
00CC7A 1 A9 0C lda #$0C ; $CC7A: A9 0C
|
|
00CC7C 1 20 11 CF jsr AddTimedStateEvent ; $CC7C: 20 11 CF
|
|
00CC7F 1
|
|
00CC7F 1 E6 62 inc PrimarySequenceState ; $CC7F: E6 62
|
|
00CC81 1 20 23 CF jsr QueuePrimaryStateMarker ; $CC81: 20 23 CF
|
|
00CC84 1
|
|
00CC84 1 A5 62 lda PrimarySequenceState ; $CC84: A5 62
|
|
00CC86 1 C9 03 cmp #$03 ; $CC86: C9 03
|
|
00CC88 1 90 20 bcc Routine_CCAA_OneTimeCommand
|
|
00CC8A 1 ; $CC88: 90 20
|
|
00CC8A 1 ; ----------------------------------------------------------------------------
|
|
00CC8A 1 ; PrimarySequenceState has reached three.
|
|
00CC8A 1 ; ----------------------------------------------------------------------------
|
|
00CC8A 1
|
|
00CC8A 1 A9 12 lda #$12 ; $CC8A: A9 12
|
|
00CC8C 1 20 11 CF jsr AddTimedStateEvent ; $CC8C: 20 11 CF
|
|
00CC8F 1
|
|
00CC8F 1 20 4A CF jsr ClearPrimaryStateField ; $CC8F: 20 4A CF
|
|
00CC92 1
|
|
00CC92 1 E6 64 inc SecondarySequenceState ; $CC92: E6 64
|
|
00CC94 1 20 2A CF jsr QueueSecondaryStateMarker ; $CC94: 20 2A CF
|
|
00CC97 1
|
|
00CC97 1 A5 64 lda SecondarySequenceState ; $CC97: A5 64
|
|
00CC99 1 C9 03 cmp #$03 ; $CC99: C9 03
|
|
00CC9B 1 90 0D bcc Routine_CCAA_OneTimeCommand
|
|
00CC9D 1 ; $CC9B: 90 0D
|
|
00CC9D 1
|
|
00CC9D 1 ; ----------------------------------------------------------------------------
|
|
00CC9D 1 ; Both state counters have reached their thresholds.
|
|
00CC9D 1 ; ----------------------------------------------------------------------------
|
|
00CC9D 1
|
|
00CC9D 1 A9 43 lda #$43 ; $CC9D: A9 43
|
|
00CC9F 1 20 51 CF jsr ClearStateFieldPair ; $CC9F: 20 51 CF
|
|
00CCA2 1
|
|
00CCA2 1 A9 3C lda #$3C ; $CCA2: A9 3C
|
|
00CCA4 1 20 11 CF jsr AddTimedStateEvent ; $CCA4: 20 11 CF
|
|
00CCA7 1
|
|
00CCA7 1 20 22 CE jsr FinishStateProgression ; $CCA7: 20 22 CE
|
|
00CCAA 1
|
|
00CCAA 1 ; ----------------------------------------------------------------------------
|
|
00CCAA 1 ; Execute this inline command once while $0596 is zero.
|
|
00CCAA 1 ; ----------------------------------------------------------------------------
|
|
00CCAA 1
|
|
00CCAA 1 Routine_CCAA_OneTimeCommand: ; $CCAA
|
|
00CCAA 1 AD 96 05 lda $0596 ; $CCAA: AD 96 05
|
|
00CCAD 1 D0 09 bne Routine_CCB8_Return ; $CCAD: D0 09
|
|
00CCAF 1
|
|
00CCAF 1 EE 96 05 inc $0596 ; $CCAF: EE 96 05
|
|
00CCB2 1
|
|
00CCB2 1 20 0A EB jsr QueueInlineObjectEvent ; $CCB2: 20 0A EB
|
|
00CCB5 1
|
|
00CCB5 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CCB5 1 28 B8 CC .byte $28,$B8,$CC ; $CCB5-$CCB7
|
|
00CCB8 1
|
|
00CCB8 1 Routine_CCB8_Return: ; $CCB8
|
|
00CCB8 1 60 rts ; $CCB8: 60
|
|
00CCB9 1
|
|
00CCB9 1 ; ============================================================================
|
|
00CCB9 1 ; $CCB9-$CCE3
|
|
00CCB9 1 ; Timed animation/state sequence.
|
|
00CCB9 1 ;
|
|
00CCB9 1 ; $03B1 is decremented twice, incremented once, then decremented again with
|
|
00CCB9 1 ; delays between each change. It is finally set to $47.
|
|
00CCB9 1 ; ============================================================================
|
|
00CCB9 1
|
|
00CCB9 1 RunDualStateAnimation: ; $CCB9
|
|
00CCB9 1 CE B1 03 dec $03B1 ; $CCB9: CE B1 03
|
|
00CCBC 1
|
|
00CCBC 1 A9 14 lda #$14 ; $CCBC: A9 14
|
|
00CCBE 1 20 41 EB jsr StoreObjectEventBankValue ; $CCBE: 20 41 EB
|
|
00CCC1 1
|
|
00CCC1 1 CE B1 03 dec $03B1 ; $CCC1: CE B1 03
|
|
00CCC4 1
|
|
00CCC4 1 A9 14 lda #$14 ; $CCC4: A9 14
|
|
00CCC6 1 20 41 EB jsr StoreObjectEventBankValue ; $CCC6: 20 41 EB
|
|
00CCC9 1
|
|
00CCC9 1 ; ----------------------------------------------------------------------------
|
|
00CCC9 1 ; Secondary entry point referenced by the inline command at $CCB5.
|
|
00CCC9 1 ; ----------------------------------------------------------------------------
|
|
00CCC9 1
|
|
00CCC9 1 RunDualStateAnimationTail: ; $CCC9
|
|
00CCC9 1 EE B1 03 inc $03B1 ; $CCC9: EE B1 03
|
|
00CCCC 1
|
|
00CCCC 1 A9 14 lda #$14 ; $CCCC: A9 14
|
|
00CCCE 1 20 41 EB jsr StoreObjectEventBankValue ; $CCCE: 20 41 EB
|
|
00CCD1 1
|
|
00CCD1 1 CE B1 03 dec $03B1 ; $CCD1: CE B1 03
|
|
00CCD4 1
|
|
00CCD4 1 A9 3C lda #$3C ; $CCD4: A9 3C
|
|
00CCD6 1 20 41 EB jsr StoreObjectEventBankValue ; $CCD6: 20 41 EB
|
|
00CCD9 1
|
|
00CCD9 1 A9 47 lda #$47 ; $CCD9: A9 47
|
|
00CCDB 1 8D B1 03 sta $03B1 ; $CCDB: 8D B1 03
|
|
00CCDE 1
|
|
00CCDE 1 CE 96 05 dec $0596 ; $CCDE: CE 96 05
|
|
00CCE1 1
|
|
00CCE1 1 4C 6A EB jmp CommonEngineExit ; $CCE1: 4C 6A EB
|
|
00CCE4 1
|
|
00CCE4 1 ; ============================================================================
|
|
00CCE4 1 ; $CCE4-$CD17
|
|
00CCE4 1 ; Alternate state transition entered from $CB1B.
|
|
00CCE4 1 ; ============================================================================
|
|
00CCE4 1
|
|
00CCE4 1 AdvanceAlternateStateSequence: ; $CCE4
|
|
00CCE4 1 E6 64 inc SecondarySequenceState ; $CCE4: E6 64
|
|
00CCE6 1
|
|
00CCE6 1 20 2A CF jsr QueueSecondaryStateMarker ; $CCE6: 20 2A CF
|
|
00CCE9 1
|
|
00CCE9 1 A9 12 lda #$12 ; $CCE9: A9 12
|
|
00CCEB 1 20 11 CF jsr AddTimedStateEvent ; $CCEB: 20 11 CF
|
|
00CCEE 1
|
|
00CCEE 1 A5 64 lda SecondarySequenceState ; $CCEE: A5 64
|
|
00CCF0 1 C9 03 cmp #$03 ; $CCF0: C9 03
|
|
00CCF2 1 90 0E bcc Routine_CD02_OptionalSetup
|
|
00CCF4 1 ; $CCF2: 90 0E
|
|
00CCF4 1
|
|
00CCF4 1 ; ----------------------------------------------------------------------------
|
|
00CCF4 1 ; State $64 has reached three.
|
|
00CCF4 1 ; ----------------------------------------------------------------------------
|
|
00CCF4 1
|
|
00CCF4 1 A9 3C lda #$3C ; $CCF4: A9 3C
|
|
00CCF6 1 20 11 CF jsr AddTimedStateEvent ; $CCF6: 20 11 CF
|
|
00CCF9 1
|
|
00CCF9 1 20 22 CE jsr FinishStateProgression ; $CCF9: 20 22 CE
|
|
00CCFC 1 20 45 CF jsr ClearBothStateFields ; $CCFC: 20 45 CF
|
|
00CCFF 1
|
|
00CCFF 1 4C 09 CD jmp Routine_CD09_OneTimeCommand
|
|
00CD02 1 ; $CCFF: 4C 09 CD
|
|
00CD02 1
|
|
00CD02 1 ; ----------------------------------------------------------------------------
|
|
00CD02 1 ; Run $CF4A only when $46 is nonzero.
|
|
00CD02 1 ; ----------------------------------------------------------------------------
|
|
00CD02 1
|
|
00CD02 1 Routine_CD02_OptionalSetup: ; $CD02
|
|
00CD02 1 A5 46 lda StateSequenceActive ; $CD02: A5 46
|
|
00CD04 1 F0 03 beq Routine_CD09_OneTimeCommand
|
|
00CD06 1 ; $CD04: F0 03
|
|
00CD06 1
|
|
00CD06 1 20 4A CF jsr ClearPrimaryStateField ; $CD06: 20 4A CF
|
|
00CD09 1
|
|
00CD09 1 ; ----------------------------------------------------------------------------
|
|
00CD09 1 ; Execute a second one-time inline command.
|
|
00CD09 1 ; ----------------------------------------------------------------------------
|
|
00CD09 1
|
|
00CD09 1 Routine_CD09_OneTimeCommand: ; $CD09
|
|
00CD09 1 AD 96 05 lda $0596 ; $CD09: AD 96 05
|
|
00CD0C 1 D0 09 bne Routine_CD17_Return ; $CD0C: D0 09
|
|
00CD0E 1
|
|
00CD0E 1 EE 96 05 inc $0596 ; $CD0E: EE 96 05
|
|
00CD11 1
|
|
00CD11 1 20 0A EB jsr QueueInlineObjectEvent ; $CD11: 20 0A EB
|
|
00CD14 1
|
|
00CD14 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CD14 1 28 17 CD .byte $28,$17,$CD ; $CD14-$CD16
|
|
00CD17 1
|
|
00CD17 1 Routine_CD17_Return: ; $CD17
|
|
00CD17 1 60 rts ; $CD17: 60
|
|
00CD18 1
|
|
00CD18 1 ; ============================================================================
|
|
00CD18 1 ; $CD18-$CD21
|
|
00CD18 1 ; Select a state path using $72.
|
|
00CD18 1 ; ============================================================================
|
|
00CD18 1
|
|
00CD18 1 DispatchStateSelectorAnimation: ; $CD18
|
|
00CD18 1 A6 72 ldx StateSelector ; $CD18: A6 72
|
|
00CD1A 1
|
|
00CD1A 1 E0 04 cpx #$04 ; $CD1A: E0 04
|
|
00CD1C 1 F0 9B beq RunDualStateAnimation ; $CD1C: F0 9B
|
|
00CD1E 1 ; Branches backward to the timed sequence.
|
|
00CD1E 1
|
|
00CD1E 1 A0 4A ldy #$4A ; $CD1E: A0 4A
|
|
00CD20 1 D0 2F bne StoreStateAnimationParameters ; $CD20: D0 2F
|
|
00CD22 1 ; Always taken because Y is nonzero.
|
|
00CD22 1
|
|
00CD22 1 ; ============================================================================
|
|
00CD22 1 ; $CD22-$CD2D
|
|
00CD22 1 ; Four parallel three-entry tables.
|
|
00CD22 1 ;
|
|
00CD22 1 ; X is expected to contain a value from $00-$02 when these tables are used by
|
|
00CD22 1 ; the routine beginning at $CD42.
|
|
00CD22 1 ; ============================================================================
|
|
00CD22 1
|
|
00CD22 1 StateHorizontalLowTable: ; $CD22
|
|
00CD22 1 00 80 00 .byte $00,$80,$00
|
|
00CD25 1
|
|
00CD25 1 StateHorizontalHighTable: ; $CD25
|
|
00CD25 1 09 FF F7 .byte $09,$FF,$F7
|
|
00CD28 1
|
|
00CD28 1 StateVerticalLowTable: ; $CD28
|
|
00CD28 1 00 00 00 .byte $00,$00,$00
|
|
00CD2B 1
|
|
00CD2B 1 StateVerticalHighTable: ; $CD2B
|
|
00CD2B 1 02 0A 02 .byte $02,$0A,$02
|
|
00CD2E 1
|
|
00CD2E 1 ; ============================================================================
|
|
00CD2E 1 ; $CD2E-$CD41
|
|
00CD2E 1 ; Run state $42 and dispatch a one-time inline command.
|
|
00CD2E 1 ; ============================================================================
|
|
00CD2E 1
|
|
00CD2E 1 ; ----------------------------------------------------------------------------
|
|
00CD2E 1 ; Contract:
|
|
00CD2E 1 ; Description: Queues Selected State Marker.
|
|
00CD2E 1 ; Entry: Memory: $0596
|
|
00CD2E 1 ; Returns/products: Registers/clobbers: A
|
|
00CD2E 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CD2E 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00CD2E 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CD2E 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CD2E 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CD2E 1 ; ----------------------------------------------------------------------------
|
|
00CD2E 1 QueueSelectedStateMarker: ; $CD2E
|
|
00CD2E 1 A9 42 lda #$42 ; $CD2E: A9 42
|
|
00CD30 1 20 11 CF jsr AddTimedStateEvent ; $CD30: 20 11 CF
|
|
00CD33 1
|
|
00CD33 1 AD 96 05 lda $0596 ; $CD33: AD 96 05
|
|
00CD36 1 D0 09 bne Routine_CD41_Return ; $CD36: D0 09
|
|
00CD38 1
|
|
00CD38 1 EE 96 05 inc $0596 ; $CD38: EE 96 05
|
|
00CD3B 1
|
|
00CD3B 1 20 0A EB jsr QueueInlineObjectEvent ; $CD3B: 20 0A EB
|
|
00CD3E 1
|
|
00CD3E 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CD3E 1 28 41 CD .byte $28,$41,$CD ; $CD3E-$CD40
|
|
00CD41 1
|
|
00CD41 1 Routine_CD41_Return: ; $CD41
|
|
00CD41 1 60 rts ; $CD41: 60
|
|
00CD42 1
|
|
00CD42 1 ; ============================================================================
|
|
00CD42 1 ; $CD42-$CD97
|
|
00CD42 1 ; Configure fields from the tables above, play a timed animation sequence,
|
|
00CD42 1 ; then restore state and leave through the common engine exit.
|
|
00CD42 1 ; ============================================================================
|
|
00CD42 1
|
|
00CD42 1 RunSelectedStateAnimation: ; $CD42
|
|
00CD42 1 A6 72 ldx StateSelector ; $CD42: A6 72
|
|
00CD44 1
|
|
00CD44 1 E0 04 cpx #$04 ; $CD44: E0 04
|
|
00CD46 1 D0 07 bne LoadStateAnimationParameters ; $CD46: D0 07
|
|
00CD48 1
|
|
00CD48 1 ; ----------------------------------------------------------------------------
|
|
00CD48 1 ; Special path for state four.
|
|
00CD48 1 ; ----------------------------------------------------------------------------
|
|
00CD48 1
|
|
00CD48 1 A9 49 lda #$49 ; $CD48: A9 49
|
|
00CD4A 1 8D B1 03 sta $03B1 ; $CD4A: 8D B1 03
|
|
00CD4D 1
|
|
00CD4D 1 D0 2C bne WaitForStateAnimation ; $CD4D: D0 2C
|
|
00CD4F 1 ; Always taken because A is nonzero.
|
|
00CD4F 1
|
|
00CD4F 1 ; ----------------------------------------------------------------------------
|
|
00CD4F 1 ; Table-driven path for states zero through two.
|
|
00CD4F 1 ;
|
|
00CD4F 1 ; Y begins at $4C and is stored into $03B1.
|
|
00CD4F 1 ; ----------------------------------------------------------------------------
|
|
00CD4F 1
|
|
00CD4F 1 LoadStateAnimationParameters: ; $CD4F
|
|
00CD4F 1 A0 4C ldy #$4C ; $CD4F: A0 4C
|
|
00CD51 1
|
|
00CD51 1
|
|
00CD51 1 StoreStateAnimationParameters: ; $CD51
|
|
00CD51 1 8C B1 03 sty $03B1 ; $CD51: 8C B1 03
|
|
00CD54 1
|
|
00CD54 1 BD 21 CD lda $CD21,x ; $CD54: BD 21 CD
|
|
00CD57 1 8D 0B 05 sta $050B ; $CD57: 8D 0B 05
|
|
00CD5A 1
|
|
00CD5A 1 BD 24 CD lda $CD24,x ; $CD5A: BD 24 CD
|
|
00CD5D 1 8D 0C 05 sta $050C ; $CD5D: 8D 0C 05
|
|
00CD60 1
|
|
00CD60 1 BD 27 CD lda $CD27,x ; $CD60: BD 27 CD
|
|
00CD63 1 8D 3C 05 sta $053C ; $CD63: 8D 3C 05
|
|
00CD66 1
|
|
00CD66 1 BD 2A CD lda $CD2A,x ; $CD66: BD 2A CD
|
|
00CD69 1 8D 3D 05 sta $053D ; $CD69: 8D 3D 05
|
|
00CD6C 1 ; ----------------------------------------------------------------------------
|
|
00CD6C 1 ; Run the indexed helper and wait for $60 ticks.
|
|
00CD6C 1 ; ----------------------------------------------------------------------------
|
|
00CD6C 1
|
|
00CD6C 1 A2 02 ldx #$02 ; $CD6C: A2 02
|
|
00CD6E 1 20 B7 E6 jsr ClearMovementTransforms ; $CD6E: 20 B7 E6
|
|
00CD71 1
|
|
00CD71 1 A9 60 lda #$60 ; $CD71: A9 60
|
|
00CD73 1 20 41 EB jsr StoreObjectEventBankValue ; $CD73: 20 41 EB
|
|
00CD76 1
|
|
00CD76 1 A9 4B lda #$4B ; $CD76: A9 4B
|
|
00CD78 1 8D B1 03 sta $03B1 ; $CD78: 8D B1 03
|
|
00CD7B 1
|
|
00CD7B 1 ; ----------------------------------------------------------------------------
|
|
00CD7B 1 ; Wait for $3C ticks.
|
|
00CD7B 1 ; ----------------------------------------------------------------------------
|
|
00CD7B 1
|
|
00CD7B 1 WaitForStateAnimation: ; $CD7B
|
|
00CD7B 1 A9 3C lda #$3C ; $CD7B: A9 3C
|
|
00CD7D 1 20 41 EB jsr StoreObjectEventBankValue ; $CD7D: 20 41 EB
|
|
00CD80 1
|
|
00CD80 1 ; ----------------------------------------------------------------------------
|
|
00CD80 1 ; Initialize indexed fields using inline data consumed by $C9A7.
|
|
00CD80 1 ;
|
|
00CD80 1 ; The first inline byte, $02, is metadata consumed by the return-address
|
|
00CD80 1 ; helper. The following four bytes initialize the indexed fields:
|
|
00CD80 1 ;
|
|
00CD80 1 ; $00,$00,$C0,$F6
|
|
00CD80 1 ; ----------------------------------------------------------------------------
|
|
00CD80 1
|
|
00CD80 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00CD83 1 ; $CD80: 20 A7 C9
|
|
00CD83 1
|
|
00CD83 1 02 .byte $02 ; $CD83: inline metadata/count
|
|
00CD84 1 00 00 C0 F6 .byte $00,$00,$C0,$F6 ; $CD84-$CD87: field data
|
|
00CD88 1
|
|
00CD88 1 ; ----------------------------------------------------------------------------
|
|
00CD88 1 ; Run the indexed helper again and set the final animation/state value.
|
|
00CD88 1 ; ----------------------------------------------------------------------------
|
|
00CD88 1
|
|
00CD88 1 A2 02 ldx #$02 ; $CD88: A2 02
|
|
00CD8A 1 20 B7 E6 jsr ClearMovementTransforms ; $CD8A: 20 B7 E6
|
|
00CD8D 1
|
|
00CD8D 1 A9 47 lda #$47 ; $CD8D: A9 47
|
|
00CD8F 1 8D B1 03 sta $03B1 ; $CD8F: 8D B1 03
|
|
00CD92 1
|
|
00CD92 1 CE 96 05 dec $0596 ; $CD92: CE 96 05
|
|
00CD95 1
|
|
00CD95 1 4C 6A EB jmp CommonEngineExit ; $CD95: 4C 6A EB
|
|
00CD98 1
|
|
00CD98 1 ; ============================================================================
|
|
00CD98 1 ; $CD98-$CDA6
|
|
00CD98 1 ; Set state $6D to two, run state/action $2A, and leave through the common
|
|
00CD98 1 ; engine exit.
|
|
00CD98 1 ; ============================================================================
|
|
00CD98 1
|
|
00CD98 1 StartHomeRunSequence: ; $CD98
|
|
00CD98 1 A9 02 lda #$02 ; $CD98: A9 02
|
|
00CD9A 1 85 6D sta SpecialSequenceState ; $CD9A: 85 6D
|
|
00CD9C 1
|
|
00CD9C 1 A9 2A lda #$2A ; $CD9C: A9 2A
|
|
00CD9E 1 20 11 CF jsr AddTimedStateEvent ; $CD9E: 20 11 CF
|
|
00CDA1 1
|
|
00CDA1 1 4C 6A EB jmp CommonEngineExit ; $CDA1: 4C 6A EB
|
|
00CDA4 1
|
|
00CDA4 1 ; ============================================================================
|
|
00CDA4 1 ; $CDA4-$CE19
|
|
00CDA4 1 ; Initialize state $6D, run an animation sequence, draw an encoded message,
|
|
00CDA4 1 ; and repeatedly copy palette/data bytes into the PPU command queue.
|
|
00CDA4 1 ; ============================================================================
|
|
00CDA4 1
|
|
00CDA4 1 RunHomeRunCelebration: ; $CDA4
|
|
00CDA4 1 A9 01 lda #$01 ; $CDA4: A9 01
|
|
00CDA6 1 85 FD sta $FD ; $CDA6: 85 FD
|
|
00CDA8 1
|
|
00CDA8 1 A9 04 lda #$04 ; $CDA8: A9 04
|
|
00CDAA 1 85 6D sta SpecialSequenceState ; $CDAA: 85 6D
|
|
00CDAC 1
|
|
00CDAC 1 ; ----------------------------------------------------------------------------
|
|
00CDAC 1 ; Dispatch an inline command through QueueInlineObjectEvent.
|
|
00CDAC 1 ; ----------------------------------------------------------------------------
|
|
00CDAC 1
|
|
00CDAC 1 20 0A EB jsr QueueInlineObjectEvent ; $CDAC: 20 0A EB
|
|
00CDAF 1
|
|
00CDAF 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00CDAF 1 15 D8 CD .byte $15,$D8,$CD ; $CDAF-$CDB1
|
|
00CDB2 1
|
|
00CDB2 1 ; ----------------------------------------------------------------------------
|
|
00CDB2 1 ; Increment the current object's animation index twice.
|
|
00CDB2 1 ; ----------------------------------------------------------------------------
|
|
00CDB2 1
|
|
00CDB2 1 A6 E1 ldx CurrentObjectIndex ; $CDB2: A6 E1
|
|
00CDB4 1 20 38 E7 jsr ConvertObjectOffsetToDisplayIndex ; $CDB4: 20 38 E7
|
|
00CDB7 1
|
|
00CDB7 1 FE 9A 03 inc $039A,x ; $CDB7: FE 9A 03
|
|
00CDBA 1 FE 9A 03 inc $039A,x ; $CDBA: FE 9A 03
|
|
00CDBD 1
|
|
00CDBD 1 ; ----------------------------------------------------------------------------
|
|
00CDBD 1 ; Wait $14 ticks, increment the animation index once more, then wait again.
|
|
00CDBD 1 ; ----------------------------------------------------------------------------
|
|
00CDBD 1
|
|
00CDBD 1 HomeRunAnimationLoop: ; $CDBD
|
|
00CDBD 1 A9 14 lda #$14 ; $CDBD: A9 14
|
|
00CDBF 1 20 41 EB jsr StoreObjectEventBankValue ; $CDBF: 20 41 EB
|
|
00CDC2 1
|
|
00CDC2 1 A6 E1 ldx CurrentObjectIndex ; $CDC2: A6 E1
|
|
00CDC4 1 20 38 E7 jsr ConvertObjectOffsetToDisplayIndex ; $CDC4: 20 38 E7
|
|
00CDC7 1
|
|
00CDC7 1 FE 9A 03 inc $039A,x ; $CDC7: FE 9A 03
|
|
00CDCA 1
|
|
00CDCA 1 A9 14 lda #$14 ; $CDCA: A9 14
|
|
00CDCC 1 20 41 EB jsr StoreObjectEventBankValue ; $CDCC: 20 41 EB
|
|
00CDCF 1
|
|
00CDCF 1 ; ----------------------------------------------------------------------------
|
|
00CDCF 1 ; Decrement the animation index. Repeat while the result is nonzero.
|
|
00CDCF 1 ; ----------------------------------------------------------------------------
|
|
00CDCF 1
|
|
00CDCF 1 A6 E1 ldx CurrentObjectIndex ; $CDCF: A6 E1
|
|
00CDD1 1 20 38 E7 jsr ConvertObjectOffsetToDisplayIndex ; $CDD1: 20 38 E7
|
|
00CDD4 1
|
|
00CDD4 1 DE 9A 03 dec $039A,x ; $CDD4: DE 9A 03
|
|
00CDD7 1 D0 E4 bne HomeRunAnimationLoop
|
|
00CDD9 1 ; $CDD7: D0 E4
|
|
00CDD9 1
|
|
00CDD9 1 ; ----------------------------------------------------------------------------
|
|
00CDD9 1 ; Draw an eight-character encoded message.
|
|
00CDD9 1 ; ----------------------------------------------------------------------------
|
|
00CDD9 1
|
|
00CDD9 1 A9 20 lda #$20 ; $CDD9: A9 20
|
|
00CDDB 1 A2 EC ldx #$EC ; $CDDB: A2 EC
|
|
00CDDD 1 A0 08 ldy #$08 ; $CDDD: A0 08
|
|
00CDDF 1 18 clc ; $CDDF: 18
|
|
00CDE0 1
|
|
00CDE0 1 20 17 EA jsr CopyInlineDisplayRecord ; $CDE0: 20 17 EA
|
|
00CDE3 1
|
|
00CDE3 1 08 .byte $08 ; $CDE3: character count
|
|
00CDE4 1 11 18 16 0E .byte $11,$18,$16,$0E ; $CDE4-$CDE7
|
|
00CDE8 1 25 1B 1E 17 .byte $25,$1B,$1E,$17 ; $CDE8-$CDEB
|
|
00CDEC 1
|
|
00CDEC 1 ; ----------------------------------------------------------------------------
|
|
00CDEC 1 ; Set up the table-copy loop.
|
|
00CDEC 1 ; ----------------------------------------------------------------------------
|
|
00CDEC 1
|
|
00CDEC 1 ResetCelebrationColorIndex: ; $CDEC
|
|
00CDEC 1 A0 07 ldy #$07 ; $CDEC: A0 07
|
|
00CDEE 1
|
|
00CDEE 1 SaveCelebrationColorIndex: ; $CDEE
|
|
00CDEE 1 84 70 sty $70 ; $CDEE: 84 70
|
|
00CDF0 1
|
|
00CDF0 1 A9 06 lda #$06 ; $CDF0: A9 06
|
|
00CDF2 1 8D C6 05 sta $05C6 ; $CDF2: 8D C6 05
|
|
00CDF5 1
|
|
00CDF5 1 ; ----------------------------------------------------------------------------
|
|
00CDF5 1 ; Wait for six frames/ticks. Set bit 7 of $FE after each wait.
|
|
00CDF5 1 ; ----------------------------------------------------------------------------
|
|
00CDF5 1
|
|
00CDF5 1 WaitCelebrationColorFrame: ; $CDF5
|
|
00CDF5 1 20 48 EB jsr SelectObjectEventBank1 ; $CDF5: 20 48 EB
|
|
00CDF8 1
|
|
00CDF8 1 A5 FE lda PendingAudioFlags ; $CDF8: A5 FE
|
|
00CDFA 1 09 80 ora #$80 ; $CDFA: 09 80
|
|
00CDFC 1 85 FE sta PendingAudioFlags ; $CDFC: 85 FE
|
|
00CDFE 1
|
|
00CDFE 1 CE C6 05 dec $05C6 ; $CDFE: CE C6 05
|
|
00CE01 1 D0 F2 bne WaitCelebrationColorFrame ; $CE01: D0 F2
|
|
00CE03 1
|
|
00CE03 1 ; ----------------------------------------------------------------------------
|
|
00CE03 1 ; Start a one-byte PPU command.
|
|
00CE03 1 ; ----------------------------------------------------------------------------
|
|
00CE03 1
|
|
00CE03 1 A9 3F lda #$3F ; $CE03: A9 3F
|
|
00CE05 1 A2 07 ldx #$07 ; $CE05: A2 07
|
|
00CE07 1 A0 01 ldy #$01 ; $CE07: A0 01
|
|
00CE09 1 18 clc ; $CE09: 18
|
|
00CE0A 1
|
|
00CE0A 1 20 3E EA jsr AllocateDisplayBufferRecord ; $CE0A: 20 3E EA
|
|
00CE0D 1
|
|
00CE0D 1 ; ----------------------------------------------------------------------------
|
|
00CE0D 1 ; Append one byte from the table at $CE1A.
|
|
00CE0D 1 ; ----------------------------------------------------------------------------
|
|
00CE0D 1
|
|
00CE0D 1 A4 70 ldy TableCopyIndex ; $CE0D: A4 70
|
|
00CE0F 1
|
|
00CE0F 1 B9 1A CE lda CelebrationPaletteSequence,y ; $CE0F: B9 1A CE
|
|
00CE12 1 9D 00 03 sta $0300,x ; $CE12: 9D 00 03
|
|
00CE15 1
|
|
00CE15 1 88 dey ; $CE15: 88
|
|
00CE16 1 10 D6 bpl SaveCelebrationColorIndex ; $CE16: 10 D6
|
|
00CE18 1
|
|
00CE18 1 30 D2 bmi ResetCelebrationColorIndex
|
|
00CE1A 1 ; $CE18: 30 D2
|
|
00CE1A 1 ; Always taken after Y becomes negative.
|
|
00CE1A 1
|
|
00CE1A 1 ; ============================================================================
|
|
00CE1A 1 ; $CE1A-$CE21
|
|
00CE1A 1 ; Eight-byte lookup table used by the loop above.
|
|
00CE1A 1 ; ============================================================================
|
|
00CE1A 1
|
|
00CE1A 1 CelebrationPaletteSequence: ; $CE1A
|
|
00CE1A 1 30 21 33 24 .byte $30,$21,$33,$24
|
|
00CE1E 1 36 27 39 2A .byte $36,$27,$39,$2A
|
|
00CE22 1
|
|
00CE22 1 ; ============================================================================
|
|
00CE22 1 ; $CE22-$CE31
|
|
00CE22 1 ; Clear active state, advance $45, process event slot $11, then leave through
|
|
00CE22 1 ; command $08.
|
|
00CE22 1 ; ============================================================================
|
|
00CE22 1
|
|
00CE22 1 ; ----------------------------------------------------------------------------
|
|
00CE22 1 ; Contract:
|
|
00CE22 1 ; Description: Implements Finish State Progression.
|
|
00CE22 1 ; Entry: Registers: A
|
|
00CE22 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CE22 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CE22 1 ; Memory effects: basemotionactive
|
|
00CE22 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CE22 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CE22 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00CE22 1 ; ----------------------------------------------------------------------------
|
|
00CE22 1 FinishStateProgression: ; $CE22
|
|
00CE22 1 A9 00 lda #$00 ; $CE22: A9 00
|
|
00CE24 1 85 5C sta BaseMotionActive ; $CE24: 85 5C
|
|
00CE26 1
|
|
00CE26 1 E6 45 inc MatchCompleteFlag ; $CE26: E6 45
|
|
00CE28 1
|
|
00CE28 1 A0 11 ldy #$11 ; $CE28: A0 11
|
|
00CE2A 1 20 66 EB jsr DispatchNextQueuedEvent ; $CE2A: 20 66 EB
|
|
00CE2D 1
|
|
00CE2D 1 A2 08 ldx #$08 ; $CE2D: A2 08
|
|
00CE2F 1 4C 2A EB jmp ProcessQueuedObjectEvent ; $CE2F: 4C 2A EB
|
|
00CE32 1
|
|
00CE32 1 ; ============================================================================
|
|
00CE32 1 ; $CE32-$CEA4
|
|
00CE32 1 ; Search a timing/state table, map selected values to flags, display the
|
|
00CE32 1 ; corresponding message, and loop until the state condition is complete.
|
|
00CE32 1 ; ============================================================================
|
|
00CE32 1
|
|
00CE32 1 RunEventAnnouncementLoop: ; $CE32
|
|
00CE32 1 A9 00 lda #$00 ; $CE32: A9 00
|
|
00CE34 1 85 6F sta PendingEvent ; $CE34: 85 6F
|
|
00CE36 1
|
|
00CE36 1 ReloadAnnouncementDelay: ; $CE36
|
|
00CE36 1 A9 01 lda #$01 ; $CE36: A9 01
|
|
00CE38 1
|
|
00CE38 1 WaitAnnouncementDelay: ; $CE38
|
|
00CE38 1 20 41 EB jsr StoreObjectEventBankValue ; $CE38: 20 41 EB
|
|
00CE3B 1
|
|
00CE3B 1 ; ----------------------------------------------------------------------------
|
|
00CE3B 1 ; Compare the current index in $6A with the limit in $69.
|
|
00CE3B 1 ; If equal, restart the search from its initial state.
|
|
00CE3B 1 ; ----------------------------------------------------------------------------
|
|
00CE3B 1
|
|
00CE3B 1 A6 6A ldx EventReadIndex ; $CE3B: A6 6A
|
|
00CE3D 1 E4 69 cpx EventWriteIndex ; $CE3D: E4 69
|
|
00CE3F 1 F0 F1 beq RunEventAnnouncementLoop ; $CE3F: F0 F1
|
|
00CE41 1
|
|
00CE41 1 CA dex ; $CE41: CA
|
|
00CE42 1 10 02 bpl FindReadyAnnouncement ; $CE42: 10 02
|
|
00CE44 1
|
|
00CE44 1 A2 03 ldx #$03 ; $CE44: A2 03
|
|
00CE46 1
|
|
00CE46 1 ; ----------------------------------------------------------------------------
|
|
00CE46 1 ; Search backward for a zero timer/state entry in $05AD-$05B0.
|
|
00CE46 1 ; Nonzero entries return to $CE36, reloading the delay value with one.
|
|
00CE46 1 ; ----------------------------------------------------------------------------
|
|
00CE46 1
|
|
00CE46 1 FindReadyAnnouncement: ; $CE46
|
|
00CE46 1 BD AD 05 lda $05AD,x ; $CE46: BD AD 05
|
|
00CE49 1 D0 EB bne ReloadAnnouncementDelay ; $CE49: D0 EB
|
|
00CE4B 1
|
|
00CE4B 1 86 6A stx EventReadIndex ; $CE4B: 86 6A
|
|
00CE4D 1 E6 6F inc PendingEvent ; $CE4D: E6 6F
|
|
00CE4F 1
|
|
00CE4F 1 BD A9 05 lda $05A9,x ; $CE4F: BD A9 05
|
|
00CE52 1 8D BA 05 sta $05BA ; $CE52: 8D BA 05
|
|
00CE55 1
|
|
00CE55 1 ; ----------------------------------------------------------------------------
|
|
00CE55 1 ; Wait one frame and retrieve the selected table value.
|
|
00CE55 1 ; ----------------------------------------------------------------------------
|
|
00CE55 1
|
|
00CE55 1 20 48 EB jsr SelectObjectEventBank1 ; $CE55: 20 48 EB
|
|
00CE58 1
|
|
00CE58 1 AC BA 05 ldy $05BA ; $CE58: AC BA 05
|
|
00CE5B 1
|
|
00CE5B 1 C0 3C cpy #$3C ; $CE5B: C0 3C
|
|
00CE5D 1 D0 12 bne MapAnnouncementToAudioFlag ; $CE5D: D0 12
|
|
00CE5F 1
|
|
00CE5F 1 ; ----------------------------------------------------------------------------
|
|
00CE5F 1 ; Special handling for value $3C.
|
|
00CE5F 1 ; ----------------------------------------------------------------------------
|
|
00CE5F 1
|
|
00CE5F 1 A5 69 lda EventWriteIndex ; $CE5F: A5 69
|
|
00CE61 1 85 6A sta EventReadIndex ; $CE61: 85 6A
|
|
00CE63 1
|
|
00CE63 1 A5 33 lda RoundStateIndex ; $CE63: A5 33
|
|
00CE65 1 C9 10 cmp #$10 ; $CE65: C9 10
|
|
00CE67 1 90 08 bcc MapAnnouncementToAudioFlag ; $CE67: 90 08
|
|
00CE69 1
|
|
00CE69 1 D0 31 bne DisplayBlankAnnouncement
|
|
00CE6B 1 ; $CE69: D0 31
|
|
00CE6B 1
|
|
00CE6B 1 A5 67 lda PlayerOneScore ; $CE6B: A5 67
|
|
00CE6D 1 C5 68 cmp PlayerTwoScore ; $CE6D: C5 68
|
|
00CE6F 1 90 2B bcc DisplayBlankAnnouncement
|
|
00CE71 1 ; $CE6F: 90 2B
|
|
00CE71 1
|
|
00CE71 1 ; ----------------------------------------------------------------------------
|
|
00CE71 1 ; Map selected Y values to a bit/flag value in X.
|
|
00CE71 1 ; ----------------------------------------------------------------------------
|
|
00CE71 1
|
|
00CE71 1 MapAnnouncementToAudioFlag: ; $CE71
|
|
00CE71 1 A2 00 ldx #$00 ; $CE71: A2 00
|
|
00CE73 1
|
|
00CE73 1 C0 06 cpy #$06 ; $CE73: C0 06
|
|
00CE75 1 D0 02 bne CheckAnnouncement12 ; $CE75: D0 02
|
|
00CE77 1
|
|
00CE77 1 A2 08 ldx #$08 ; $CE77: A2 08
|
|
00CE79 1
|
|
00CE79 1 CheckAnnouncement12: ; $CE79
|
|
00CE79 1 C0 12 cpy #$12 ; $CE79: C0 12
|
|
00CE7B 1 D0 02 bne CheckAnnouncement42 ; $CE7B: D0 02
|
|
00CE7D 1
|
|
00CE7D 1 A2 01 ldx #$01 ; $CE7D: A2 01
|
|
00CE7F 1
|
|
00CE7F 1 CheckAnnouncement42: ; $CE7F
|
|
00CE7F 1 C0 42 cpy #$42 ; $CE7F: C0 42
|
|
00CE81 1 D0 02 bne CheckAnnouncement0C ; $CE81: D0 02
|
|
00CE83 1
|
|
00CE83 1 A2 02 ldx #$02 ; $CE83: A2 02
|
|
00CE85 1
|
|
00CE85 1 CheckAnnouncement0C: ; $CE85
|
|
00CE85 1 C0 0C cpy #$0C ; $CE85: C0 0C
|
|
00CE87 1 D0 02 bne CheckAnnouncement18 ; $CE87: D0 02
|
|
00CE89 1
|
|
00CE89 1 A2 10 ldx #$10 ; $CE89: A2 10
|
|
00CE8B 1
|
|
00CE8B 1 CheckAnnouncement18: ; $CE8B
|
|
00CE8B 1 C0 18 cpy #$18 ; $CE8B: C0 18
|
|
00CE8D 1 D0 02 bne SaveAnnouncementAudioFlag ; $CE8D: D0 02
|
|
00CE8F 1
|
|
00CE8F 1 A2 08 ldx #$08 ; $CE8F: A2 08
|
|
00CE91 1
|
|
00CE91 1 SaveAnnouncementAudioFlag: ; $CE91
|
|
00CE91 1 86 FE stx PendingAudioFlags ; $CE91: 86 FE
|
|
00CE93 1
|
|
00CE93 1 98 tya ; $CE93: 98
|
|
00CE94 1 20 A5 CE jsr DisplayAnnouncementPair
|
|
00CE97 1 ; $CE94: 20 A5 CE
|
|
00CE97 1
|
|
00CE97 1 A9 3C lda #$3C ; $CE97: A9 3C
|
|
00CE99 1 20 41 EB jsr StoreObjectEventBankValue ; $CE99: 20 41 EB
|
|
00CE9C 1
|
|
00CE9C 1 ; ----------------------------------------------------------------------------
|
|
00CE9C 1 ; Display the default message.
|
|
00CE9C 1 ; ----------------------------------------------------------------------------
|
|
00CE9C 1
|
|
00CE9C 1 DisplayBlankAnnouncement: ; $CE9C
|
|
00CE9C 1 A9 00 lda #$00 ; $CE9C: A9 00
|
|
00CE9E 1 20 A5 CE jsr DisplayAnnouncementPair
|
|
00CEA1 1 ; $CE9E: 20 A5 CE
|
|
00CEA1 1
|
|
00CEA1 1 ; ----------------------------------------------------------------------------
|
|
00CEA1 1 ; Continue at the wait call without reloading A with one.
|
|
00CEA1 1 ;
|
|
00CEA1 1 ; This distinct target is required for the original D0 93 branch operand:
|
|
00CEA1 1 ;
|
|
00CEA1 1 ; $CEA3: D0 93 -> $CE38
|
|
00CEA1 1 ; ----------------------------------------------------------------------------
|
|
00CEA1 1
|
|
00CEA1 1 A9 05 lda #$05 ; $CEA1: A9 05
|
|
00CEA3 1 D0 93 bne WaitAnnouncementDelay ; $CEA3: D0 93
|
|
00CEA5 1 ; Always taken because A is nonzero.
|
|
00CEA5 1
|
|
00CEA5 1 ; ============================================================================
|
|
00CEA5 1 ; $CEA5-$CEC8
|
|
00CEA5 1 ; Queue a six-byte encoded message selected by A.
|
|
00CEA5 1 ;
|
|
00CEA5 1 ; Entry:
|
|
00CEA5 1 ; A = offset into the encoded text table at $CEC9.
|
|
00CEA5 1 ; ============================================================================
|
|
00CEA5 1
|
|
00CEA5 1 DisplayAnnouncementPair: ; $CEA5
|
|
00CEA5 1 48 pha ; $CEA5: 48
|
|
00CEA6 1
|
|
00CEA6 1 A0 23 ldy #$23 ; $CEA6: A0 23
|
|
00CEA8 1 20 AE CE jsr QueueAnnouncementText ; $CEA8: 20 AE CE
|
|
00CEAB 1
|
|
00CEAB 1 68 pla ; $CEAB: 68
|
|
00CEAC 1
|
|
00CEAC 1 ; ----------------------------------------------------------------------------
|
|
00CEAC 1 ; Secondary entry point.
|
|
00CEAC 1 ;
|
|
00CEAC 1 ; Entry:
|
|
00CEAC 1 ; A = text-table offset.
|
|
00CEAC 1 ; The destination selector is changed to $2B.
|
|
00CEAC 1 ; ----------------------------------------------------------------------------
|
|
00CEAC 1
|
|
00CEAC 1 DisplaySecondaryAnnouncement: ; $CEAC
|
|
00CEAC 1 A0 2B ldy #$2B ; $CEAC: A0 2B
|
|
00CEAE 1
|
|
00CEAE 1 ; ----------------------------------------------------------------------------
|
|
00CEAE 1 ; Contract:
|
|
00CEAE 1 ; Description: Queues Announcement Text.
|
|
00CEAE 1 ; Entry: Registers: A, X, Y; Memory: announcementtexttable
|
|
00CEAE 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CEAE 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CEAE 1 ; Memory effects: textcopycount, $0300
|
|
00CEAE 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CEAE 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CEAE 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CEAE 1 ; ----------------------------------------------------------------------------
|
|
00CEAE 1 QueueAnnouncementText: ; $CEAE
|
|
00CEAE 1 48 pha ; $CEAE: 48
|
|
00CEAF 1 18 clc ; $CEAF: 18
|
|
00CEB0 1
|
|
00CEB0 1 98 tya ; $CEB0: 98
|
|
00CEB1 1 A2 37 ldx #$37 ; $CEB1: A2 37
|
|
00CEB3 1 A0 06 ldy #$06 ; $CEB3: A0 06
|
|
00CEB5 1
|
|
00CEB5 1 84 6B sty TextCopyCount ; $CEB5: 84 6B
|
|
00CEB7 1
|
|
00CEB7 1 20 3E EA jsr AllocateDisplayBufferRecord ; $CEB7: 20 3E EA
|
|
00CEBA 1
|
|
00CEBA 1 68 pla ; $CEBA: 68
|
|
00CEBB 1 A8 tay ; $CEBB: A8
|
|
00CEBC 1
|
|
00CEBC 1 CopyAnnouncementText: ; $CEBC
|
|
00CEBC 1 B9 C9 CE lda AnnouncementTextTable,y ; $CEBC: B9 C9 CE
|
|
00CEBF 1 9D 00 03 sta $0300,x ; $CEBF: 9D 00 03
|
|
00CEC2 1
|
|
00CEC2 1 C8 iny ; $CEC2: C8
|
|
00CEC3 1 E8 inx ; $CEC3: E8
|
|
00CEC4 1
|
|
00CEC4 1 C6 6B dec TextCopyCount ; $CEC4: C6 6B
|
|
00CEC6 1 D0 F4 bne CopyAnnouncementText ; $CEC6: D0 F4
|
|
00CEC8 1
|
|
00CEC8 1 60 rts ; $CEC8: 60
|
|
00CEC9 1
|
|
00CEC9 1 ; ============================================================================
|
|
00CEC9 1 ; Encoded text/data table begins at CPU $CEC9.
|
|
00CEC9 1 ; ============================================================================
|
|
00CEC9 1
|
|
00CEC9 1 ; ============================================================================
|
|
00CEC9 1 ; $CEC9-$CF10
|
|
00CEC9 1 ; Encoded six-character message table.
|
|
00CEC9 1 ;
|
|
00CEC9 1 ; Routine $CEA5 selects an entry by passing an offset in A, then copies six
|
|
00CEC9 1 ; bytes beginning at AnnouncementTextTable + A.
|
|
00CEC9 1 ;
|
|
00CEC9 1 ; Known offsets used by the preceding routine include:
|
|
00CEC9 1 ;
|
|
00CEC9 1 ; $00, $06, $0C, $12, $18, $1E, $24, $2A, $30, $36, $3C, $42
|
|
00CEC9 1 ;
|
|
00CEC9 1 ; Each entry is exactly six bytes.
|
|
00CEC9 1 ; ============================================================================
|
|
00CEC9 1
|
|
00CEC9 1 AnnouncementTextTable: ; $CEC9
|
|
00CEC9 1
|
|
00CEC9 1 AnnouncementTextBlank: ; $CEC9, offset $00
|
|
00CEC9 1 25 25 25 25 .byte $25,$25,$25,$25,$25,$25
|
|
00CECD 1 25 25
|
|
00CECF 1
|
|
00CECF 1 AnnouncementTextFoul: ; $CECF, offset $06
|
|
00CECF 1 25 0F 18 1E .byte $25,$0F,$18,$1E,$15,$25
|
|
00CED3 1 15 25
|
|
00CED5 1
|
|
00CED5 1 AnnouncementTextStrike: ; $CED5, offset $0C
|
|
00CED5 1 1C 1D 1B 12 .byte $1C,$1D,$1B,$12,$14,$0E
|
|
00CED9 1 14 0E
|
|
00CEDB 1
|
|
00CEDB 1 AnnouncementTextOut: ; $CEDB, offset $12
|
|
00CEDB 1 25 18 1E 1D .byte $25,$18,$1E,$1D,$25,$25
|
|
00CEDF 1 25 25
|
|
00CEE1 1
|
|
00CEE1 1 AnnouncementTextBall: ; $CEE1, offset $18
|
|
00CEE1 1 25 0B 0A 15 .byte $25,$0B,$0A,$15,$15,$25
|
|
00CEE5 1 15 25
|
|
00CEE7 1
|
|
00CEE7 1 AnnouncementTextWalk: ; $CEE7, offset $1E
|
|
00CEE7 1 25 20 0A 15 .byte $25,$20,$0A,$15,$14,$25
|
|
00CEEB 1 14 25
|
|
00CEED 1
|
|
00CEED 1 AnnouncementTextSingle: ; $CEED, offset $24
|
|
00CEED 1 1C 12 17 10 .byte $1C,$12,$17,$10,$15,$0E
|
|
00CEF1 1 15 0E
|
|
00CEF3 1
|
|
00CEF3 1 AnnouncementTextTwoBase: ; $CEF3, offset $2A
|
|
00CEF3 1 02 25 0B 0A .byte $02,$25,$0B,$0A,$1C,$0E
|
|
00CEF7 1 1C 0E
|
|
00CEF9 1
|
|
00CEF9 1 AnnouncementTextThreeBase: ; $CEF9, offset $30
|
|
00CEF9 1 03 25 0B 0A .byte $03,$25,$0B,$0A,$1C,$0E
|
|
00CEFD 1 1C 0E
|
|
00CEFF 1
|
|
00CEFF 1 AnnouncementTextDeadBall: ; $CEFF, offset $36
|
|
00CEFF 1 0D 25 0B 0A .byte $0D,$25,$0B,$0A,$15,$15
|
|
00CF03 1 15 15
|
|
00CF05 1
|
|
00CF05 1 AnnouncementTextChange: ; $CF05, offset $3C
|
|
00CF05 1 0C 11 0A 17 .byte $0C,$11,$0A,$17,$10,$0E
|
|
00CF09 1 10 0E
|
|
00CF0B 1
|
|
00CF0B 1 AnnouncementTextSafe: ; $CF0B, offset $42
|
|
00CF0B 1 25 1C 0A 0F .byte $25,$1C,$0A,$0F,$0E,$25
|
|
00CF0F 1 0E 25
|
|
00CF11 1
|
|
00CF11 1 ; ============================================================================
|
|
00CF11 1 ; $CF11-$CF22
|
|
00CF11 1 ; Move backward through a four-entry circular index and initialize the
|
|
00CF11 1 ; corresponding timer/state fields.
|
|
00CF11 1 ;
|
|
00CF11 1 ; Input:
|
|
00CF11 1 ; A = value stored into $05A9,X
|
|
00CF11 1 ;
|
|
00CF11 1 ; Operation:
|
|
00CF11 1 ; Decrement $69, wrapping from $00 to $03.
|
|
00CF11 1 ; Store the caller-supplied A value into $05A9,X.
|
|
00CF11 1 ; Initialize $05AD,X to $14.
|
|
00CF11 1 ;
|
|
00CF11 1 ; Output:
|
|
00CF11 1 ; X = updated index
|
|
00CF11 1 ; $69 = updated index
|
|
00CF11 1 ; ============================================================================
|
|
00CF11 1
|
|
00CF11 1 ; ----------------------------------------------------------------------------
|
|
00CF11 1 ; Contract:
|
|
00CF11 1 ; Description: Implements Add Timed State Event.
|
|
00CF11 1 ; Entry: Registers: A, X; Memory: eventwriteindex
|
|
00CF11 1 ; Returns/products: Registers/clobbers: A, X
|
|
00CF11 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF11 1 ; Memory effects: eventwriteindex, $05a9, $05ad
|
|
00CF11 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF11 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF11 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 9.
|
|
00CF11 1 ; ----------------------------------------------------------------------------
|
|
00CF11 1 AddTimedStateEvent: ; $CF11
|
|
00CF11 1 A6 69 ldx EventWriteIndex ; $CF11: A6 69
|
|
00CF13 1
|
|
00CF13 1 CA dex ; $CF13: CA
|
|
00CF14 1 10 02 bpl Routine_CF18_SaveIndex ; $CF14: 10 02
|
|
00CF16 1
|
|
00CF16 1 A2 03 ldx #$03 ; $CF16: A2 03
|
|
00CF18 1 ; Wrap the index from zero to three.
|
|
00CF18 1
|
|
00CF18 1 Routine_CF18_SaveIndex: ; $CF18
|
|
00CF18 1 86 69 stx EventWriteIndex ; $CF18: 86 69
|
|
00CF1A 1
|
|
00CF1A 1 9D A9 05 sta $05A9,x ; $CF1A: 9D A9 05
|
|
00CF1D 1 ; Store the caller-supplied state value.
|
|
00CF1D 1
|
|
00CF1D 1 A9 14 lda #$14 ; $CF1D: A9 14
|
|
00CF1F 1 9D AD 05 sta $05AD,x ; $CF1F: 9D AD 05
|
|
00CF22 1 ; Initialize the associated timer.
|
|
00CF22 1
|
|
00CF22 1 60 rts ; $CF22: 60
|
|
00CF23 1
|
|
00CF23 1 ; ============================================================================
|
|
00CF23 1 ; $CF23-$CF44
|
|
00CF23 1 ; Select a state-dependent value, construct a one-byte PPU queue entry,
|
|
00CF23 1 ; and append tile/data byte $AE.
|
|
00CF23 1 ;
|
|
00CF23 1 ; Two entry points exist:
|
|
00CF23 1 ;
|
|
00CF23 1 ; $CF23 derives a value from $62 using base $22.
|
|
00CF23 1 ; $CF2A derives a value from $64 using base $42.
|
|
00CF23 1 ;
|
|
00CF23 1 ; Both paths continue through $CF2F.
|
|
00CF23 1 ; ============================================================================
|
|
00CF23 1
|
|
00CF23 1 ; ----------------------------------------------------------------------------
|
|
00CF23 1 ; Contract:
|
|
00CF23 1 ; Description: Queues Primary State Marker.
|
|
00CF23 1 ; Entry: Registers: A; Memory: primarysequencestate, secondarysequencestate
|
|
00CF23 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CF23 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF23 1 ; Memory effects: $0300
|
|
00CF23 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF23 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF23 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00CF23 1 ; ----------------------------------------------------------------------------
|
|
00CF23 1 QueuePrimaryStateMarker: ; $CF23
|
|
00CF23 1 18 clc ; $CF23: 18
|
|
00CF24 1
|
|
00CF24 1 A9 22 lda #$22 ; $CF24: A9 22
|
|
00CF26 1 65 62 adc PrimarySequenceState ; $CF26: 65 62
|
|
00CF28 1
|
|
00CF28 1 D0 05 bne BuildStateMarkerEntries ; $CF28: D0 05
|
|
00CF2A 1 ; Always taken unless the addition wraps
|
|
00CF2A 1 ; exactly to zero.
|
|
00CF2A 1
|
|
00CF2A 1 ; ----------------------------------------------------------------------------
|
|
00CF2A 1 ; Secondary entry point used by callers that derive the value from $64.
|
|
00CF2A 1 ; ----------------------------------------------------------------------------
|
|
00CF2A 1
|
|
00CF2A 1 ; ----------------------------------------------------------------------------
|
|
00CF2A 1 ; Contract:
|
|
00CF2A 1 ; Description: Queues Secondary State Marker.
|
|
00CF2A 1 ; Entry: Registers: A; Memory: secondarysequencestate
|
|
00CF2A 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CF2A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF2A 1 ; Memory effects: $0300
|
|
00CF2A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF2A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF2A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00CF2A 1 ; ----------------------------------------------------------------------------
|
|
00CF2A 1 QueueSecondaryStateMarker: ; $CF2A
|
|
00CF2A 1 18 clc ; $CF2A: 18
|
|
00CF2B 1
|
|
00CF2B 1 A9 42 lda #$42 ; $CF2B: A9 42
|
|
00CF2D 1 65 64 adc SecondarySequenceState ; $CF2D: 65 64
|
|
00CF2F 1
|
|
00CF2F 1 ; ----------------------------------------------------------------------------
|
|
00CF2F 1 ; Preserve the calculated value, perform the first setup call, then use the
|
|
00CF2F 1 ; saved value as X for the PPU queue helper.
|
|
00CF2F 1 ; ----------------------------------------------------------------------------
|
|
00CF2F 1
|
|
00CF2F 1 ; ----------------------------------------------------------------------------
|
|
00CF2F 1 ; Contract:
|
|
00CF2F 1 ; Description: Implements Build State Marker Entries.
|
|
00CF2F 1 ; Entry: Registers: A
|
|
00CF2F 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CF2F 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF2F 1 ; Memory effects: $0300
|
|
00CF2F 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF2F 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF2F 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CF2F 1 ; ----------------------------------------------------------------------------
|
|
00CF2F 1 BuildStateMarkerEntries: ; $CF2F
|
|
00CF2F 1 48 pha ; $CF2F: 48
|
|
00CF30 1 AA tax ; $CF30: AA
|
|
00CF31 1
|
|
00CF31 1 A9 23 lda #$23 ; $CF31: A9 23
|
|
00CF33 1 20 3A CF jsr QueueStateMarkerEntry ; $CF33: 20 3A CF
|
|
00CF36 1
|
|
00CF36 1 68 pla ; $CF36: 68
|
|
00CF37 1 AA tax ; $CF37: AA
|
|
00CF38 1
|
|
00CF38 1 A9 2B lda #$2B ; $CF38: A9 2B
|
|
00CF3A 1
|
|
00CF3A 1 ; ----------------------------------------------------------------------------
|
|
00CF3A 1 ; Secondary helper entry.
|
|
00CF3A 1 ;
|
|
00CF3A 1 ; Entry:
|
|
00CF3A 1 ; A = destination selector/address component
|
|
00CF3A 1 ; X = state-derived coordinate/index
|
|
00CF3A 1 ;
|
|
00CF3A 1 ; Queue one data byte and append $AE.
|
|
00CF3A 1 ; ----------------------------------------------------------------------------
|
|
00CF3A 1
|
|
00CF3A 1 ; ----------------------------------------------------------------------------
|
|
00CF3A 1 ; Contract:
|
|
00CF3A 1 ; Description: Queues State Marker Entry.
|
|
00CF3A 1 ; Entry: Registers: A
|
|
00CF3A 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00CF3A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF3A 1 ; Memory effects: $0300
|
|
00CF3A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF3A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF3A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CF3A 1 ; ----------------------------------------------------------------------------
|
|
00CF3A 1 QueueStateMarkerEntry: ; $CF3A
|
|
00CF3A 1 A0 01 ldy #$01 ; $CF3A: A0 01
|
|
00CF3C 1
|
|
00CF3C 1 20 3E EA jsr AllocateDisplayBufferRecord ; $CF3C: 20 3E EA
|
|
00CF3F 1
|
|
00CF3F 1 A9 AE lda #$AE ; $CF3F: A9 AE
|
|
00CF41 1 9D 00 03 sta $0300,x ; $CF41: 9D 00 03
|
|
00CF44 1
|
|
00CF44 1 60 rts ; $CF44: 60
|
|
00CF45 1
|
|
00CF45 1 ; ============================================================================
|
|
00CF45 1 ; $CF45-$CF66
|
|
00CF45 1 ; Queue two related three-character display fields.
|
|
00CF45 1 ;
|
|
00CF45 1 ; Entry points:
|
|
00CF45 1 ; $CF45 queues fields using selectors $43 and $23.
|
|
00CF45 1 ; $CF4A queues only the field using selector $23.
|
|
00CF45 1 ; $CF51 accepts a selector in A.
|
|
00CF45 1 ; $CF5C performs the final three-character blank-field write.
|
|
00CF45 1 ; ============================================================================
|
|
00CF45 1
|
|
00CF45 1 ; ----------------------------------------------------------------------------
|
|
00CF45 1 ; Contract:
|
|
00CF45 1 ; Description: Clears or resets Both State Fields.
|
|
00CF45 1 ; Entry: Registers: A
|
|
00CF45 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00CF45 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF45 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00CF45 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF45 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF45 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CF45 1 ; ----------------------------------------------------------------------------
|
|
00CF45 1 ClearBothStateFields: ; $CF45
|
|
00CF45 1 A9 43 lda #$43 ; $CF45: A9 43
|
|
00CF47 1 20 51 CF jsr ClearStateFieldPair ; $CF47: 20 51 CF
|
|
00CF4A 1
|
|
00CF4A 1 ; ----------------------------------------------------------------------------
|
|
00CF4A 1 ; Secondary entry point.
|
|
00CF4A 1 ; ----------------------------------------------------------------------------
|
|
00CF4A 1
|
|
00CF4A 1 ; ----------------------------------------------------------------------------
|
|
00CF4A 1 ; Contract:
|
|
00CF4A 1 ; Description: Clears or resets Primary State Field.
|
|
00CF4A 1 ; Entry: Registers: A
|
|
00CF4A 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00CF4A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF4A 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00CF4A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF4A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF4A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00CF4A 1 ; ----------------------------------------------------------------------------
|
|
00CF4A 1 ClearPrimaryStateField: ; $CF4A
|
|
00CF4A 1 A9 23 lda #$23 ; $CF4A: A9 23
|
|
00CF4C 1 20 51 CF jsr ClearStateFieldPair ; $CF4C: 20 51 CF
|
|
00CF4F 1
|
|
00CF4F 1 A9 03 lda #$03 ; $CF4F: A9 03
|
|
00CF51 1
|
|
00CF51 1 ; ----------------------------------------------------------------------------
|
|
00CF51 1 ; Preserve the caller-supplied value in A and X.
|
|
00CF51 1 ;
|
|
00CF51 1 ; The first blank field uses destination selector $23.
|
|
00CF51 1 ; ----------------------------------------------------------------------------
|
|
00CF51 1
|
|
00CF51 1 ; ----------------------------------------------------------------------------
|
|
00CF51 1 ; Contract:
|
|
00CF51 1 ; Description: Clears or resets State Field Pair.
|
|
00CF51 1 ; Entry: Registers: A
|
|
00CF51 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00CF51 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF51 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00CF51 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF51 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF51 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00CF51 1 ; ----------------------------------------------------------------------------
|
|
00CF51 1 ClearStateFieldPair: ; $CF51
|
|
00CF51 1 48 pha ; $CF51: 48
|
|
00CF52 1 AA tax ; $CF52: AA
|
|
00CF53 1
|
|
00CF53 1 A9 23 lda #$23 ; $CF53: A9 23
|
|
00CF55 1 20 5C CF jsr QueueThreeBlanks ; $CF55: 20 5C CF
|
|
00CF58 1
|
|
00CF58 1 68 pla ; $CF58: 68
|
|
00CF59 1 AA tax ; $CF59: AA
|
|
00CF5A 1
|
|
00CF5A 1 A9 2B lda #$2B ; $CF5A: A9 2B
|
|
00CF5C 1
|
|
00CF5C 1 ; ----------------------------------------------------------------------------
|
|
00CF5C 1 ; Queue a three-character blank field.
|
|
00CF5C 1 ;
|
|
00CF5C 1 ; Entry:
|
|
00CF5C 1 ; A = destination selector/address component
|
|
00CF5C 1 ; X = caller-supplied coordinate or index
|
|
00CF5C 1 ;
|
|
00CF5C 1 ; The routine at $EA17 consumes the four inline bytes following the JSR:
|
|
00CF5C 1 ; one length byte followed by three encoded blank characters.
|
|
00CF5C 1 ; ----------------------------------------------------------------------------
|
|
00CF5C 1
|
|
00CF5C 1 ; ----------------------------------------------------------------------------
|
|
00CF5C 1 ; Contract:
|
|
00CF5C 1 ; Description: Queues Three Blanks.
|
|
00CF5C 1 ; Entry: No register input inferred
|
|
00CF5C 1 ; Returns/products: Registers/clobbers: Y; Flags: condition flags may carry result state
|
|
00CF5C 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF5C 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00CF5C 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF5C 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF5C 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CF5C 1 ; ----------------------------------------------------------------------------
|
|
00CF5C 1 QueueThreeBlanks: ; $CF5C
|
|
00CF5C 1 A0 03 ldy #$03 ; $CF5C: A0 03
|
|
00CF5E 1 18 clc ; $CF5E: 18
|
|
00CF5F 1
|
|
00CF5F 1 20 17 EA jsr CopyInlineDisplayRecord ; $CF5F: 20 17 EA
|
|
00CF62 1
|
|
00CF62 1 03 .byte $03 ; $CF62: character count
|
|
00CF63 1 25 25 25 .byte $25,$25,$25 ; $CF63-$CF65
|
|
00CF66 1
|
|
00CF66 1 60 rts ; $CF66: 60
|
|
00CF67 1
|
|
00CF67 1 ; ============================================================================
|
|
00CF67 1 ; $CF67-$CF8A
|
|
00CF67 1 ; Build a four-byte PPU queue entry using the current state in $33.
|
|
00CF67 1 ;
|
|
00CF67 1 ; The helper at $EA3E creates a four-byte queue record and returns its data
|
|
00CF67 1 ; position in X. This routine then fills the record with values derived from
|
|
00CF67 1 ; $33.
|
|
00CF67 1 ; ============================================================================
|
|
00CF67 1
|
|
00CF67 1 ; ----------------------------------------------------------------------------
|
|
00CF67 1 ; Contract:
|
|
00CF67 1 ; Description: Queues Round Number Display.
|
|
00CF67 1 ; Entry: Registers: A, Y; Memory: roundstateindex
|
|
00CF67 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CF67 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF67 1 ; Memory effects: $0300, $0301, $0302, $0303
|
|
00CF67 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF67 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF67 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CF67 1 ; ----------------------------------------------------------------------------
|
|
00CF67 1 QueueRoundNumberDisplay: ; $CF67
|
|
00CF67 1 A9 2A lda #$2A ; $CF67: A9 2A
|
|
00CF69 1 A2 82 ldx #$82 ; $CF69: A2 82
|
|
00CF6B 1 A0 04 ldy #$04 ; $CF6B: A0 04
|
|
00CF6D 1 18 clc ; $CF6D: 18
|
|
00CF6E 1
|
|
00CF6E 1 20 3E EA jsr AllocateDisplayBufferRecord ; $CF6E: 20 3E EA
|
|
00CF71 1
|
|
00CF71 1 ; ----------------------------------------------------------------------------
|
|
00CF71 1 ; Derive the first byte from half of $33, rounded upward.
|
|
00CF71 1 ;
|
|
00CF71 1 ; Y = ($33 >> 1) + 1
|
|
00CF71 1 ; ----------------------------------------------------------------------------
|
|
00CF71 1
|
|
00CF71 1 A5 33 lda RoundStateIndex ; $CF71: A5 33
|
|
00CF73 1 4A lsr ; $CF73: 4A
|
|
00CF74 1 A8 tay ; $CF74: A8
|
|
00CF75 1 C8 iny ; $CF75: C8
|
|
00CF76 1
|
|
00CF76 1 98 tya ; $CF76: 98
|
|
00CF77 1 9D 00 03 sta $0300,x ; $CF77: 9D 00 03
|
|
00CF7A 1
|
|
00CF7A 1 ; ----------------------------------------------------------------------------
|
|
00CF7A 1 ; Store $3B as the second byte.
|
|
00CF7A 1 ;
|
|
00CF7A 1 ; Carry remains clear from the preceding LSR because $33 is expected to be
|
|
00CF7A 1 ; even or within the state range used by this routine.
|
|
00CF7A 1 ; ----------------------------------------------------------------------------
|
|
00CF7A 1
|
|
00CF7A 1 A9 3B lda #$3B ; $CF7A: A9 3B
|
|
00CF7C 1 9D 01 03 sta $0301,x ; $CF7C: 9D 01 03
|
|
00CF7F 1
|
|
00CF7F 1 ; ----------------------------------------------------------------------------
|
|
00CF7F 1 ; Calculate the third byte:
|
|
00CF7F 1 ;
|
|
00CF7F 1 ; (($3B - $1C) << 1) = $3E
|
|
00CF7F 1 ;
|
|
00CF7F 1 ; SEC is not issued here. Carry from the preceding operations is intentionally
|
|
00CF7F 1 ; used by the original code.
|
|
00CF7F 1 ; ----------------------------------------------------------------------------
|
|
00CF7F 1
|
|
00CF7F 1 E9 1C sbc #$1C ; $CF7F: E9 1C
|
|
00CF81 1 0A asl ; $CF81: 0A
|
|
00CF82 1 9D 02 03 sta $0302,x ; $CF82: 9D 02 03
|
|
00CF85 1
|
|
00CF85 1 ; ----------------------------------------------------------------------------
|
|
00CF85 1 ; Calculate the fourth byte from the shifted result plus one.
|
|
00CF85 1 ; ----------------------------------------------------------------------------
|
|
00CF85 1
|
|
00CF85 1 69 01 adc #$01 ; $CF85: 69 01
|
|
00CF87 1 9D 03 03 sta $0303,x ; $CF87: 9D 03 03
|
|
00CF8A 1
|
|
00CF8A 1 60 rts ; $CF8A: 60
|
|
00CF8B 1
|
|
00CF8B 1 ; ============================================================================
|
|
00CF8B 1 ; $CF8B-$CFA5
|
|
00CF8B 1 ; Build a two-byte PPU queue entry using values selected by $34 and $35.
|
|
00CF8B 1 ;
|
|
00CF8B 1 ; The routine at $EA3E creates a two-byte queue record. The two data bytes are
|
|
00CF8B 1 ; read from the lookup table at $C024 using $34 and $35 as indices.
|
|
00CF8B 1 ; ============================================================================
|
|
00CF8B 1
|
|
00CF8B 1 ; ----------------------------------------------------------------------------
|
|
00CF8B 1 ; Contract:
|
|
00CF8B 1 ; Description: Queues Player Value Display.
|
|
00CF8B 1 ; Entry: Registers: A; Memory: playeroneselection, $c024, playertwoselection
|
|
00CF8B 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CF8B 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CF8B 1 ; Memory effects: $0300, $0301
|
|
00CF8B 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CF8B 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CF8B 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00CF8B 1 ; ----------------------------------------------------------------------------
|
|
00CF8B 1 QueuePlayerValueDisplay: ; $CF8B
|
|
00CF8B 1 A9 2A lda #$2A ; $CF8B: A9 2A
|
|
00CF8D 1 A2 A2 ldx #$A2 ; $CF8D: A2 A2
|
|
00CF8F 1 A0 02 ldy #$02 ; $CF8F: A0 02
|
|
00CF91 1
|
|
00CF91 1 38 sec ; $CF91: 38
|
|
00CF92 1 20 3E EA jsr AllocateDisplayBufferRecord ; $CF92: 20 3E EA
|
|
00CF95 1
|
|
00CF95 1 ; ----------------------------------------------------------------------------
|
|
00CF95 1 ; Select the first byte using $34.
|
|
00CF95 1 ; ----------------------------------------------------------------------------
|
|
00CF95 1
|
|
00CF95 1 A4 34 ldy PlayerOneSelection ; $CF95: A4 34
|
|
00CF97 1
|
|
00CF97 1 B9 24 C0 lda $C024,y ; $CF97: B9 24 C0
|
|
00CF9A 1 9D 00 03 sta $0300,x ; $CF9A: 9D 00 03
|
|
00CF9D 1
|
|
00CF9D 1 ; ----------------------------------------------------------------------------
|
|
00CF9D 1 ; Select the second byte using $35.
|
|
00CF9D 1 ; ----------------------------------------------------------------------------
|
|
00CF9D 1
|
|
00CF9D 1 A4 35 ldy PlayerTwoSelection ; $CF9D: A4 35
|
|
00CF9F 1
|
|
00CF9F 1 B9 24 C0 lda $C024,y ; $CF9F: B9 24 C0
|
|
00CFA2 1 9D 01 03 sta $0301,x ; $CFA2: 9D 01 03
|
|
00CFA5 1
|
|
00CFA5 1 60 rts ; $CFA5: 60
|
|
00CFA6 1
|
|
00CFA6 1 ; ============================================================================
|
|
00CFA6 1 ; $CFA6-$D01C
|
|
00CFA6 1 ; Update one of two counters, update a shared total, and build several PPU
|
|
00CFA6 1 ; queue entries representing the resulting values.
|
|
00CFA6 1 ; ============================================================================
|
|
00CFA6 1
|
|
00CFA6 1 ; ----------------------------------------------------------------------------
|
|
00CFA6 1 ; Contract:
|
|
00CFA6 1 ; Description: Updates Counters And Display.
|
|
00CFA6 1 ; Entry: Registers: A, X, Y; Memory: roundstateindex, $67, pendingscoreincrement, inningorsharedscore, playeronescore
|
|
00CFA6 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00CFA6 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00CFA6 1 ; Memory effects: $67, inningorsharedscore, $0307, $0301, $0300, $0306
|
|
00CFA6 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00CFA6 1 ; comparison, load, or store path and are not a stable API product.
|
|
00CFA6 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00CFA6 1 ; ----------------------------------------------------------------------------
|
|
00CFA6 1 UpdateCountersAndDisplay: ; $CFA6
|
|
00CFA6 1 A5 33 lda RoundStateIndex ; $CFA6: A5 33
|
|
00CFA8 1 29 01 and #$01 ; $CFA8: 29 01
|
|
00CFAA 1 AA tax ; $CFAA: AA
|
|
00CFAB 1 ; Select counter $67 or $68.
|
|
00CFAB 1
|
|
00CFAB 1 ; ----------------------------------------------------------------------------
|
|
00CFAB 1 ; Add $65 to the selected counter, saturating the result at $63.
|
|
00CFAB 1 ; ----------------------------------------------------------------------------
|
|
00CFAB 1
|
|
00CFAB 1 18 clc ; $CFAB: 18
|
|
00CFAC 1
|
|
00CFAC 1 B5 67 lda PlayerOneScore,x ; $CFAC: B5 67
|
|
00CFAE 1 65 65 adc PendingScoreIncrement ; $CFAE: 65 65
|
|
00CFB0 1
|
|
00CFB0 1 C9 64 cmp #$64 ; $CFB0: C9 64
|
|
00CFB2 1 90 02 bcc SaveSaturatedSideCounter
|
|
00CFB4 1 ; $CFB2: 90 02
|
|
00CFB4 1
|
|
00CFB4 1 A9 63 lda #$63 ; $CFB4: A9 63
|
|
00CFB6 1
|
|
00CFB6 1 SaveSaturatedSideCounter: ; $CFB6
|
|
00CFB6 1 95 67 sta PlayerOneScore,x ; $CFB6: 95 67
|
|
00CFB8 1
|
|
00CFB8 1 ; ----------------------------------------------------------------------------
|
|
00CFB8 1 ; Add $65 to the shared value at $66 and reduce it using the conversion helper
|
|
00CFB8 1 ; at $D01D.
|
|
00CFB8 1 ; ----------------------------------------------------------------------------
|
|
00CFB8 1
|
|
00CFB8 1 18 clc ; $CFB8: 18
|
|
00CFB9 1
|
|
00CFB9 1 A5 66 lda InningOrSharedScore ; $CFB9: A5 66
|
|
00CFBB 1 65 65 adc PendingScoreIncrement ; $CFBB: 65 65
|
|
00CFBD 1
|
|
00CFBD 1 20 1D D0 jsr DivideABy10 ; $CFBD: 20 1D D0
|
|
00CFC0 1 85 66 sta InningOrSharedScore ; $CFC0: 85 66
|
|
00CFC2 1
|
|
00CFC2 1 ; ----------------------------------------------------------------------------
|
|
00CFC2 1 ; Derive a PPU queue position from the selected side in X.
|
|
00CFC2 1 ;
|
|
00CFC2 1 ; The ROR sequence incorporates X's bit value into A before adding $94.
|
|
00CFC2 1 ; ----------------------------------------------------------------------------
|
|
00CFC2 1
|
|
00CFC2 1 B5 67 lda PlayerOneScore,x ; $CFC2: B5 67
|
|
00CFC4 1 48 pha ; $CFC4: 48
|
|
00CFC5 1
|
|
00CFC5 1 8A txa ; $CFC5: 8A
|
|
00CFC6 1 4A lsr ; $CFC6: 4A
|
|
00CFC7 1 6A ror ; $CFC7: 6A
|
|
00CFC8 1 6A ror ; $CFC8: 6A
|
|
00CFC9 1 6A ror ; $CFC9: 6A
|
|
00CFCA 1
|
|
00CFCA 1 69 94 adc #$94 ; $CFCA: 69 94
|
|
00CFCC 1 AA tax ; $CFCC: AA
|
|
00CFCD 1
|
|
00CFCD 1 ; ----------------------------------------------------------------------------
|
|
00CFCD 1 ; Create a two-byte PPU queue entry.
|
|
00CFCD 1 ; ----------------------------------------------------------------------------
|
|
00CFCD 1
|
|
00CFCD 1 A9 20 lda #$20 ; $CFCD: A9 20
|
|
00CFCF 1 A0 02 ldy #$02 ; $CFCF: A0 02
|
|
00CFD1 1
|
|
00CFD1 1 20 3E EA jsr AllocateDisplayBufferRecord ; $CFD1: 20 3E EA
|
|
00CFD4 1
|
|
00CFD4 1 ; ----------------------------------------------------------------------------
|
|
00CFD4 1 ; Convert the selected counter into display digits.
|
|
00CFD4 1 ;
|
|
00CFD4 1 ; Routine $D01D returns:
|
|
00CFD4 1 ; A = remainder/digit-like value
|
|
00CFD4 1 ; Y = quotient-like value
|
|
00CFD4 1 ; ----------------------------------------------------------------------------
|
|
00CFD4 1
|
|
00CFD4 1 68 pla ; $CFD4: 68
|
|
00CFD5 1 20 1D D0 jsr DivideABy10 ; $CFD5: 20 1D D0
|
|
00CFD8 1
|
|
00CFD8 1 9D 07 03 sta $0307,x ; $CFD8: 9D 07 03
|
|
00CFDB 1
|
|
00CFDB 1 69 27 adc #$27 ; $CFDB: 69 27
|
|
00CFDD 1 9D 01 03 sta $0301,x ; $CFDD: 9D 01 03
|
|
00CFE0 1
|
|
00CFE0 1 ; ----------------------------------------------------------------------------
|
|
00CFE0 1 ; Build the associated leading digit or blank character.
|
|
00CFE0 1 ; ----------------------------------------------------------------------------
|
|
00CFE0 1
|
|
00CFE0 1 98 tya ; $CFE0: 98
|
|
00CFE1 1 F0 04 beq BlankLeadingCounterDigit
|
|
00CFE3 1 ; $CFE1: F0 04
|
|
00CFE3 1
|
|
00CFE3 1 69 28 adc #$28 ; $CFE3: 69 28
|
|
00CFE5 1 D0 04 bne StoreCounterDisplayDigits ; $CFE5: D0 04
|
|
00CFE7 1 ; Always taken for the expected input range.
|
|
00CFE7 1
|
|
00CFE7 1 BlankLeadingCounterDigit: ; $CFE7
|
|
00CFE7 1 A0 25 ldy #$25 ; $CFE7: A0 25
|
|
00CFE9 1 ; Encoded blank character.
|
|
00CFE9 1
|
|
00CFE9 1 A9 33 lda #$33 ; $CFE9: A9 33
|
|
00CFEB 1
|
|
00CFEB 1 StoreCounterDisplayDigits: ; $CFEB
|
|
00CFEB 1 9D 00 03 sta $0300,x ; $CFEB: 9D 00 03
|
|
00CFEE 1
|
|
00CFEE 1 98 tya ; $CFEE: 98
|
|
00CFEF 1 9D 06 03 sta $0306,x ; $CFEF: 9D 06 03
|
|
00CFF2 1
|
|
00CFF2 1 ; ----------------------------------------------------------------------------
|
|
00CFF2 1 ; Build a second two-byte queue entry selected by the low bit of $33.
|
|
00CFF2 1 ; ----------------------------------------------------------------------------
|
|
00CFF2 1
|
|
00CFF2 1 A5 33 lda RoundStateIndex ; $CFF2: A5 33
|
|
00CFF4 1 4A lsr ; $CFF4: 4A
|
|
00CFF5 1
|
|
00CFF5 1 A9 A4 lda #$A4 ; $CFF5: A9 A4
|
|
00CFF7 1 90 02 bcc SelectPlayerDisplayQueueOffset ; $CFF7: 90 02
|
|
00CFF9 1
|
|
00CFF9 1 69 1F adc #$1F ; $CFF9: 69 1F
|
|
00CFFB 1
|
|
00CFFB 1 SelectPlayerDisplayQueueOffset: ; $CFFB
|
|
00CFFB 1 AA tax ; $CFFB: AA
|
|
00CFFC 1
|
|
00CFFC 1 A9 2A lda #$2A ; $CFFC: A9 2A
|
|
00CFFE 1 A0 02 ldy #$02 ; $CFFE: A0 02
|
|
00D000 1 18 clc ; $D000: 18
|
|
00D001 1
|
|
00D001 1 20 3E EA jsr AllocateDisplayBufferRecord ; $D001: 20 3E EA
|
|
00D004 1
|
|
00D004 1 ; ----------------------------------------------------------------------------
|
|
00D004 1 ; Build a final one-byte queue entry.
|
|
00D004 1 ; ----------------------------------------------------------------------------
|
|
00D004 1
|
|
00D004 1 A5 33 lda RoundStateIndex ; $D004: A5 33
|
|
00D006 1 4A lsr ; $D006: 4A
|
|
00D007 1 90 02 bcc SelectSharedCounterQueueOffset ; $D007: 90 02
|
|
00D009 1
|
|
00D009 1 69 1F adc #$1F ; $D009: 69 1F
|
|
00D00B 1
|
|
00D00B 1 SelectSharedCounterQueueOffset: ; $D00B
|
|
00D00B 1 69 8B adc #$8B ; $D00B: 69 8B
|
|
00D00D 1 AA tax ; $D00D: AA
|
|
00D00E 1
|
|
00D00E 1 A9 20 lda #$20 ; $D00E: A9 20
|
|
00D010 1 A0 01 ldy #$01 ; $D010: A0 01
|
|
00D012 1
|
|
00D012 1 20 3E EA jsr AllocateDisplayBufferRecord ; $D012: 20 3E EA
|
|
00D015 1
|
|
00D015 1 A5 66 lda InningOrSharedScore ; $D015: A5 66
|
|
00D017 1 69 28 adc #$28 ; $D017: 69 28
|
|
00D019 1 9D 00 03 sta $0300,x ; $D019: 9D 00 03
|
|
00D01C 1
|
|
00D01C 1 60 rts ; $D01C: 60
|
|
00D01D 1
|
|
00D01D 1 ; ============================================================================
|
|
00D01D 1 ; $D01D-$D027
|
|
00D01D 1 ; Divide an unsigned 8-bit value by ten.
|
|
00D01D 1 ;
|
|
00D01D 1 ; Entry:
|
|
00D01D 1 ; A = unsigned value to divide
|
|
00D01D 1 ;
|
|
00D01D 1 ; Exit:
|
|
00D01D 1 ; A = remainder, range $00-$09
|
|
00D01D 1 ; Y = quotient
|
|
00D01D 1 ;
|
|
00D01D 1 ; The routine repeatedly subtracts ten until the subtraction underflows,
|
|
00D01D 1 ; then adds ten back to restore the nonnegative remainder.
|
|
00D01D 1 ; ============================================================================
|
|
00D01D 1
|
|
00D01D 1 ; ----------------------------------------------------------------------------
|
|
00D01D 1 ; Contract:
|
|
00D01D 1 ; Description: Implements Divide A By 1 0.
|
|
00D01D 1 ; Entry: Registers: A, Y
|
|
00D01D 1 ; Returns/products: Registers/clobbers: A, Y; Flags: condition flags may carry result state
|
|
00D01D 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00D01D 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00D01D 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00D01D 1 ; comparison, load, or store path and are not a stable API product.
|
|
00D01D 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 4.
|
|
00D01D 1 ; ----------------------------------------------------------------------------
|
|
00D01D 1 DivideABy10: ; $D01D
|
|
00D01D 1 A0 FF ldy #$FF ; $D01D: A0 FF
|
|
00D01F 1 ; The first INY changes this to zero.
|
|
00D01F 1
|
|
00D01F 1 Routine_D01F_SubtractTen: ; $D01F
|
|
00D01F 1 38 sec ; $D01F: 38
|
|
00D020 1 E9 0A sbc #$0A ; $D020: E9 0A
|
|
00D022 1
|
|
00D022 1 C8 iny ; $D022: C8
|
|
00D023 1 B0 FA bcs Routine_D01F_SubtractTen
|
|
00D025 1 ; $D023: B0 FA
|
|
00D025 1
|
|
00D025 1 69 0A adc #$0A ; $D025: 69 0A
|
|
00D027 1 ; Carry is clear after the failed subtraction,
|
|
00D027 1 ; so this restores the remainder without an
|
|
00D027 1 ; extra increment.
|
|
00D027 1
|
|
00D027 1 60 rts ; $D027: 60
|
|
00D028 1
|
|
00D028 1 ; ============================================================================
|
|
00D028 1 ; $D028-$D068
|
|
00D028 1 ; Display and format the value at $71.
|
|
00D028 1 ; ============================================================================
|
|
00D028 1
|
|
00D028 1 DisplaySharedCounter: ; $D028
|
|
00D028 1 18 clc ; $D028: 18
|
|
00D029 1
|
|
00D029 1 A9 2A lda #$2A ; $D029: A9 2A
|
|
00D02B 1 A2 2D ldx #$2D ; $D02B: A2 2D
|
|
00D02D 1 A0 05 ldy #$05 ; $D02D: A0 05
|
|
00D02F 1
|
|
00D02F 1 20 17 EA jsr CopyInlineDisplayRecord ; $D02F: 20 17 EA
|
|
00D032 1
|
|
00D032 1 05 .byte $05 ; $D032
|
|
00D033 1 25 25 25 39 .byte $25,$25,$25,$39,$3A ; $D033-$D037
|
|
00D037 1 3A
|
|
00D038 1
|
|
00D038 1 A5 71 lda DisplayCounterValue ; $D038: A5 71
|
|
00D03A 1 C9 64 cmp #$64 ; $D03A: C9 64
|
|
00D03C 1 90 09 bcc ConvertSharedCounterToDigits ; $D03C: 90 09
|
|
00D03E 1
|
|
00D03E 1 A9 01 lda #$01 ; $D03E: A9 01
|
|
00D040 1 9D FB 02 sta $02FB,x ; $D040: 9D FB 02
|
|
00D043 1
|
|
00D043 1 A5 71 lda DisplayCounterValue ; $D043: A5 71
|
|
00D045 1 E9 64 sbc #$64 ; $D045: E9 64
|
|
00D047 1
|
|
00D047 1 ConvertSharedCounterToDigits: ; $D047
|
|
00D047 1 20 1D D0 jsr DivideABy10 ; $D047: 20 1D D0
|
|
00D04A 1
|
|
00D04A 1 9D FD 02 sta $02FD,x ; $D04A: 9D FD 02
|
|
00D04D 1
|
|
00D04D 1 98 tya ; $D04D: 98
|
|
00D04E 1 9D FC 02 sta $02FC,x ; $D04E: 9D FC 02
|
|
00D051 1
|
|
00D051 1 A9 5A lda #$5A ; $D051: A9 5A
|
|
00D053 1 20 41 EB jsr StoreObjectEventBankValue ; $D053: 20 41 EB
|
|
00D056 1
|
|
00D056 1 18 clc ; $D056: 18
|
|
00D057 1
|
|
00D057 1 A9 2A lda #$2A ; $D057: A9 2A
|
|
00D059 1 A2 2D ldx #$2D ; $D059: A2 2D
|
|
00D05B 1 A0 05 ldy #$05 ; $D05B: A0 05
|
|
00D05D 1
|
|
00D05D 1 20 17 EA jsr CopyInlineDisplayRecord ; $D05D: 20 17 EA
|
|
00D060 1
|
|
00D060 1 05 .byte $05 ; $D060
|
|
00D061 1 26 26 26 26 .byte $26,$26,$26,$26,$26 ; $D061-$D065
|
|
00D065 1 26
|
|
00D066 1
|
|
00D066 1 4C 6A EB jmp CommonEngineExit ; $D066: 4C 6A EB
|
|
00D069 1
|
|
00D069 1 ; ============================================================================
|
|
00D069 1 ; $D069-$D09F
|
|
00D069 1 ; Initialize object position and sprite fields from the structured table at
|
|
00D069 1 ; $D0A0.
|
|
00D069 1 ;
|
|
00D069 1 ; Two entry points exist:
|
|
00D069 1 ;
|
|
00D069 1 ; $D069 initializes A to $23 before using it as the initial table offset.
|
|
00D069 1 ; $D06B uses the caller-supplied A value as the initial table offset.
|
|
00D069 1 ;
|
|
00D069 1 ; Table records are seven bytes long. A zero byte in ObjectInitializationTable,Y terminates
|
|
00D069 1 ; the record list.
|
|
00D069 1 ; ============================================================================
|
|
00D069 1
|
|
00D069 1 ; ----------------------------------------------------------------------------
|
|
00D069 1 ; Contract:
|
|
00D069 1 ; Description: Initializes Default Objects.
|
|
00D069 1 ; Entry: Registers: A, X, Y; Memory: objectinitializationtable, objectinitxlowfield, objectinitxhighfield, objectinitylowfield, objectinityhighfield, objectinitframefield, objectinitattributefield
|
|
00D069 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00D069 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00D069 1 ; Memory effects: $0509, $050a, $053a, $053b, $039b, $03b0
|
|
00D069 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00D069 1 ; comparison, load, or store path and are not a stable API product.
|
|
00D069 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00D069 1 ; ----------------------------------------------------------------------------
|
|
00D069 1 InitializeDefaultObjects: ; $D069
|
|
00D069 1 A9 23 lda #$23 ; $D069: A9 23
|
|
00D06B 1
|
|
00D06B 1 ; ----------------------------------------------------------------------------
|
|
00D06B 1 ; Secondary entry point.
|
|
00D06B 1 ;
|
|
00D06B 1 ; Entry:
|
|
00D06B 1 ; A = initial offset into ObjectInitializationTable
|
|
00D06B 1 ; ----------------------------------------------------------------------------
|
|
00D06B 1
|
|
00D06B 1 ; ----------------------------------------------------------------------------
|
|
00D06B 1 ; Contract:
|
|
00D06B 1 ; Description: Initializes Objects From Table.
|
|
00D06B 1 ; Entry: Registers: A, X, Y; Memory: objectinitializationtable, objectinitxlowfield, objectinitxhighfield, objectinitylowfield, objectinityhighfield, objectinitframefield, objectinitattributefield
|
|
00D06B 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00D06B 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00D06B 1 ; Memory effects: $0509, $050a, $053a, $053b, $039b, $03b0
|
|
00D06B 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00D06B 1 ; comparison, load, or store path and are not a stable API product.
|
|
00D06B 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00D06B 1 ; ----------------------------------------------------------------------------
|
|
00D06B 1 InitializeObjectsFromTable: ; $D06B
|
|
00D06B 1 A8 tay ; $D06B: A8
|
|
00D06C 1
|
|
00D06C 1 InitializeNextObjectRecord: ; $D06C
|
|
00D06C 1 BE A0 D0 ldx ObjectInitializationTable,y ; $D06C: BE A0 D0
|
|
00D06F 1 F0 2E beq ObjectInitializationReturn ; $D06F: F0 2E
|
|
00D071 1
|
|
00D071 1 ; ----------------------------------------------------------------------------
|
|
00D071 1 ; Copy four position bytes from the table into the object arrays selected by X.
|
|
00D071 1 ; ----------------------------------------------------------------------------
|
|
00D071 1
|
|
00D071 1 B9 A3 D0 lda ObjectInitXLowField,y ; $D071: B9 A3 D0
|
|
00D074 1 9D 09 05 sta $0509,x ; $D074: 9D 09 05
|
|
00D077 1
|
|
00D077 1 B9 A4 D0 lda ObjectInitXHighField,y ; $D077: B9 A4 D0
|
|
00D07A 1 9D 0A 05 sta $050A,x ; $D07A: 9D 0A 05
|
|
00D07D 1
|
|
00D07D 1 B9 A5 D0 lda ObjectInitYLowField,y ; $D07D: B9 A5 D0
|
|
00D080 1 9D 3A 05 sta $053A,x ; $D080: 9D 3A 05
|
|
00D083 1
|
|
00D083 1 B9 A6 D0 lda ObjectInitYHighField,y ; $D083: B9 A6 D0
|
|
00D086 1 9D 3B 05 sta $053B,x ; $D086: 9D 3B 05
|
|
00D089 1
|
|
00D089 1 ; ----------------------------------------------------------------------------
|
|
00D089 1 ; Convert the object-array offset into the associated sprite-array index.
|
|
00D089 1 ; ----------------------------------------------------------------------------
|
|
00D089 1
|
|
00D089 1 8A txa ; $D089: 8A
|
|
00D08A 1 4A lsr ; $D08A: 4A
|
|
00D08B 1 AA tax ; $D08B: AA
|
|
00D08C 1
|
|
00D08C 1 ; ----------------------------------------------------------------------------
|
|
00D08C 1 ; Copy the sprite tile/frame value.
|
|
00D08C 1 ; ----------------------------------------------------------------------------
|
|
00D08C 1
|
|
00D08C 1 B9 A1 D0 lda ObjectInitFrameField,y ; $D08C: B9 A1 D0
|
|
00D08F 1 9D 9B 03 sta $039B,x ; $D08F: 9D 9B 03
|
|
00D092 1
|
|
00D092 1 ; ----------------------------------------------------------------------------
|
|
00D092 1 ; Copy the optional sprite attribute/value when it is nonzero.
|
|
00D092 1 ; ----------------------------------------------------------------------------
|
|
00D092 1
|
|
00D092 1 B9 A2 D0 lda ObjectInitAttributeField,y ; $D092: B9 A2 D0
|
|
00D095 1 F0 03 beq AdvanceObjectInitRecord ; $D095: F0 03
|
|
00D097 1
|
|
00D097 1 9D B0 03 sta $03B0,x ; $D097: 9D B0 03
|
|
00D09A 1
|
|
00D09A 1 ; ----------------------------------------------------------------------------
|
|
00D09A 1 ; Advance to the next seven-byte record.
|
|
00D09A 1 ;
|
|
00D09A 1 ; Carry is expected to be clear after the table and store operations.
|
|
00D09A 1 ; ----------------------------------------------------------------------------
|
|
00D09A 1
|
|
00D09A 1 AdvanceObjectInitRecord: ; $D09A
|
|
00D09A 1 98 tya ; $D09A: 98
|
|
00D09B 1 69 07 adc #$07 ; $D09B: 69 07
|
|
00D09D 1 D0 CC bne InitializeObjectsFromTable ; $D09D: D0 CC
|
|
00D09F 1 ; Effectively loops until a terminating record.
|
|
00D09F 1
|
|
00D09F 1 ObjectInitializationReturn: ; $D09F
|
|
00D09F 1 60 rts ; $D09F: 60
|
|
00D0A0 1
|
|
00D0A0 1 ; ============================================================================
|
|
00D0A0 1 ; Structured seven-byte object table begins at CPU $D0A0.
|
|
00D0A0 1 ;
|
|
00D0A0 1 ; Record format inferred during the first pass:
|
|
00D0A0 1 ;
|
|
00D0A0 1 ; +0 object-array offset
|
|
00D0A0 1 ; +1 sprite tile/frame
|
|
00D0A0 1 ; +2 optional sprite attribute/value
|
|
00D0A0 1 ; +3 $0509,X
|
|
00D0A0 1 ; +4 $050A,X
|
|
00D0A0 1 ; +5 $053A,X
|
|
00D0A0 1 ; +6 $053B,X
|
|
00D0A0 1 ; ============================================================================
|
|
00D0A0 1
|
|
00D0A0 1 ; ============================================================================
|
|
00D0A0 1 ; $D0A0-$D125
|
|
00D0A0 1 ; Object initialization table used by InitializeDefaultObjects/InitializeObjectsFromTable.
|
|
00D0A0 1 ;
|
|
00D0A0 1 ; Each record is seven bytes:
|
|
00D0A0 1 ;
|
|
00D0A0 1 ; +0 object-array offset in X
|
|
00D0A0 1 ; +1 value stored at $039B,(X / 2)
|
|
00D0A0 1 ; +2 optional value stored at $03B0,(X / 2)
|
|
00D0A0 1 ; +3 value stored at $0509,X
|
|
00D0A0 1 ; +4 value stored at $050A,X
|
|
00D0A0 1 ; +5 value stored at $053A,X
|
|
00D0A0 1 ; +6 value stored at $053B,X
|
|
00D0A0 1 ;
|
|
00D0A0 1 ; A zero object-array offset terminates the table.
|
|
00D0A0 1 ; ============================================================================
|
|
00D0A0 1
|
|
00D0A0 1 ObjectInitializationTable:
|
|
00D0A0 1
|
|
00D0A0 1 ; ----------------------------------------------------------------------------
|
|
00D0A0 1 ; Record 0
|
|
00D0A0 1 ;
|
|
00D0A0 1 ; Object offset: $06
|
|
00D0A0 1 ; Sprite index: $03
|
|
00D0A0 1 ; ----------------------------------------------------------------------------
|
|
00D0A0 1
|
|
00D0A0 1 ObjectInit_D0A0: ; $D0A0
|
|
00D0A0 1 06 .byte $06 ; Object-array offset
|
|
00D0A1 1 7A .byte $7A ; $039B + (X / 2)
|
|
00D0A2 1 7A .byte $7A ; $03B0 + (X / 2)
|
|
00D0A3 1 CD FE .byte $CD,$FE ; $0509/$050A
|
|
00D0A5 1 4C F8 .byte $4C,$F8 ; $053A/$053B
|
|
00D0A7 1
|
|
00D0A7 1 ; ----------------------------------------------------------------------------
|
|
00D0A7 1 ; Record 1
|
|
00D0A7 1 ; ----------------------------------------------------------------------------
|
|
00D0A7 1
|
|
00D0A7 1 ObjectInit_D0A7: ; $D0A7
|
|
00D0A7 1 08 .byte $08
|
|
00D0A8 1 7A .byte $7A
|
|
00D0A9 1 7A .byte $7A
|
|
00D0AA 1 00 FC .byte $00,$FC
|
|
00D0AC 1 00 F7 .byte $00,$F7
|
|
00D0AE 1
|
|
00D0AE 1 ; ----------------------------------------------------------------------------
|
|
00D0AE 1 ; Record 2
|
|
00D0AE 1 ; ----------------------------------------------------------------------------
|
|
00D0AE 1
|
|
00D0AE 1 ObjectInit_D0AE: ; $D0AE
|
|
00D0AE 1 0A .byte $0A
|
|
00D0AF 1 7A .byte $7A
|
|
00D0B0 1 7A .byte $7A
|
|
00D0B1 1 00 FB .byte $00,$FB
|
|
00D0B3 1 00 F7 .byte $00,$F7
|
|
00D0B5 1
|
|
00D0B5 1 ; ----------------------------------------------------------------------------
|
|
00D0B5 1 ; Record 3
|
|
00D0B5 1 ; ----------------------------------------------------------------------------
|
|
00D0B5 1
|
|
00D0B5 1 ObjectInit_D0B5: ; $D0B5
|
|
00D0B5 1 0C .byte $0C
|
|
00D0B6 1 7A .byte $7A
|
|
00D0B7 1 7A .byte $7A
|
|
00D0B8 1 00 FA .byte $00,$FA
|
|
00D0BA 1 00 F7 .byte $00,$F7
|
|
00D0BC 1
|
|
00D0BC 1 ; ----------------------------------------------------------------------------
|
|
00D0BC 1 ; Record 4
|
|
00D0BC 1 ; ----------------------------------------------------------------------------
|
|
00D0BC 1
|
|
00D0BC 1 ObjectInit_D0BC: ; $D0BC
|
|
00D0BC 1 02 .byte $02
|
|
00D0BD 1 6E .byte $6E
|
|
00D0BE 1 47 .byte $47
|
|
00D0BF 1 00 00 .byte $00,$00
|
|
00D0C1 1 C0 F6 .byte $C0,$F6
|
|
00D0C3 1
|
|
00D0C3 1 ; ----------------------------------------------------------------------------
|
|
00D0C3 1 ; Record 5
|
|
00D0C3 1 ; ----------------------------------------------------------------------------
|
|
00D0C3 1
|
|
00D0C3 1 ObjectInit_D0C3: ; $D0C3
|
|
00D0C3 1 04 .byte $04
|
|
00D0C4 1 59 .byte $59
|
|
00D0C5 1 11 .byte $11
|
|
00D0C6 1 00 00 .byte $00,$00
|
|
00D0C8 1 22 F7 .byte $22,$F7
|
|
00D0CA 1
|
|
00D0CA 1 ; ----------------------------------------------------------------------------
|
|
00D0CA 1 ; Record 6
|
|
00D0CA 1 ; ----------------------------------------------------------------------------
|
|
00D0CA 1
|
|
00D0CA 1 ObjectInit_D0CA: ; $D0CA
|
|
00D0CA 1 0E .byte $0E
|
|
00D0CB 1 5B .byte $5B
|
|
00D0CC 1 08 .byte $08
|
|
00D0CD 1 00 00 .byte $00,$00
|
|
00D0CF 1 48 02 .byte $48,$02
|
|
00D0D1 1
|
|
00D0D1 1 ; ----------------------------------------------------------------------------
|
|
00D0D1 1 ; Record 7
|
|
00D0D1 1 ; ----------------------------------------------------------------------------
|
|
00D0D1 1
|
|
00D0D1 1 ObjectInit_D0D1: ; $D0D1
|
|
00D0D1 1 10 .byte $10
|
|
00D0D2 1 5B .byte $5B
|
|
00D0D3 1 2F .byte $2F
|
|
00D0D4 1 00 08 .byte $00,$08
|
|
00D0D6 1 00 05 .byte $00,$05
|
|
00D0D8 1
|
|
00D0D8 1 ; ----------------------------------------------------------------------------
|
|
00D0D8 1 ; Record 8
|
|
00D0D8 1 ; ----------------------------------------------------------------------------
|
|
00D0D8 1
|
|
00D0D8 1 ObjectInit_D0D8: ; $D0D8
|
|
00D0D8 1 12 .byte $12
|
|
00D0D9 1 5B .byte $5B
|
|
00D0DA 1 2F .byte $2F
|
|
00D0DB 1 00 04 .byte $00,$04
|
|
00D0DD 1 00 09 .byte $00,$09
|
|
00D0DF 1
|
|
00D0DF 1 ; ----------------------------------------------------------------------------
|
|
00D0DF 1 ; Record 9
|
|
00D0DF 1 ; ----------------------------------------------------------------------------
|
|
00D0DF 1
|
|
00D0DF 1 ObjectInit_D0DF: ; $D0DF
|
|
00D0DF 1 14 .byte $14
|
|
00D0E0 1 5B .byte $5B
|
|
00D0E1 1 2F .byte $2F
|
|
00D0E2 1 00 FC .byte $00,$FC
|
|
00D0E4 1 00 09 .byte $00,$09
|
|
00D0E6 1
|
|
00D0E6 1 ; ----------------------------------------------------------------------------
|
|
00D0E6 1 ; Record 10
|
|
00D0E6 1 ; ----------------------------------------------------------------------------
|
|
00D0E6 1
|
|
00D0E6 1 ObjectInit_D0E6: ; $D0E6
|
|
00D0E6 1 16 .byte $16
|
|
00D0E7 1 5B .byte $5B
|
|
00D0E8 1 2F .byte $2F
|
|
00D0E9 1 00 F8 .byte $00,$F8
|
|
00D0EB 1 00 05 .byte $00,$05
|
|
00D0ED 1
|
|
00D0ED 1 ; ----------------------------------------------------------------------------
|
|
00D0ED 1 ; Record 11
|
|
00D0ED 1 ; ----------------------------------------------------------------------------
|
|
00D0ED 1
|
|
00D0ED 1 ObjectInit_D0ED: ; $D0ED
|
|
00D0ED 1 18 .byte $18
|
|
00D0EE 1 69 .byte $69
|
|
00D0EF 1 00 .byte $00 ; Optional $03B0 value is not written
|
|
00D0F0 1 00 0B .byte $00,$0B
|
|
00D0F2 1 00 01 .byte $00,$01
|
|
00D0F4 1
|
|
00D0F4 1 ; ----------------------------------------------------------------------------
|
|
00D0F4 1 ; Record 12
|
|
00D0F4 1 ; ----------------------------------------------------------------------------
|
|
00D0F4 1
|
|
00D0F4 1 ObjectInit_D0F4: ; $D0F4
|
|
00D0F4 1 1A .byte $1A
|
|
00D0F5 1 69 .byte $69
|
|
00D0F6 1 00 .byte $00
|
|
00D0F7 1 00 01 .byte $00,$01
|
|
00D0F9 1 00 0A .byte $00,$0A
|
|
00D0FB 1
|
|
00D0FB 1 ; ----------------------------------------------------------------------------
|
|
00D0FB 1 ; Record 13
|
|
00D0FB 1 ; ----------------------------------------------------------------------------
|
|
00D0FB 1
|
|
00D0FB 1 ObjectInit_D0FB: ; $D0FB
|
|
00D0FB 1 1C .byte $1C
|
|
00D0FC 1 69 .byte $69
|
|
00D0FD 1 00 .byte $00
|
|
00D0FE 1 00 F5 .byte $00,$F5
|
|
00D100 1 00 01 .byte $00,$01
|
|
00D102 1
|
|
00D102 1 ; ----------------------------------------------------------------------------
|
|
00D102 1 ; Record 14
|
|
00D102 1 ; ----------------------------------------------------------------------------
|
|
00D102 1
|
|
00D102 1 ObjectInit_D102: ; $D102
|
|
00D102 1 1E .byte $1E
|
|
00D103 1 67 .byte $67
|
|
00D104 1 00 .byte $00
|
|
00D105 1 00 0C .byte $00,$0C
|
|
00D107 1 00 12 .byte $00,$12
|
|
00D109 1
|
|
00D109 1 ; ----------------------------------------------------------------------------
|
|
00D109 1 ; Record 15
|
|
00D109 1 ; ----------------------------------------------------------------------------
|
|
00D109 1
|
|
00D109 1 ObjectInit_D109: ; $D109
|
|
00D109 1 20 .byte $20
|
|
00D10A 1 67 .byte $67
|
|
00D10B 1 00 .byte $00
|
|
00D10C 1 00 00 .byte $00,$00
|
|
00D10E 1 00 17 .byte $00,$17
|
|
00D110 1
|
|
00D110 1 ; ----------------------------------------------------------------------------
|
|
00D110 1 ; Record 16
|
|
00D110 1 ; ----------------------------------------------------------------------------
|
|
00D110 1
|
|
00D110 1 ObjectInit_D110: ; $D110
|
|
00D110 1 22 .byte $22
|
|
00D111 1 67 .byte $67
|
|
00D112 1 00 .byte $00
|
|
00D113 1 00 F4 .byte $00,$F4
|
|
00D115 1 00 12 .byte $00,$12
|
|
00D117 1
|
|
00D117 1 ; ----------------------------------------------------------------------------
|
|
00D117 1 ; Record 17
|
|
00D117 1 ; ----------------------------------------------------------------------------
|
|
00D117 1
|
|
00D117 1 ObjectInit_D117: ; $D117
|
|
00D117 1 24 .byte $24
|
|
00D118 1 69 .byte $69
|
|
00D119 1 00 .byte $00
|
|
00D11A 1 00 13 .byte $00,$13
|
|
00D11C 1 00 0B .byte $00,$0B
|
|
00D11E 1
|
|
00D11E 1 ; ----------------------------------------------------------------------------
|
|
00D11E 1 ; Record 18
|
|
00D11E 1 ; ----------------------------------------------------------------------------
|
|
00D11E 1
|
|
00D11E 1 ObjectInit_D11E: ; $D11E
|
|
00D11E 1 26 .byte $26
|
|
00D11F 1 69 .byte $69
|
|
00D120 1 00 .byte $00
|
|
00D121 1 00 ED .byte $00,$ED
|
|
00D123 1 00 0B .byte $00,$0B
|
|
00D125 1
|
|
00D125 1 ; ----------------------------------------------------------------------------
|
|
00D125 1 ; Table terminator
|
|
00D125 1 ; ----------------------------------------------------------------------------
|
|
00D125 1
|
|
00D125 1 ObjectInitTable_End: ; $D125
|
|
00D125 1 00 .byte $00
|
|
00D126 1
|
|
00D126 1 ; ============================================================================
|
|
00D126 1 ; Field aliases used by the table-reading routine.
|
|
00D126 1 ;
|
|
00D126 1 ; These labels correspond to fields in the first record. Indexed accesses use
|
|
00D126 1 ; Y as the record offset, so the same labels describe every seven-byte record.
|
|
00D126 1 ; ============================================================================
|
|
00D126 1
|
|
00D126 1 ObjectInitFrameField = ObjectInitializationTable + 1
|
|
00D126 1 ObjectInitAttributeField = ObjectInitializationTable + 2
|
|
00D126 1 ObjectInitXLowField = ObjectInitializationTable + 3
|
|
00D126 1 ObjectInitXHighField = ObjectInitializationTable + 4
|
|
00D126 1 ObjectInitYLowField = ObjectInitializationTable + 5
|
|
00D126 1 ObjectInitYHighField = ObjectInitializationTable + 6
|
|
00D126 1
|
|
00D126 1 ; ============================================================================
|
|
00D126 1 ; $D126-$D14A
|
|
00D126 1 ; Conditionally initialize object fields and an animation value.
|
|
00D126 1 ;
|
|
00D126 1 ; The routine checks the signed state bytes at $0599 and $059A. Processing
|
|
00D126 1 ; continues only when:
|
|
00D126 1 ;
|
|
00D126 1 ; $0599 is nonnegative
|
|
00D126 1 ; $059A is negative
|
|
00D126 1 ;
|
|
00D126 1 ; Otherwise, the routine returns immediately.
|
|
00D126 1 ; ============================================================================
|
|
00D126 1
|
|
00D126 1 ; ----------------------------------------------------------------------------
|
|
00D126 1 ; Contract:
|
|
00D126 1 ; Description: Initializes Conditional Object.
|
|
00D126 1 ; Entry: Registers: A, X; Memory: $0599, $059a
|
|
00D126 1 ; Returns/products: Registers/clobbers: A, X
|
|
00D126 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00D126 1 ; Memory effects: objectselectionlowerbound, $03b8
|
|
00D126 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00D126 1 ; comparison, load, or store path and are not a stable API product.
|
|
00D126 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00D126 1 ; ----------------------------------------------------------------------------
|
|
00D126 1 InitializeConditionalObject: ; $D126
|
|
00D126 1 A9 00 lda #$00 ; $D126: A9 00
|
|
00D128 1 85 A5 sta ObjectSelectionLowerBound ; $D128: 85 A5
|
|
00D12A 1
|
|
00D12A 1 ; ----------------------------------------------------------------------------
|
|
00D12A 1 ; Return if $0599 is negative.
|
|
00D12A 1 ; ----------------------------------------------------------------------------
|
|
00D12A 1
|
|
00D12A 1 AD 99 05 lda $0599 ; $D12A: AD 99 05
|
|
00D12D 1 30 1B bmi ConditionalObjectInitReturn ; $D12D: 30 1B
|
|
00D12F 1
|
|
00D12F 1 ; ----------------------------------------------------------------------------
|
|
00D12F 1 ; Return if $059A is nonnegative.
|
|
00D12F 1 ; ----------------------------------------------------------------------------
|
|
00D12F 1
|
|
00D12F 1 AD 9A 05 lda $059A ; $D12F: AD 9A 05
|
|
00D132 1 10 16 bpl ConditionalObjectInitReturn ; $D132: 10 16
|
|
00D134 1
|
|
00D134 1 ; ----------------------------------------------------------------------------
|
|
00D134 1 ; Initialize indexed object fields.
|
|
00D134 1 ;
|
|
00D134 1 ; Routine $C9A7 consumes the five bytes immediately following the JSR:
|
|
00D134 1 ;
|
|
00D134 1 ; $10 inline metadata/object offset
|
|
00D134 1 ; $00,$07,$00,$00 four field values
|
|
00D134 1 ;
|
|
00D134 1 ; Based on Routine_C9A7, the four field bytes are stored into:
|
|
00D134 1 ;
|
|
00D134 1 ; $0509,X = $00
|
|
00D134 1 ; $050A,X = $07
|
|
00D134 1 ; $053A,X = $00
|
|
00D134 1 ; $053B,X = $00
|
|
00D134 1 ; ============================================================================
|
|
00D134 1
|
|
00D134 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D137 1 ; $D134: 20 A7 C9
|
|
00D137 1
|
|
00D137 1 10 .byte $10 ; $D137: inline metadata/object offset
|
|
00D138 1 00 07 00 00 .byte $00,$07,$00,$00 ; $D138-$D13B: field data
|
|
00D13C 1
|
|
00D13C 1 ; ----------------------------------------------------------------------------
|
|
00D13C 1 ; Set the working value at $A5, then run the indexed helper at $E6B7.
|
|
00D13C 1 ; ----------------------------------------------------------------------------
|
|
00D13C 1
|
|
00D13C 1 A2 10 ldx #$10 ; $D13C: A2 10
|
|
00D13E 1 86 A5 stx ObjectSelectionLowerBound ; $D13E: 86 A5
|
|
00D140 1
|
|
00D140 1 20 B7 E6 jsr ClearMovementTransforms ; $D140: 20 B7 E6
|
|
00D143 1 B0 05 bcs ConditionalObjectInitReturn ; $D143: B0 05
|
|
00D145 1
|
|
00D145 1 ; ----------------------------------------------------------------------------
|
|
00D145 1 ; On success, set the animation/state value at $03B8 to $2A.
|
|
00D145 1 ; ----------------------------------------------------------------------------
|
|
00D145 1
|
|
00D145 1 A9 2A lda #$2A ; $D145: A9 2A
|
|
00D147 1 8D B8 03 sta $03B8 ; $D147: 8D B8 03
|
|
00D14A 1
|
|
00D14A 1 ConditionalObjectInitReturn: ; $D14A
|
|
00D14A 1 60 rts ; $D14A: 60
|
|
00D14B 1
|
|
00D14B 1 ; ============================================================================
|
|
00D14B 1 ; $D14B-$D166
|
|
00D14B 1 ; Lookup tables used by the routines beginning around $D167 and $D1D0.
|
|
00D14B 1 ;
|
|
00D14B 1 ; The exact semantic meanings remain provisional in the first pass, but later
|
|
00D14B 1 ; indexed references establish these boundaries:
|
|
00D14B 1 ;
|
|
00D14B 1 ; $D14B-$D153 nine-byte lookup table
|
|
00D14B 1 ; $D154-$D15C nine-byte lookup table
|
|
00D14B 1 ; $D15D-$D161 five-byte lookup table
|
|
00D14B 1 ; $D162-$D166 five-byte lookup table
|
|
00D14B 1 ; ============================================================================
|
|
00D14B 1
|
|
00D14B 1 ; ----------------------------------------------------------------------------
|
|
00D14B 1 ; Nine-byte threshold or selection table.
|
|
00D14B 1 ;
|
|
00D14B 1 ; Later code searches this table using X values below nine.
|
|
00D14B 1 ; ----------------------------------------------------------------------------
|
|
00D14B 1
|
|
00D14B 1 PitchDirectionThresholdTable: ; $D14B
|
|
00D14B 1 00 4E 77 8C .byte $00,$4E,$77,$8C
|
|
00D14F 1 94 A7 D0 E5 .byte $94,$A7,$D0,$E5
|
|
00D153 1 ED .byte $ED
|
|
00D154 1
|
|
00D154 1 ; ----------------------------------------------------------------------------
|
|
00D154 1 ; Nine-byte result table paired with PitchDirectionThresholdTable.
|
|
00D154 1 ;
|
|
00D154 1 ; Entries appear to be returned or stored after a matching threshold is found
|
|
00D154 1 ; in PitchDirectionThresholdTable.
|
|
00D154 1 ; ----------------------------------------------------------------------------
|
|
00D154 1
|
|
00D154 1 PitchDirectionResultTable: ; $D154
|
|
00D154 1 00 05 01 04 .byte $00,$05,$01,$04
|
|
00D158 1 06 0A 02 08 .byte $06,$0A,$02,$08
|
|
00D15C 1 09 .byte $09
|
|
00D15D 1
|
|
00D15D 1 ; ----------------------------------------------------------------------------
|
|
00D15D 1 ; Five-byte threshold or selection table.
|
|
00D15D 1 ; ----------------------------------------------------------------------------
|
|
00D15D 1
|
|
00D15D 1 PitchTypeThresholdTable: ; $D15D
|
|
00D15D 1 00 1A 80 9A .byte $00,$1A,$80,$9A,$C0
|
|
00D161 1 C0
|
|
00D162 1
|
|
00D162 1 ; ----------------------------------------------------------------------------
|
|
00D162 1 ; Five-byte result table paired with PitchTypeThresholdTable.
|
|
00D162 1 ; ----------------------------------------------------------------------------
|
|
00D162 1
|
|
00D162 1 PitchTypeResultTable: ; $D162
|
|
00D162 1 00 04 08 00 .byte $00,$04,$08,$00,$04
|
|
00D166 1 04
|
|
00D167 1
|
|
00D167 1 ; ============================================================================
|
|
00D167 1 ; $D167-$D18A
|
|
00D167 1 ; Conditional command dispatch followed by state and object-field
|
|
00D167 1 ; initialization.
|
|
00D167 1 ; ============================================================================
|
|
00D167 1
|
|
00D167 1 InitializePrimaryGameplayActor: ; $D167
|
|
00D167 1 A5 0F lda DerivedControl0 ; $D167: A5 0F
|
|
00D169 1 D0 06 bne ClearPrimaryActorState ; $D169: D0 06
|
|
00D16B 1
|
|
00D16B 1 20 0A EB jsr QueueInlineObjectEvent ; $D16B: 20 0A EB
|
|
00D16E 1
|
|
00D16E 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D16E 1 19 F7 D3 .byte $19,$F7,$D3 ; $D16E-$D170
|
|
00D171 1
|
|
00D171 1 ; ----------------------------------------------------------------------------
|
|
00D171 1 ; Clear working state variables.
|
|
00D171 1 ; ----------------------------------------------------------------------------
|
|
00D171 1
|
|
00D171 1 ClearPrimaryActorState: ; $D171
|
|
00D171 1 A9 00 lda #$00 ; $D171: A9 00
|
|
00D173 1
|
|
00D173 1 85 9D sta CurrentActionState ; $D173: 85 9D
|
|
00D175 1 85 81 sta RandomValue81 ; $D175: 85 81
|
|
00D177 1 85 82 sta ActorActionComplete ; $D177: 85 82
|
|
00D179 1 85 7F sta SelectedStateCount ; $D179: 85 7F
|
|
00D17B 1 85 87 sta ObjectProximityState ; $D17B: 85 87
|
|
00D17D 1
|
|
00D17D 1 ; ----------------------------------------------------------------------------
|
|
00D17D 1 ; Initialize the base object fields using the six inline bytes following the
|
|
00D17D 1 ; call to LoadBasePositionFieldsInline.
|
|
00D17D 1 ;
|
|
00D17D 1 ; Routine $C963 stores these bytes as:
|
|
00D17D 1 ;
|
|
00D17D 1 ; $0509 = $00
|
|
00D17D 1 ; $050A = $00
|
|
00D17D 1 ; $053A = $46
|
|
00D17D 1 ; $053B = $02
|
|
00D17D 1 ; $056B = $00
|
|
00D17D 1 ; $056C = $02
|
|
00D17D 1 ; ----------------------------------------------------------------------------
|
|
00D17D 1
|
|
00D17D 1 20 63 C9 jsr LoadBasePositionFieldsInline ; $D17D: 20 63 C9
|
|
00D180 1
|
|
00D180 1 00 00 .byte $00,$00 ; $D180-$D181
|
|
00D182 1 46 02 .byte $46,$02 ; $D182-$D183
|
|
00D184 1 00 02 .byte $00,$02 ; $D184-$D185
|
|
00D186 1
|
|
00D186 1 ; ----------------------------------------------------------------------------
|
|
00D186 1 ; Initialize the animation/state value at $03B2.
|
|
00D186 1 ; ----------------------------------------------------------------------------
|
|
00D186 1
|
|
00D186 1 A9 11 lda #$11 ; $D186: A9 11
|
|
00D188 1 8D B2 03 sta $03B2 ; $D188: 8D B2 03
|
|
00D18B 1
|
|
00D18B 1 ; ============================================================================
|
|
00D18B 1 ; $D18B-$D1CF
|
|
00D18B 1 ; Generate a randomized loop count, animate $03B7, optionally run an extra
|
|
00D18B 1 ; timing sequence, and dispatch an inline command.
|
|
00D18B 1 ; ============================================================================
|
|
00D18B 1
|
|
00D18B 1 RunPitcherWindupSequence: ; $D18B
|
|
00D18B 1 20 F5 E5 jsr AdvanceRandomState ; $D18B: 20 F5 E5
|
|
00D18E 1 85 73 sta WindupLoopCounter ; $D18E: 85 73
|
|
00D190 1
|
|
00D190 1 ; ----------------------------------------------------------------------------
|
|
00D190 1 ; Transform the random byte into a value whose upper six bits are set.
|
|
00D190 1 ;
|
|
00D190 1 ; A = ((random >> 2) OR random OR $FC)
|
|
00D190 1 ;
|
|
00D190 1 ; This produces a short increment loop ending when WindupLoopCounter wraps to zero.
|
|
00D190 1 ; ----------------------------------------------------------------------------
|
|
00D190 1
|
|
00D190 1 4A lsr ; $D190: 4A
|
|
00D191 1 4A lsr ; $D191: 4A
|
|
00D192 1
|
|
00D192 1 05 73 ora WindupLoopCounter ; $D192: 05 73
|
|
00D194 1 09 FC ora #$FC ; $D194: 09 FC
|
|
00D196 1 85 73 sta WindupLoopCounter ; $D196: 85 73
|
|
00D198 1
|
|
00D198 1 D0 08 bne SetWindupFrame ; $D198: D0 08
|
|
00D19A 1 ; Normally taken because OR #$FC makes the
|
|
00D19A 1 ; result nonzero.
|
|
00D19A 1
|
|
00D19A 1 ; ----------------------------------------------------------------------------
|
|
00D19A 1 ; Alternate entry when the transformed value is zero.
|
|
00D19A 1 ; ----------------------------------------------------------------------------
|
|
00D19A 1
|
|
00D19A 1 RunWindupAlternateFrame: ; $D19A
|
|
00D19A 1 CE B7 03 dec $03B7 ; $D19A: CE B7 03
|
|
00D19D 1
|
|
00D19D 1 A9 0F lda #$0F ; $D19D: A9 0F
|
|
00D19F 1 20 41 EB jsr StoreObjectEventBankValue ; $D19F: 20 41 EB
|
|
00D1A2 1
|
|
00D1A2 1 ; ----------------------------------------------------------------------------
|
|
00D1A2 1 ; Set animation/frame $03B7 to seven and wait $3C ticks.
|
|
00D1A2 1 ; ----------------------------------------------------------------------------
|
|
00D1A2 1
|
|
00D1A2 1 SetWindupFrame: ; $D1A2
|
|
00D1A2 1 A9 07 lda #$07 ; $D1A2: A9 07
|
|
00D1A4 1 8D B7 03 sta $03B7 ; $D1A4: 8D B7 03
|
|
00D1A7 1
|
|
00D1A7 1 A9 3C lda #$3C ; $D1A7: A9 3C
|
|
00D1A9 1 20 41 EB jsr StoreObjectEventBankValue ; $D1A9: 20 41 EB
|
|
00D1AC 1
|
|
00D1AC 1 ; ----------------------------------------------------------------------------
|
|
00D1AC 1 ; Increment $73 until it wraps to zero.
|
|
00D1AC 1 ;
|
|
00D1AC 1 ; Each nonzero result loops through the frame-decrement and short-delay path
|
|
00D1AC 1 ; at $D19A before restoring frame seven and waiting again.
|
|
00D1AC 1 ; ----------------------------------------------------------------------------
|
|
00D1AC 1
|
|
00D1AC 1 E6 73 inc WindupLoopCounter ; $D1AC: E6 73
|
|
00D1AE 1 D0 EA bne RunWindupAlternateFrame
|
|
00D1B0 1 ; $D1AE: D0 EA
|
|
00D1B0 1
|
|
00D1B0 1 ; ----------------------------------------------------------------------------
|
|
00D1B0 1 ; Advance the animation/frame once after the randomized loop completes.
|
|
00D1B0 1 ; ----------------------------------------------------------------------------
|
|
00D1B0 1
|
|
00D1B0 1 EE B7 03 inc $03B7 ; $D1B0: EE B7 03
|
|
00D1B3 1
|
|
00D1B3 1 ; ----------------------------------------------------------------------------
|
|
00D1B3 1 ; Skip the optional two-step animation when $0599 is negative.
|
|
00D1B3 1 ; ----------------------------------------------------------------------------
|
|
00D1B3 1
|
|
00D1B3 1 AD 99 05 lda $0599 ; $D1B3: AD 99 05
|
|
00D1B6 1 30 10 bmi FinishWindupSequence ; $D1B6: 30 10
|
|
00D1B8 1
|
|
00D1B8 1 A9 1E lda #$1E ; $D1B8: A9 1E
|
|
00D1BA 1 20 41 EB jsr StoreObjectEventBankValue ; $D1BA: 20 41 EB
|
|
00D1BD 1
|
|
00D1BD 1 EE B7 03 inc $03B7 ; $D1BD: EE B7 03
|
|
00D1C0 1
|
|
00D1C0 1 A9 1E lda #$1E ; $D1C0: A9 1E
|
|
00D1C2 1 20 41 EB jsr StoreObjectEventBankValue ; $D1C2: 20 41 EB
|
|
00D1C5 1
|
|
00D1C5 1 CE B7 03 dec $03B7 ; $D1C5: CE B7 03
|
|
00D1C8 1
|
|
00D1C8 1 ; ----------------------------------------------------------------------------
|
|
00D1C8 1 ; Dispatch the next state through an inline command record.
|
|
00D1C8 1 ; ----------------------------------------------------------------------------
|
|
00D1C8 1
|
|
00D1C8 1 FinishWindupSequence: ; $D1C8
|
|
00D1C8 1 20 0A EB jsr QueueInlineObjectEvent ; $D1C8: 20 0A EB
|
|
00D1CB 1
|
|
00D1CB 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D1CB 1 17 AC D2 .byte $17,$AC,$D2 ; $D1CB-$D1CD
|
|
00D1CE 1
|
|
00D1CE 1 E6 7E inc ActionSequenceCounter ; $D1CE: E6 7E
|
|
00D1D0 1
|
|
00D1D0 1 ; ============================================================================
|
|
00D1D0 1 ; $D1D0-$D2A3
|
|
00D1D0 1 ; Randomized decision, animation, movement adjustment, and state transition.
|
|
00D1D0 1 ; ============================================================================
|
|
00D1D0 1
|
|
00D1D0 1 SelectPitchAction: ; $D1D0
|
|
00D1D0 1 20 48 EB jsr SelectObjectEventBank1 ; $D1D0: 20 48 EB
|
|
00D1D3 1
|
|
00D1D3 1 A5 10 lda $10 ; $D1D3: A5 10
|
|
00D1D5 1 D0 33 bne UseControllerPitchSelection
|
|
00D1D7 1 ; $D1D5: D0 33
|
|
00D1D7 1
|
|
00D1D7 1 ; ----------------------------------------------------------------------------
|
|
00D1D7 1 ; Wait $3C ticks before making a randomized selection.
|
|
00D1D7 1 ; ----------------------------------------------------------------------------
|
|
00D1D7 1
|
|
00D1D7 1 A9 3C lda #$3C ; $D1D7: A9 3C
|
|
00D1D9 1 20 41 EB jsr StoreObjectEventBankValue ; $D1D9: 20 41 EB
|
|
00D1DC 1
|
|
00D1DC 1 20 F5 E5 jsr AdvanceRandomState ; $D1DC: 20 F5 E5
|
|
00D1DF 1
|
|
00D1DF 1 ; ----------------------------------------------------------------------------
|
|
00D1DF 1 ; Search backward through $9F-$A1 for an entry below eight.
|
|
00D1DF 1 ;
|
|
00D1DF 1 ; X begins at two. The first entry below eight determines X.
|
|
00D1DF 1 ; ----------------------------------------------------------------------------
|
|
00D1DF 1
|
|
00D1DF 1 A2 02 ldx #$02 ; $D1DF: A2 02
|
|
00D1E1 1
|
|
00D1E1 1 FindAvailablePitchState: ; $D1E1
|
|
00D1E1 1 B4 9F ldy SecondaryActorState0,x ; $D1E1: B4 9F
|
|
00D1E3 1
|
|
00D1E3 1 C0 08 cpy #$08 ; $D1E3: C0 08
|
|
00D1E5 1 90 03 bcc SelectPitchType
|
|
00D1E7 1 ; $D1E5: 90 03
|
|
00D1E7 1
|
|
00D1E7 1 CA dex ; $D1E7: CA
|
|
00D1E8 1 10 F7 bpl FindAvailablePitchState
|
|
00D1EA 1 ; $D1E8: 10 F7
|
|
00D1EA 1
|
|
00D1EA 1 ; ----------------------------------------------------------------------------
|
|
00D1EA 1 ; Rotate the random value, then select from paired tables at $D15D/$D162.
|
|
00D1EA 1 ; ----------------------------------------------------------------------------
|
|
00D1EA 1
|
|
00D1EA 1 SelectPitchType: ; $D1EA
|
|
00D1EA 1 6A ror ; $D1EA: 6A
|
|
00D1EB 1
|
|
00D1EB 1 A2 05 ldx #$05 ; $D1EB: A2 05
|
|
00D1ED 1
|
|
00D1ED 1 SearchPitchTypeThresholds: ; $D1ED
|
|
00D1ED 1 CA dex ; $D1ED: CA
|
|
00D1EE 1
|
|
00D1EE 1 DD 5D D1 cmp PitchTypeThresholdTable,x ; $D1EE: DD 5D D1
|
|
00D1F1 1 90 FA bcc SearchPitchTypeThresholds
|
|
00D1F3 1 ; $D1F1: 90 FA
|
|
00D1F3 1
|
|
00D1F3 1 BD 62 D1 lda PitchTypeResultTable,x ; $D1F3: BD 62 D1
|
|
00D1F6 1 85 21 sta SelectedPitchAction ; $D1F6: 85 21
|
|
00D1F8 1
|
|
00D1F8 1 ; ----------------------------------------------------------------------------
|
|
00D1F8 1 ; Make a second randomized table selection using $D14B/$D154.
|
|
00D1F8 1 ; ----------------------------------------------------------------------------
|
|
00D1F8 1
|
|
00D1F8 1 20 F5 E5 jsr AdvanceRandomState ; $D1F8: 20 F5 E5
|
|
00D1FB 1
|
|
00D1FB 1 A2 09 ldx #$09 ; $D1FB: A2 09
|
|
00D1FD 1
|
|
00D1FD 1 SearchPitchDirectionThresholds: ; $D1FD
|
|
00D1FD 1 CA dex ; $D1FD: CA
|
|
00D1FE 1
|
|
00D1FE 1 DD 4B D1 cmp PitchDirectionThresholdTable,x ; $D1FE: DD 4B D1
|
|
00D201 1 90 FA bcc SearchPitchDirectionThresholds
|
|
00D203 1 ; $D201: 90 FA
|
|
00D203 1
|
|
00D203 1 BD 54 D1 lda PitchDirectionResultTable,x ; $D203: BD 54 D1
|
|
00D206 1 85 91 sta $91 ; $D206: 85 91
|
|
00D208 1
|
|
00D208 1 B0 08 bcs AnimatePitchStart ; $D208: B0 08
|
|
00D20A 1 ; Always taken after the table search succeeds.
|
|
00D20A 1
|
|
00D20A 1 ; ----------------------------------------------------------------------------
|
|
00D20A 1 ; Alternate path used when $10 is nonzero.
|
|
00D20A 1 ; ----------------------------------------------------------------------------
|
|
00D20A 1
|
|
00D20A 1 UseControllerPitchSelection: ; $D20A
|
|
00D20A 1 A5 14 lda InputState2 ; $D20A: A5 14
|
|
00D20C 1 85 21 sta SelectedPitchAction ; $D20C: 85 21
|
|
00D20E 1
|
|
00D20E 1 A5 18 lda InputAux2 ; $D20E: A5 18
|
|
00D210 1 10 BE bpl SelectPitchAction ; $D210: 10 BE
|
|
00D212 1
|
|
00D212 1 ; ----------------------------------------------------------------------------
|
|
00D212 1 ; Process event slot $17 and dispatch the next state.
|
|
00D212 1 ; ----------------------------------------------------------------------------
|
|
00D212 1
|
|
00D212 1 AnimatePitchStart: ; $D212
|
|
00D212 1 A0 17 ldy #$17 ; $D212: A0 17
|
|
00D214 1 20 66 EB jsr DispatchNextQueuedEvent ; $D214: 20 66 EB
|
|
00D217 1
|
|
00D217 1 20 48 EB jsr SelectObjectEventBank1 ; $D217: 20 48 EB
|
|
00D21A 1
|
|
00D21A 1 20 0A EB jsr QueueInlineObjectEvent ; $D21A: 20 0A EB
|
|
00D21D 1
|
|
00D21D 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D21D 1 13 DA D6 .byte $13,$DA,$D6 ; $D21D-$D21F
|
|
00D220 1
|
|
00D220 1 ; ----------------------------------------------------------------------------
|
|
00D220 1 ; Animate $03B7 from $0C through $0F with a ten-tick delay between frames.
|
|
00D220 1 ; ----------------------------------------------------------------------------
|
|
00D220 1
|
|
00D220 1 A9 0C lda #$0C ; $D220: A9 0C
|
|
00D222 1 8D B7 03 sta $03B7 ; $D222: 8D B7 03
|
|
00D225 1
|
|
00D225 1 PitchStartAnimationLoop: ; $D225
|
|
00D225 1 A9 0A lda #$0A ; $D225: A9 0A
|
|
00D227 1 20 41 EB jsr StoreObjectEventBankValue ; $D227: 20 41 EB
|
|
00D22A 1
|
|
00D22A 1 EE B7 03 inc $03B7 ; $D22A: EE B7 03
|
|
00D22D 1
|
|
00D22D 1 AD B7 03 lda $03B7 ; $D22D: AD B7 03
|
|
00D230 1 C9 0F cmp #$0F ; $D230: C9 0F
|
|
00D232 1 90 F1 bcc PitchStartAnimationLoop
|
|
00D234 1 ; $D232: 90 F1
|
|
00D234 1
|
|
00D234 1 ; ----------------------------------------------------------------------------
|
|
00D234 1 ; Use bits 2-3 of $21 to select entries from the tables at $D2A4-$D2AC.
|
|
00D234 1 ; ----------------------------------------------------------------------------
|
|
00D234 1
|
|
00D234 1 A5 21 lda SelectedPitchAction ; $D234: A5 21
|
|
00D236 1 4A lsr ; $D236: 4A
|
|
00D237 1 4A lsr ; $D237: 4A
|
|
00D238 1
|
|
00D238 1 29 03 and #$03 ; $D238: 29 03
|
|
00D23A 1 AA tax ; $D23A: AA
|
|
00D23B 1
|
|
00D23B 1 BD AA D2 lda PitchRenderFlagTable,x ; $D23B: BD AA D2
|
|
00D23E 1 85 FF sta RenderStateFlags ; $D23E: 85 FF
|
|
00D240 1
|
|
00D240 1 ; ----------------------------------------------------------------------------
|
|
00D240 1 ; Combine a random value with the signed table at $D2A4, then use the result as
|
|
00D240 1 ; Y to select a delay from the table at $D2A7.
|
|
00D240 1 ; ----------------------------------------------------------------------------
|
|
00D240 1
|
|
00D240 1 20 F5 E5 jsr AdvanceRandomState ; $D240: 20 F5 E5
|
|
00D243 1
|
|
00D243 1 09 F0 ora #$F0 ; $D243: 09 F0
|
|
00D245 1 FD A4 D2 sbc PitchVelocityBiasTable,x ; $D245: FD A4 D2
|
|
00D248 1 A8 tay ; $D248: A8
|
|
00D249 1
|
|
00D249 1 BD A7 D2 lda PitchDelayTable,x ; $D249: BD A7 D2
|
|
00D24C 1 85 94 sta PitchUpdateDelay ; $D24C: 85 94
|
|
00D24E 1
|
|
00D24E 1 ; ----------------------------------------------------------------------------
|
|
00D24E 1 ; Initialize base movement state.
|
|
00D24E 1 ;
|
|
00D24E 1 ; Y from the preceding calculation is passed to InitializeBaseMotionZero.
|
|
00D24E 1 ; ----------------------------------------------------------------------------
|
|
00D24E 1
|
|
00D24E 1 A2 00 ldx #$00 ; $D24E: A2 00
|
|
00D250 1 20 23 CA jsr InitializeBaseMotionZero ; $D250: 20 23 CA
|
|
00D253 1
|
|
00D253 1 ; ----------------------------------------------------------------------------
|
|
00D253 1 ; Generate and transform another random value through the helper at $C036.
|
|
00D253 1 ; The result is stored as both $71 and $81.
|
|
00D253 1 ; ----------------------------------------------------------------------------
|
|
00D253 1
|
|
00D253 1 20 F5 E5 jsr AdvanceRandomState ; $D253: 20 F5 E5
|
|
00D256 1 20 36 C0 jsr $C036 ; $D256: 20 36 C0
|
|
00D259 1
|
|
00D259 1 85 71 sta DisplayCounterValue ; $D259: 85 71
|
|
00D25B 1 85 81 sta RandomValue81 ; $D25B: 85 81
|
|
00D25D 1
|
|
00D25D 1 E6 9D inc CurrentActionState ; $D25D: E6 9D
|
|
00D25F 1
|
|
00D25F 1 ; ----------------------------------------------------------------------------
|
|
00D25F 1 ; Dispatch the next state through an inline command.
|
|
00D25F 1 ; ----------------------------------------------------------------------------
|
|
00D25F 1
|
|
00D25F 1 20 0A EB jsr QueueInlineObjectEvent ; $D25F: 20 0A EB
|
|
00D262 1
|
|
00D262 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D262 1 04 85 D7 .byte $04,$85,$D7 ; $D262-$D264
|
|
00D265 1
|
|
00D265 1 ; ----------------------------------------------------------------------------
|
|
00D265 1 ; Wait using the selected delay value from $94.
|
|
00D265 1 ; ----------------------------------------------------------------------------
|
|
00D265 1
|
|
00D265 1 UpdatePitchMovement: ; $D265
|
|
00D265 1 A5 94 lda PitchUpdateDelay ; $D265: A5 94
|
|
00D267 1 20 41 EB jsr StoreObjectEventBankValue ; $D267: 20 41 EB
|
|
00D26A 1
|
|
00D26A 1 ; ----------------------------------------------------------------------------
|
|
00D26A 1 ; Choose a direction/control value.
|
|
00D26A 1 ; ----------------------------------------------------------------------------
|
|
00D26A 1
|
|
00D26A 1 A5 10 lda $10 ; $D26A: A5 10
|
|
00D26C 1 D0 0D bne UsePitchControllerInput ; $D26C: D0 0D
|
|
00D26E 1
|
|
00D26E 1 A5 91 lda PitchDirectionDecision ; $D26E: A5 91
|
|
00D270 1
|
|
00D270 1 AE 3B 05 ldx $053B ; $D270: AE 3B 05
|
|
00D273 1 E0 FD cpx #$FD ; $D273: E0 FD
|
|
00D275 1 10 06 bpl ApplyPitchHorizontalInput ; $D275: 10 06
|
|
00D277 1
|
|
00D277 1 4A lsr ; $D277: 4A
|
|
00D278 1 4A lsr ; $D278: 4A
|
|
00D279 1
|
|
00D279 1 D0 02 bne ApplyPitchHorizontalInput ; $D279: D0 02
|
|
00D27B 1
|
|
00D27B 1 UsePitchControllerInput: ; $D27B
|
|
00D27B 1 A5 14 lda InputState2 ; $D27B: A5 14
|
|
00D27D 1
|
|
00D27D 1 ; ----------------------------------------------------------------------------
|
|
00D27D 1 ; Adjust the signed high movement byte at $0508 according to bits in A.
|
|
00D27D 1 ; ----------------------------------------------------------------------------
|
|
00D27D 1
|
|
00D27D 1 ApplyPitchHorizontalInput: ; $D27D
|
|
00D27D 1 4A lsr ; $D27D: 4A
|
|
00D27E 1 90 05 bcc ApplyPitchLeftInput
|
|
00D280 1 ; $D27E: 90 05
|
|
00D280 1
|
|
00D280 1 EE 08 05 inc $0508 ; $D280: EE 08 05
|
|
00D283 1 B0 06 bcs SetPitchMovementFlags ; $D283: B0 06
|
|
00D285 1 ; Always taken because LSR set carry.
|
|
00D285 1
|
|
00D285 1 ApplyPitchLeftInput: ; $D285
|
|
00D285 1 4A lsr ; $D285: 4A
|
|
00D286 1 90 07 bcc CheckPitchVerticalLimit
|
|
00D288 1 ; $D286: 90 07
|
|
00D288 1
|
|
00D288 1 CE 08 05 dec $0508 ; $D288: CE 08 05
|
|
00D28B 1
|
|
00D28B 1 SetPitchMovementFlags: ; $D28B
|
|
00D28B 1 A9 08 lda #$08 ; $D28B: A9 08
|
|
00D28D 1 85 FF sta RenderStateFlags ; $D28D: 85 FF
|
|
00D28F 1
|
|
00D28F 1 ; ----------------------------------------------------------------------------
|
|
00D28F 1 ; Continue until the vertical high position reaches $FA or greater.
|
|
00D28F 1 ; ----------------------------------------------------------------------------
|
|
00D28F 1
|
|
00D28F 1 CheckPitchVerticalLimit: ; $D28F
|
|
00D28F 1 AD 3B 05 lda $053B ; $D28F: AD 3B 05
|
|
00D292 1 C9 FA cmp #$FA ; $D292: C9 FA
|
|
00D294 1 10 CF bpl UpdatePitchMovement
|
|
00D296 1 ; $D294: 10 CF
|
|
00D296 1
|
|
00D296 1 ; ----------------------------------------------------------------------------
|
|
00D296 1 ; Set the final animation value, dispatch the next state, and leave.
|
|
00D296 1 ; ----------------------------------------------------------------------------
|
|
00D296 1
|
|
00D296 1 A9 2F lda #$2F ; $D296: A9 2F
|
|
00D298 1 8D B7 03 sta $03B7 ; $D298: 8D B7 03
|
|
00D29B 1
|
|
00D29B 1 20 0A EB jsr QueueInlineObjectEvent ; $D29B: 20 0A EB
|
|
00D29E 1
|
|
00D29E 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D29E 1 21 27 D0 .byte $21,$27,$D0 ; $D29E-$D2A0
|
|
00D2A1 1
|
|
00D2A1 1 4C 6A EB jmp CommonEngineExit ; $D2A1: 4C 6A EB
|
|
00D2A4 1
|
|
00D2A4 1 ; ============================================================================
|
|
00D2A4 1 ; $D2A4-$D2AC
|
|
00D2A4 1 ; Three parallel three-byte lookup tables selected by bits 2-3 of $21.
|
|
00D2A4 1 ; ============================================================================
|
|
00D2A4 1
|
|
00D2A4 1 PitchVelocityBiasTable: ; $D2A4
|
|
00D2A4 1 37 47 27 .byte $37,$47,$27
|
|
00D2A7 1
|
|
00D2A7 1 PitchDelayTable: ; $D2A7
|
|
00D2A7 1 05 04 06 .byte $05,$04,$06
|
|
00D2AA 1
|
|
00D2AA 1 PitchRenderFlagTable: ; $D2AA
|
|
00D2AA 1 02 01 04 .byte $02,$01,$04
|
|
00D2AD 1
|
|
00D2AD 1 ; ============================================================================
|
|
00D2AD 1 ; $D2AD-$D329
|
|
00D2AD 1 ; Timed selection loop, player/input selection, event processing, and state
|
|
00D2AD 1 ; transition.
|
|
00D2AD 1 ; ============================================================================
|
|
00D2AD 1
|
|
00D2AD 1 SelectBatterAction: ; $D2AD
|
|
00D2AD 1 A9 30 lda #$30 ; $D2AD: A9 30
|
|
00D2AF 1 8D C8 05 sta $05C8 ; $D2AF: 8D C8 05
|
|
00D2B2 1
|
|
00D2B2 1 ; ----------------------------------------------------------------------------
|
|
00D2B2 1 ; Wait for a frame and evaluate the current input/state.
|
|
00D2B2 1 ; ----------------------------------------------------------------------------
|
|
00D2B2 1
|
|
00D2B2 1 WaitForBatterAction: ; $D2B2
|
|
00D2B2 1 20 48 EB jsr SelectObjectEventBank1 ; $D2B2: 20 48 EB
|
|
00D2B5 1
|
|
00D2B5 1 A5 10 lda $10 ; $D2B5: A5 10
|
|
00D2B7 1 D0 1B bne UseBatterControllerInput ; $D2B7: D0 1B
|
|
00D2B9 1
|
|
00D2B9 1 A5 82 lda ActorActionComplete ; $D2B9: A5 82
|
|
00D2BB 1 D0 F0 bne SelectBatterAction ; $D2BB: D0 F0
|
|
00D2BD 1
|
|
00D2BD 1 ; ----------------------------------------------------------------------------
|
|
00D2BD 1 ; Check three entries at $0575, $0573, and $0571.
|
|
00D2BD 1 ;
|
|
00D2BD 1 ; If any entry is nonzero, control branches forward to $D32A.
|
|
00D2BD 1 ; ----------------------------------------------------------------------------
|
|
00D2BD 1
|
|
00D2BD 1 A2 04 ldx #$04 ; $D2BD: A2 04
|
|
00D2BF 1
|
|
00D2BF 1 CheckActiveFieldObjects: ; $D2BF
|
|
00D2BF 1 BD 75 05 lda $0575,x ; $D2BF: BD 75 05
|
|
00D2C2 1 D0 66 bne SelectActionFromObjectState ; $D2C2: D0 66
|
|
00D2C4 1
|
|
00D2C4 1 CA dex ; $D2C4: CA
|
|
00D2C5 1 CA dex ; $D2C5: CA
|
|
00D2C6 1 10 F7 bpl CheckActiveFieldObjects
|
|
00D2C8 1 ; $D2C6: 10 F7
|
|
00D2C8 1
|
|
00D2C8 1 ; ----------------------------------------------------------------------------
|
|
00D2C8 1 ; Count down $05C8 while no active entry is found.
|
|
00D2C8 1 ; ----------------------------------------------------------------------------
|
|
00D2C8 1
|
|
00D2C8 1 CE C8 05 dec $05C8 ; $D2C8: CE C8 05
|
|
00D2CB 1 D0 E5 bne WaitForBatterAction ; $D2CB: D0 E5
|
|
00D2CD 1
|
|
00D2CD 1 ; ----------------------------------------------------------------------------
|
|
00D2CD 1 ; If the random value is below $46, continue at $D2D9.
|
|
00D2CD 1 ; Otherwise, use the current input byte at $18.
|
|
00D2CD 1 ; ----------------------------------------------------------------------------
|
|
00D2CD 1
|
|
00D2CD 1 20 F5 E5 jsr AdvanceRandomState ; $D2CD: 20 F5 E5
|
|
00D2D0 1 C9 46 cmp #$46 ; $D2D0: C9 46
|
|
00D2D2 1 90 05 bcc SelectBatterActionSlot ; $D2D2: 90 05
|
|
00D2D4 1
|
|
00D2D4 1 UseBatterControllerInput: ; $D2D4
|
|
00D2D4 1 A5 18 lda InputAux2 ; $D2D4: A5 18
|
|
00D2D6 1 0A asl ; $D2D6: 0A
|
|
00D2D7 1 10 D9 bpl WaitForBatterAction ; $D2D7: 10 D9
|
|
00D2D9 1
|
|
00D2D9 1 ; ----------------------------------------------------------------------------
|
|
00D2D9 1 ; Search backward through $9F-$A1 for an entry below eight.
|
|
00D2D9 1 ; ----------------------------------------------------------------------------
|
|
00D2D9 1
|
|
00D2D9 1 SelectBatterActionSlot: ; $D2D9
|
|
00D2D9 1 A2 03 ldx #$03 ; $D2D9: A2 03
|
|
00D2DB 1
|
|
00D2DB 1 FindAvailableBatterActionSlot: ; $D2DB
|
|
00D2DB 1 CA dex ; $D2DB: CA
|
|
00D2DC 1 30 CF bmi SelectBatterAction ; $D2DC: 30 CF
|
|
00D2DE 1
|
|
00D2DE 1 B5 9F lda SecondaryActorState0,x ; $D2DE: B5 9F
|
|
00D2E0 1 C9 08 cmp #$08 ; $D2E0: C9 08
|
|
00D2E2 1 B0 F7 bcs FindAvailableBatterActionSlot ; $D2E2: B0 F7
|
|
00D2E4 1
|
|
00D2E4 1 E6 7F inc SelectedStateCount ; $D2E4: E6 7F
|
|
00D2E6 1
|
|
00D2E6 1 ; ----------------------------------------------------------------------------
|
|
00D2E6 1 ; Select the working value for $21.
|
|
00D2E6 1 ; ----------------------------------------------------------------------------
|
|
00D2E6 1
|
|
00D2E6 1 A5 10 lda $10 ; $D2E6: A5 10
|
|
00D2E8 1 D0 0D bne UseBatterInputAction ; $D2E8: D0 0D
|
|
00D2EA 1
|
|
00D2EA 1 A5 9F lda SecondaryActorState0 ; $D2EA: A5 9F
|
|
00D2EC 1 C9 02 cmp #$02 ; $D2EC: C9 02
|
|
00D2EE 1 D0 07 bne UseBatterInputAction ; $D2EE: D0 07
|
|
00D2F0 1
|
|
00D2F0 1 20 F5 E5 jsr AdvanceRandomState ; $D2F0: 20 F5 E5
|
|
00D2F3 1 29 01 and #$01 ; $D2F3: 29 01
|
|
00D2F5 1 10 02 bpl SaveBatterAction ; $D2F5: 10 02
|
|
00D2F7 1 ; Always taken after AND #$01.
|
|
00D2F7 1
|
|
00D2F7 1 UseBatterInputAction: ; $D2F7
|
|
00D2F7 1 A5 14 lda InputState2 ; $D2F7: A5 14
|
|
00D2F9 1
|
|
00D2F9 1 SaveBatterAction: ; $D2F9
|
|
00D2F9 1 85 21 sta SelectedPitchAction ; $D2F9: 85 21
|
|
00D2FB 1
|
|
00D2FB 1 ; ----------------------------------------------------------------------------
|
|
00D2FB 1 ; Process event slots $0E and $11.
|
|
00D2FB 1 ; ----------------------------------------------------------------------------
|
|
00D2FB 1
|
|
00D2FB 1 A0 0E ldy #$0E ; $D2FB: A0 0E
|
|
00D2FD 1 20 66 EB jsr DispatchNextQueuedEvent ; $D2FD: 20 66 EB
|
|
00D300 1
|
|
00D300 1 A0 11 ldy #$11 ; $D300: A0 11
|
|
00D302 1 20 66 EB jsr DispatchNextQueuedEvent ; $D302: 20 66 EB
|
|
00D305 1
|
|
00D305 1 ; ----------------------------------------------------------------------------
|
|
00D305 1 ; Initialize animation frame $0C, wait ten ticks, then run the helper at $D33C.
|
|
00D305 1 ; ----------------------------------------------------------------------------
|
|
00D305 1
|
|
00D305 1 A9 0C lda #$0C ; $D305: A9 0C
|
|
00D307 1 8D B7 03 sta $03B7 ; $D307: 8D B7 03
|
|
00D30A 1
|
|
00D30A 1 A9 0A lda #$0A ; $D30A: A9 0A
|
|
00D30C 1 20 41 EB jsr StoreObjectEventBankValue ; $D30C: 20 41 EB
|
|
00D30F 1
|
|
00D30F 1 20 3C D3 jsr DispatchActionType ; $D30F: 20 3C D3
|
|
00D312 1
|
|
00D312 1 E6 9D inc CurrentActionState ; $D312: E6 9D
|
|
00D314 1 CE B7 03 dec $03B7 ; $D314: CE B7 03
|
|
00D317 1
|
|
00D317 1 ; ----------------------------------------------------------------------------
|
|
00D317 1 ; Dispatch the next state through an inline command.
|
|
00D317 1 ; ----------------------------------------------------------------------------
|
|
00D317 1
|
|
00D317 1 20 0A EB jsr QueueInlineObjectEvent ; $D317: 20 0A EB
|
|
00D31A 1
|
|
00D31A 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D31A 1 11 D7 D5 .byte $11,$D7,$D5 ; $D31A-$D31C
|
|
00D31D 1
|
|
00D31D 1 A9 1E lda #$1E ; $D31D: A9 1E
|
|
00D31F 1 20 41 EB jsr StoreObjectEventBankValue ; $D31F: 20 41 EB
|
|
00D322 1
|
|
00D322 1 A9 2F lda #$2F ; $D322: A9 2F
|
|
00D324 1 8D A2 03 sta $03A2 ; $D324: 8D A2 03
|
|
00D327 1
|
|
00D327 1 4C 6A EB jmp CommonEngineExit ; $D327: 4C 6A EB
|
|
00D32A 1
|
|
00D32A 1 ; ============================================================================
|
|
00D32A 1 ; $D32A-$D338
|
|
00D32A 1 ; Select an action value from a three-byte lookup table.
|
|
00D32A 1 ;
|
|
00D32A 1 ; Entry:
|
|
00D32A 1 ; X = object or player index
|
|
00D32A 1 ;
|
|
00D32A 1 ; Operation:
|
|
00D32A 1 ; 1. Increment $7F.
|
|
00D32A 1 ; 2. Divide X by two.
|
|
00D32A 1 ; 3. Use the resulting index to read $0599-$059B.
|
|
00D32A 1 ; 4. Divide that value by two.
|
|
00D32A 1 ; 5. Use the result as an index into ObjectActionLookupTable.
|
|
00D32A 1 ; 6. Branch back to $D2F9 with the selected value in A.
|
|
00D32A 1 ;
|
|
00D32A 1 ; The table values are all nonzero, so the final BNE is effectively
|
|
00D32A 1 ; unconditional for valid indices.
|
|
00D32A 1 ; ============================================================================
|
|
00D32A 1
|
|
00D32A 1 SelectActionFromObjectState: ; $D32A
|
|
00D32A 1 E6 7F inc SelectedStateCount ; $D32A: E6 7F
|
|
00D32C 1
|
|
00D32C 1 8A txa ; $D32C: 8A
|
|
00D32D 1 4A lsr ; $D32D: 4A
|
|
00D32E 1 AA tax ; $D32E: AA
|
|
00D32F 1
|
|
00D32F 1 BD 99 05 lda $0599,x ; $D32F: BD 99 05
|
|
00D332 1 4A lsr ; $D332: 4A
|
|
00D333 1 AA tax ; $D333: AA
|
|
00D334 1
|
|
00D334 1 BD 38 D3 lda $D338,x ; $D334: BD 38 D3
|
|
00D337 1 D0 C0 bne SaveBatterAction ; $D337: D0 C0
|
|
00D339 1
|
|
00D339 1 ; ============================================================================
|
|
00D339 1 ; $D339-$D33B
|
|
00D339 1 ; Action/control lookup table.
|
|
00D339 1 ;
|
|
00D339 1 ; Indexed by half of the selected value from $0599-$059B.
|
|
00D339 1 ; ============================================================================
|
|
00D339 1
|
|
00D339 1 ObjectActionLookupTable: ; $D339
|
|
00D339 1 01 08 02 .byte $01,$08,$02
|
|
00D33C 1
|
|
00D33C 1 ; ============================================================================
|
|
00D33C 1 ; $D33C-$D381
|
|
00D33C 1 ; Select one of three state paths using $21 and the values at $9F-$A1.
|
|
00D33C 1 ;
|
|
00D33C 1 ; The routine can:
|
|
00D33C 1 ; Set $059D to $01 and dispatch command $10
|
|
00D33C 1 ; Set $059E to $02 and dispatch command $12
|
|
00D33C 1 ; Set $05A0 to $03 and dispatch command $16
|
|
00D33C 1 ; ============================================================================
|
|
00D33C 1
|
|
00D33C 1 ; ----------------------------------------------------------------------------
|
|
00D33C 1 ; Contract:
|
|
00D33C 1 ; Description: Implements Dispatch Action Type.
|
|
00D33C 1 ; Entry: Registers: A, X; Memory: selectedpitchaction, secondaryactorstate0
|
|
00D33C 1 ; Returns/products: Registers/clobbers: A, X
|
|
00D33C 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00D33C 1 ; Memory effects: $059d
|
|
00D33C 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00D33C 1 ; comparison, load, or store path and are not a stable API product.
|
|
00D33C 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00D33C 1 ; ----------------------------------------------------------------------------
|
|
00D33C 1 DispatchActionType: ; $D33C
|
|
00D33C 1 A5 21 lda SelectedPitchAction ; $D33C: A5 21
|
|
00D33E 1 29 0B and #$0B ; $D33E: 29 0B
|
|
00D340 1 D0 1F bne Routine_D361_TestBits ; $D340: D0 1F
|
|
00D342 1
|
|
00D342 1 ; ----------------------------------------------------------------------------
|
|
00D342 1 ; Search the three entries at $9F-$A1 in reverse order.
|
|
00D342 1 ; ----------------------------------------------------------------------------
|
|
00D342 1
|
|
00D342 1 A2 02 ldx #$02 ; $D342: A2 02
|
|
00D344 1
|
|
00D344 1 Routine_D344_SearchEntries: ; $D344
|
|
00D344 1 B5 9F lda SecondaryActorState0,x ; $D344: B5 9F
|
|
00D346 1 C9 08 cmp #$08 ; $D346: C9 08
|
|
00D348 1 B0 08 bcs Routine_D352_NextEntry ; $D348: B0 08
|
|
00D34A 1
|
|
00D34A 1 C9 06 cmp #$06 ; $D34A: C9 06
|
|
00D34C 1 B0 25 bcs Routine_D373_State3 ; $D34C: B0 25
|
|
00D34E 1
|
|
00D34E 1 C9 04 cmp #$04 ; $D34E: C9 04
|
|
00D350 1 B0 15 bcs Routine_D367_State2 ; $D350: B0 15
|
|
00D352 1
|
|
00D352 1 Routine_D352_NextEntry: ; $D352
|
|
00D352 1 CA dex ; $D352: CA
|
|
00D353 1 10 EF bpl Routine_D344_SearchEntries
|
|
00D355 1 ; $D353: 10 EF
|
|
00D355 1
|
|
00D355 1 ; ----------------------------------------------------------------------------
|
|
00D355 1 ; State 1.
|
|
00D355 1 ; ----------------------------------------------------------------------------
|
|
00D355 1
|
|
00D355 1 Routine_D355_State1: ; $D355
|
|
00D355 1 A9 01 lda #$01 ; $D355: A9 01
|
|
00D357 1 8D 9D 05 sta $059D ; $D357: 8D 9D 05
|
|
00D35A 1
|
|
00D35A 1 20 0A EB jsr QueueInlineObjectEvent ; $D35A: 20 0A EB
|
|
00D35D 1
|
|
00D35D 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D35D 1 10 AB E3 .byte $10,$AB,$E3 ; $D35D-$D35F
|
|
00D360 1
|
|
00D360 1 60 rts ; $D360: 60
|
|
00D361 1
|
|
00D361 1 ; ----------------------------------------------------------------------------
|
|
00D361 1 ; When $21 & $0B is nonzero, test its low two bits.
|
|
00D361 1 ;
|
|
00D361 1 ; Bit 0 selects state 1.
|
|
00D361 1 ; Bit 1 selects state 3.
|
|
00D361 1 ; Otherwise, state 2 is selected.
|
|
00D361 1 ; ----------------------------------------------------------------------------
|
|
00D361 1
|
|
00D361 1 Routine_D361_TestBits: ; $D361
|
|
00D361 1 4A lsr ; $D361: 4A
|
|
00D362 1 B0 F1 bcs Routine_D355_State1 ; $D362: B0 F1
|
|
00D364 1
|
|
00D364 1 4A lsr ; $D364: 4A
|
|
00D365 1 B0 0C bcs Routine_D373_State3 ; $D365: B0 0C
|
|
00D367 1
|
|
00D367 1 ; ----------------------------------------------------------------------------
|
|
00D367 1 ; State 2.
|
|
00D367 1 ; ----------------------------------------------------------------------------
|
|
00D367 1
|
|
00D367 1 Routine_D367_State2: ; $D367
|
|
00D367 1 A9 02 lda #$02 ; $D367: A9 02
|
|
00D369 1 8D 9E 05 sta $059E ; $D369: 8D 9E 05
|
|
00D36C 1
|
|
00D36C 1 20 0A EB jsr QueueInlineObjectEvent ; $D36C: 20 0A EB
|
|
00D36F 1
|
|
00D36F 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D36F 1 12 AB E3 .byte $12,$AB,$E3 ; $D36F-$D371
|
|
00D372 1
|
|
00D372 1 60 rts ; $D372: 60
|
|
00D373 1
|
|
00D373 1 ; ----------------------------------------------------------------------------
|
|
00D373 1 ; State 3.
|
|
00D373 1 ; ----------------------------------------------------------------------------
|
|
00D373 1
|
|
00D373 1 Routine_D373_State3: ; $D373
|
|
00D373 1 A9 03 lda #$03 ; $D373: A9 03
|
|
00D375 1 8D A0 05 sta $05A0 ; $D375: 8D A0 05
|
|
00D378 1
|
|
00D378 1 20 0A EB jsr QueueInlineObjectEvent ; $D378: 20 0A EB
|
|
00D37B 1
|
|
00D37B 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D37B 1 16 AB E3 .byte $16,$AB,$E3 ; $D37B-$D37D
|
|
00D37E 1
|
|
00D37E 1 CE B7 03 dec $03B7 ; $D37E: CE B7 03
|
|
00D381 1
|
|
00D381 1 60 rts ; $D381: 60
|
|
00D382 1
|
|
00D382 1 ; ============================================================================
|
|
00D382 1 ; $D382-$D3EF
|
|
00D382 1 ; Derive an index from input state, apply signed coordinate offsets, constrain
|
|
00D382 1 ; the resulting positions, update object state, and repeat.
|
|
00D382 1 ; ============================================================================
|
|
00D382 1
|
|
00D382 1 MoveControlledObject: ; $D382
|
|
00D382 1 20 48 EB jsr SelectObjectEventBank1 ; $D382: 20 48 EB
|
|
00D385 1
|
|
00D385 1 ; ----------------------------------------------------------------------------
|
|
00D385 1 ; Derive a small index in Y from the value at $13.
|
|
00D385 1 ;
|
|
00D385 1 ; The value is ORed with $F0, then shifted right until carry clears.
|
|
00D385 1 ; Y begins at $FF and is incremented once per shift.
|
|
00D385 1 ; ----------------------------------------------------------------------------
|
|
00D385 1
|
|
00D385 1 A0 FF ldy #$FF ; $D385: A0 FF
|
|
00D387 1
|
|
00D387 1 A5 13 lda InputState1 ; $D387: A5 13
|
|
00D389 1 09 F0 ora #$F0 ; $D389: 09 F0
|
|
00D38B 1
|
|
00D38B 1 Routine_D38B_FindIndex: ; $D38B
|
|
00D38B 1 C8 iny ; $D38B: C8
|
|
00D38C 1 4A lsr ; $D38C: 4A
|
|
00D38D 1 90 FC bcc Routine_D38B_FindIndex ; $D38D: 90 FC
|
|
00D38F 1
|
|
00D38F 1 84 05 sty MathTemp05 ; $D38F: 84 05
|
|
00D391 1
|
|
00D391 1 ; ----------------------------------------------------------------------------
|
|
00D391 1 ; Load a signed horizontal offset from the table at $D3F0.
|
|
00D391 1 ;
|
|
00D391 1 ; X is used as the sign-extension byte:
|
|
00D391 1 ;
|
|
00D391 1 ; X = $00 for nonnegative offsets
|
|
00D391 1 ; X = $FF for negative offsets
|
|
00D391 1 ; ----------------------------------------------------------------------------
|
|
00D391 1
|
|
00D391 1 A2 00 ldx #$00 ; $D391: A2 00
|
|
00D393 1
|
|
00D393 1 B9 F0 D3 lda ControlledHorizontalOffsetTable,y ; $D393: B9 F0 D3
|
|
00D396 1 10 01 bpl Routine_D399_AddHorizontal
|
|
00D398 1 ; $D396: 10 01
|
|
00D398 1
|
|
00D398 1 CA dex ; $D398: CA
|
|
00D399 1 ; X = $FF
|
|
00D399 1
|
|
00D399 1 Routine_D399_AddHorizontal: ; $D399
|
|
00D399 1 18 clc ; $D399: 18
|
|
00D39A 1
|
|
00D39A 1 6D 0F 05 adc $050F ; $D39A: 6D 0F 05
|
|
00D39D 1 A8 tay ; $D39D: A8
|
|
00D39E 1 85 AE sta CalculatedCoordinateLow ; $D39E: 85 AE
|
|
00D3A0 1
|
|
00D3A0 1 8A txa ; $D3A0: 8A
|
|
00D3A1 1 6D 10 05 adc $0510 ; $D3A1: 6D 10 05
|
|
00D3A4 1 85 AF sta CalculatedCoordinateHigh ; $D3A4: 85 AF
|
|
00D3A6 1
|
|
00D3A6 1 ; ----------------------------------------------------------------------------
|
|
00D3A6 1 ; Normalize or transform the signed horizontal coordinate in A:Y.
|
|
00D3A6 1 ; ----------------------------------------------------------------------------
|
|
00D3A6 1
|
|
00D3A6 1 20 CB E7 jsr AbsoluteValueAY ; $D3A6: 20 CB E7
|
|
00D3A9 1 AA tax ; $D3A9: AA
|
|
00D3AA 1
|
|
00D3AA 1 ; ----------------------------------------------------------------------------
|
|
00D3AA 1 ; Accept the new horizontal coordinate only when it lies inside the permitted
|
|
00D3AA 1 ; range.
|
|
00D3AA 1 ;
|
|
00D3AA 1 ; The two-stage signed test uses Y as the low byte and X/A as the high byte.
|
|
00D3AA 1 ; ----------------------------------------------------------------------------
|
|
00D3AA 1
|
|
00D3AA 1 C0 60 cpy #$60 ; $D3AA: C0 60
|
|
00D3AC 1 E9 01 sbc #$01 ; $D3AC: E9 01
|
|
00D3AE 1 10 11 bpl Routine_D3C1_Vertical ; $D3AE: 10 11
|
|
00D3B0 1
|
|
00D3B0 1 8A txa ; $D3B0: 8A
|
|
00D3B1 1
|
|
00D3B1 1 C0 00 cpy #$00 ; $D3B1: C0 00
|
|
00D3B3 1 E9 01 sbc #$01 ; $D3B3: E9 01
|
|
00D3B5 1 30 0A bmi Routine_D3C1_Vertical ; $D3B5: 30 0A
|
|
00D3B7 1
|
|
00D3B7 1 A5 AE lda CalculatedCoordinateLow ; $D3B7: A5 AE
|
|
00D3B9 1 8D 0F 05 sta $050F ; $D3B9: 8D 0F 05
|
|
00D3BC 1
|
|
00D3BC 1 A5 AF lda CalculatedCoordinateHigh ; $D3BC: A5 AF
|
|
00D3BE 1 8D 10 05 sta $0510 ; $D3BE: 8D 10 05
|
|
00D3C1 1
|
|
00D3C1 1 ; ----------------------------------------------------------------------------
|
|
00D3C1 1 ; Load a signed vertical offset from the overlapping table at $D3F3.
|
|
00D3C1 1 ; ----------------------------------------------------------------------------
|
|
00D3C1 1
|
|
00D3C1 1 Routine_D3C1_Vertical: ; $D3C1
|
|
00D3C1 1 A4 05 ldy MathTemp05 ; $D3C1: A4 05
|
|
00D3C3 1 A2 00 ldx #$00 ; $D3C3: A2 00
|
|
00D3C5 1
|
|
00D3C5 1 B9 F3 D3 lda ControlledVerticalOffsetTable,y ; $D3C5: B9 F3 D3
|
|
00D3C8 1 10 01 bpl Routine_D3CB_AddVertical
|
|
00D3CA 1 ; $D3C8: 10 01
|
|
00D3CA 1
|
|
00D3CA 1 CA dex ; $D3CA: CA
|
|
00D3CB 1 ; X = $FF
|
|
00D3CB 1
|
|
00D3CB 1 Routine_D3CB_AddVertical: ; $D3CB
|
|
00D3CB 1 18 clc ; $D3CB: 18
|
|
00D3CC 1
|
|
00D3CC 1 6D 40 05 adc $0540 ; $D3CC: 6D 40 05
|
|
00D3CF 1 A8 tay ; $D3CF: A8
|
|
00D3D0 1
|
|
00D3D0 1 8A txa ; $D3D0: 8A
|
|
00D3D1 1 6D 41 05 adc $0541 ; $D3D1: 6D 41 05
|
|
00D3D4 1 AA tax ; $D3D4: AA
|
|
00D3D5 1
|
|
00D3D5 1 ; ----------------------------------------------------------------------------
|
|
00D3D5 1 ; Accept the vertical coordinate only when it lies inside the permitted range.
|
|
00D3D5 1 ; ----------------------------------------------------------------------------
|
|
00D3D5 1
|
|
00D3D5 1 C0 C0 cpy #$C0 ; $D3D5: C0 C0
|
|
00D3D7 1 E9 F8 sbc #$F8 ; $D3D7: E9 F8
|
|
00D3D9 1 10 0D bpl Routine_D3E8_UpdateObject
|
|
00D3DB 1 ; $D3D9: 10 0D
|
|
00D3DB 1
|
|
00D3DB 1 8A txa ; $D3DB: 8A
|
|
00D3DC 1
|
|
00D3DC 1 C0 A0 cpy #$A0 ; $D3DC: C0 A0
|
|
00D3DE 1 E9 F7 sbc #$F7 ; $D3DE: E9 F7
|
|
00D3E0 1 30 06 bmi Routine_D3E8_UpdateObject
|
|
00D3E2 1 ; $D3E0: 30 06
|
|
00D3E2 1
|
|
00D3E2 1 8C 40 05 sty $0540 ; $D3E2: 8C 40 05
|
|
00D3E5 1 8E 41 05 stx $0541 ; $D3E5: 8E 41 05
|
|
00D3E8 1
|
|
00D3E8 1 ; ----------------------------------------------------------------------------
|
|
00D3E8 1 ; Update object six, then repeat the routine.
|
|
00D3E8 1 ; ----------------------------------------------------------------------------
|
|
00D3E8 1
|
|
00D3E8 1 Routine_D3E8_UpdateObject: ; $D3E8
|
|
00D3E8 1 A2 06 ldx #$06 ; $D3E8: A2 06
|
|
00D3EA 1 20 B7 E6 jsr ClearMovementTransforms ; $D3EA: 20 B7 E6
|
|
00D3ED 1
|
|
00D3ED 1 4C 82 D3 jmp MoveControlledObject ; $D3ED: 4C 82 D3
|
|
00D3F0 1
|
|
00D3F0 1 ; ============================================================================
|
|
00D3F0 1 ; Temporary aliases for the lookup data immediately following the routine.
|
|
00D3F0 1 ; Remove these aliases when the $D3F0 data block is decoded.
|
|
00D3F0 1 ; ============================================================================
|
|
00D3F0 1
|
|
00D3F0 1 ControlledHorizontalOffsetTable: ; $D3F0
|
|
00D3F0 1 01 FF 00 .byte $01,$FF,$00
|
|
00D3F3 1
|
|
00D3F3 1 ControlledVerticalOffsetTable: ; $D3F3
|
|
00D3F3 1 00 00 FF 01 .byte $00,$00,$FF,$01,$00
|
|
00D3F7 1 00
|
|
00D3F8 1
|
|
00D3F8 1 ; ============================================================================
|
|
00D3F8 1 ; $D3F8-$D477
|
|
00D3F8 1 ; Randomized timing and coordinate-validation routine.
|
|
00D3F8 1 ; ============================================================================
|
|
00D3F8 1
|
|
00D3F8 1 RunControlledActorDelay: ; $D3F8
|
|
00D3F8 1 A9 14 lda #$14 ; $D3F8: A9 14
|
|
00D3FA 1 85 92 sta ActionDelayCounter ; $D3FA: 85 92
|
|
00D3FC 1
|
|
00D3FC 1 ; ----------------------------------------------------------------------------
|
|
00D3FC 1 ; Run $EB4C twenty times while setting $13 to $80 between iterations.
|
|
00D3FC 1 ; ----------------------------------------------------------------------------
|
|
00D3FC 1
|
|
00D3FC 1 Routine_D3FC_InitialDelay: ; $D3FC
|
|
00D3FC 1 20 4C EB jsr SelectObjectEventBank0 ; $D3FC: 20 4C EB
|
|
00D3FF 1
|
|
00D3FF 1 A9 80 lda #$80 ; $D3FF: A9 80
|
|
00D401 1 85 13 sta InputState1 ; $D401: 85 13
|
|
00D403 1
|
|
00D403 1 C6 92 dec ActionDelayCounter ; $D403: C6 92
|
|
00D405 1 D0 F5 bne Routine_D3FC_InitialDelay
|
|
00D407 1 ; $D405: D0 F5
|
|
00D407 1
|
|
00D407 1 ; ----------------------------------------------------------------------------
|
|
00D407 1 ; Generate a random value from zero through ten.
|
|
00D407 1 ; ----------------------------------------------------------------------------
|
|
00D407 1
|
|
00D407 1 SelectControlledActorDelay: ; $D407
|
|
00D407 1 20 F5 E5 jsr AdvanceRandomState ; $D407: 20 F5 E5
|
|
00D40A 1
|
|
00D40A 1 29 0F and #$0F ; $D40A: 29 0F
|
|
00D40C 1 C9 0B cmp #$0B ; $D40C: C9 0B
|
|
00D40E 1 B0 F7 bcs SelectControlledActorDelay
|
|
00D410 1 ; $D40E: B0 F7
|
|
00D410 1
|
|
00D410 1 ; ----------------------------------------------------------------------------
|
|
00D410 1 ; Convert values ten and below into a signed countdown-like value.
|
|
00D410 1 ;
|
|
00D410 1 ; Carry remains set after CMP when A is ten, otherwise it is clear. The
|
|
00D410 1 ; subtraction intentionally uses that carry state.
|
|
00D410 1 ; ----------------------------------------------------------------------------
|
|
00D410 1
|
|
00D410 1 E9 0A sbc #$0A ; $D410: E9 0A
|
|
00D412 1 85 92 sta ActionDelayCounter ; $D412: 85 92
|
|
00D414 1
|
|
00D414 1 ; ----------------------------------------------------------------------------
|
|
00D414 1 ; Wait until the high position byte at $053B becomes negative.
|
|
00D414 1 ; ----------------------------------------------------------------------------
|
|
00D414 1
|
|
00D414 1 WaitForActorAscent: ; $D414
|
|
00D414 1 20 48 EB jsr SelectObjectEventBank1 ; $D414: 20 48 EB
|
|
00D417 1
|
|
00D417 1 AE 3B 05 ldx $053B ; $D417: AE 3B 05
|
|
00D41A 1 CA dex ; $D41A: CA
|
|
00D41B 1 10 F7 bpl WaitForActorAscent
|
|
00D41D 1 ; $D41B: 10 F7
|
|
00D41D 1
|
|
00D41D 1 ; ----------------------------------------------------------------------------
|
|
00D41D 1 ; Increment the countdown and wait until $053B reaches at least $FD.
|
|
00D41D 1 ; ----------------------------------------------------------------------------
|
|
00D41D 1
|
|
00D41D 1 WaitForActorDescent: ; $D41D
|
|
00D41D 1 E6 92 inc ActionDelayCounter ; $D41D: E6 92
|
|
00D41F 1
|
|
00D41F 1 20 48 EB jsr SelectObjectEventBank1 ; $D41F: 20 48 EB
|
|
00D422 1
|
|
00D422 1 AD 3B 05 lda $053B ; $D422: AD 3B 05
|
|
00D425 1 C9 FD cmp #$FD ; $D425: C9 FD
|
|
00D427 1 10 F4 bpl WaitForActorDescent
|
|
00D429 1 ; $D427: 10 F4
|
|
00D429 1
|
|
00D429 1 ; ----------------------------------------------------------------------------
|
|
00D429 1 ; Generate a random byte. Values below two take the alternate timing path.
|
|
00D429 1 ; ----------------------------------------------------------------------------
|
|
00D429 1
|
|
00D429 1 20 F5 E5 jsr AdvanceRandomState ; $D429: 20 F5 E5
|
|
00D42C 1
|
|
00D42C 1 C9 02 cmp #$02 ; $D42C: C9 02
|
|
00D42E 1 90 31 bcc SelectActorAlternateDelay
|
|
00D430 1 ; $D42E: 90 31
|
|
00D430 1
|
|
00D430 1 ; ----------------------------------------------------------------------------
|
|
00D430 1 ; Normalize the current horizontal position in A:Y.
|
|
00D430 1 ; ----------------------------------------------------------------------------
|
|
00D430 1
|
|
00D430 1 AA tax ; $D430: AA
|
|
00D431 1
|
|
00D431 1 AC 09 05 ldy $0509 ; $D431: AC 09 05
|
|
00D434 1 AD 0A 05 lda $050A ; $D434: AD 0A 05
|
|
00D437 1
|
|
00D437 1 20 CB E7 jsr AbsoluteValueAY ; $D437: 20 CB E7
|
|
00D43A 1
|
|
00D43A 1 ; ----------------------------------------------------------------------------
|
|
00D43A 1 ; Validate the normalized coordinate against two bounds.
|
|
00D43A 1 ;
|
|
00D43A 1 ; X still contains the random byte selected at $D429.
|
|
00D43A 1 ; ----------------------------------------------------------------------------
|
|
00D43A 1
|
|
00D43A 1 E0 DC cpx #$DC ; $D43A: E0 DC
|
|
00D43C 1 B0 37 bcs FinishControlledActorDelay ; $D43C: B0 37
|
|
00D43E 1
|
|
00D43E 1 C0 20 cpy #$20 ; $D43E: C0 20
|
|
00D440 1 E9 00 sbc #$00 ; $D440: E9 00
|
|
00D442 1 90 04 bcc RunActorDelayCountdown ; $D442: 90 04
|
|
00D444 1
|
|
00D444 1 E0 38 cpx #$38 ; $D444: E0 38
|
|
00D446 1 B0 2D bcs FinishControlledActorDelay ; $D446: B0 2D
|
|
00D448 1
|
|
00D448 1 ; ----------------------------------------------------------------------------
|
|
00D448 1 ; Wait while counting $92 down through zero.
|
|
00D448 1 ; ----------------------------------------------------------------------------
|
|
00D448 1
|
|
00D448 1 RunActorDelayCountdown: ; $D448
|
|
00D448 1 20 48 EB jsr SelectObjectEventBank1 ; $D448: 20 48 EB
|
|
00D44B 1
|
|
00D44B 1 C6 92 dec ActionDelayCounter ; $D44B: C6 92
|
|
00D44D 1 10 F9 bpl RunActorDelayCountdown ; $D44D: 10 F9
|
|
00D44F 1
|
|
00D44F 1 ; ----------------------------------------------------------------------------
|
|
00D44F 1 ; Run another fixed twenty-iteration delay.
|
|
00D44F 1 ; ----------------------------------------------------------------------------
|
|
00D44F 1
|
|
00D44F 1 A9 14 lda #$14 ; $D44F: A9 14
|
|
00D451 1 85 92 sta ActionDelayCounter ; $D451: 85 92
|
|
00D453 1
|
|
00D453 1 RunActorFinalDelay: ; $D453
|
|
00D453 1 20 4C EB jsr SelectObjectEventBank0 ; $D453: 20 4C EB
|
|
00D456 1
|
|
00D456 1 A9 80 lda #$80 ; $D456: A9 80
|
|
00D458 1 85 13 sta InputState1 ; $D458: 85 13
|
|
00D45A 1
|
|
00D45A 1 C6 92 dec ActionDelayCounter ; $D45A: C6 92
|
|
00D45C 1 D0 F5 bne RunActorFinalDelay ; $D45C: D0 F5
|
|
00D45E 1
|
|
00D45E 1 4C 6A EB jmp CommonEngineExit ; $D45E: 4C 6A EB
|
|
00D461 1
|
|
00D461 1 ; ----------------------------------------------------------------------------
|
|
00D461 1 ; Alternate randomized delay path for values below two.
|
|
00D461 1 ; ----------------------------------------------------------------------------
|
|
00D461 1
|
|
00D461 1 SelectActorAlternateDelay: ; $D461
|
|
00D461 1 20 F5 E5 jsr AdvanceRandomState ; $D461: 20 F5 E5
|
|
00D464 1
|
|
00D464 1 29 07 and #$07 ; $D464: 29 07
|
|
00D466 1 69 04 adc #$04 ; $D466: 69 04
|
|
00D468 1 85 92 sta ActionDelayCounter ; $D468: 85 92
|
|
00D46A 1
|
|
00D46A 1 RunActorAlternateDelay: ; $D46A
|
|
00D46A 1 20 4C EB jsr SelectObjectEventBank0 ; $D46A: 20 4C EB
|
|
00D46D 1
|
|
00D46D 1 A9 80 lda #$80 ; $D46D: A9 80
|
|
00D46F 1 85 13 sta InputState1 ; $D46F: 85 13
|
|
00D471 1
|
|
00D471 1 C6 92 dec ActionDelayCounter ; $D471: C6 92
|
|
00D473 1 D0 F5 bne RunActorAlternateDelay
|
|
00D475 1 ; $D473: D0 F5
|
|
00D475 1
|
|
00D475 1 FinishControlledActorDelay: ; $D475
|
|
00D475 1 4C 6A EB jmp CommonEngineExit ; $D475: 4C 6A EB
|
|
00D478 1
|
|
00D478 1 ; ============================================================================
|
|
00D478 1 ; $D478-$D4FE
|
|
00D478 1 ; Initialize object six, transform coordinates, and run a state-controlled
|
|
00D478 1 ; animation loop.
|
|
00D478 1 ; ============================================================================
|
|
00D478 1
|
|
00D478 1 RunFielderAnimationSequence: ; $D478
|
|
00D478 1 A9 00 lda #$00 ; $D478: A9 00
|
|
00D47A 1 85 87 sta ObjectProximityState ; $D47A: 85 87
|
|
00D47C 1
|
|
00D47C 1 ; ----------------------------------------------------------------------------
|
|
00D47C 1 ; Initialize indexed fields for object offset $06.
|
|
00D47C 1 ;
|
|
00D47C 1 ; Routine $C9A7 consumes five inline bytes:
|
|
00D47C 1 ;
|
|
00D47C 1 ; $06 object offset/metadata
|
|
00D47C 1 ; $F0,$FE,$20,$F8 four field values
|
|
00D47C 1 ; ----------------------------------------------------------------------------
|
|
00D47C 1
|
|
00D47C 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D47F 1 ; $D47C: 20 A7 C9
|
|
00D47F 1
|
|
00D47F 1 06 .byte $06 ; $D47F
|
|
00D480 1 F0 FE 20 F8 .byte $F0,$FE,$20,$F8 ; $D480-$D483
|
|
00D484 1
|
|
00D484 1 ; ----------------------------------------------------------------------------
|
|
00D484 1 ; XOR both bytes of the coordinate at $050F/$0510 with $4C.
|
|
00D484 1 ; ----------------------------------------------------------------------------
|
|
00D484 1
|
|
00D484 1 AD 0F 05 lda $050F ; $D484: AD 0F 05
|
|
00D487 1 45 4C eor HorizontalDirectionMask ; $D487: 45 4C
|
|
00D489 1 8D 0F 05 sta $050F ; $D489: 8D 0F 05
|
|
00D48C 1
|
|
00D48C 1 AD 10 05 lda $0510 ; $D48C: AD 10 05
|
|
00D48F 1 45 4C eor HorizontalDirectionMask ; $D48F: 45 4C
|
|
00D491 1 8D 10 05 sta $0510 ; $D491: 8D 10 05
|
|
00D494 1
|
|
00D494 1 ; ----------------------------------------------------------------------------
|
|
00D494 1 ; Initialize animation and timing state.
|
|
00D494 1 ; ----------------------------------------------------------------------------
|
|
00D494 1
|
|
00D494 1 A9 00 lda #$00 ; $D494: A9 00
|
|
00D496 1 8D B3 03 sta $03B3 ; $D496: 8D B3 03
|
|
00D499 1
|
|
00D499 1 A9 1E lda #$1E ; $D499: A9 1E
|
|
00D49B 1 20 41 EB jsr StoreObjectEventBankValue ; $D49B: 20 41 EB
|
|
00D49E 1
|
|
00D49E 1 ; ----------------------------------------------------------------------------
|
|
00D49E 1 ; Shared loop restart point.
|
|
00D49E 1 ; ----------------------------------------------------------------------------
|
|
00D49E 1
|
|
00D49E 1 ResetFielderAnimationCounters: ; $D49E
|
|
00D49E 1 A9 00 lda #$00 ; $D49E: A9 00
|
|
00D4A0 1 85 8D sta FielderInputBalance ; $D4A0: 85 8D
|
|
00D4A2 1
|
|
00D4A2 1 A9 0B lda #$0B ; $D4A2: A9 0B
|
|
00D4A4 1 85 8C sta FielderAnimationCountdown ; $D4A4: 85 8C
|
|
00D4A6 1
|
|
00D4A6 1 ; ----------------------------------------------------------------------------
|
|
00D4A6 1 ; Wait until $13 becomes negative.
|
|
00D4A6 1 ; ----------------------------------------------------------------------------
|
|
00D4A6 1
|
|
00D4A6 1 WaitForFielderInput: ; $D4A6
|
|
00D4A6 1 20 48 EB jsr SelectObjectEventBank1 ; $D4A6: 20 48 EB
|
|
00D4A9 1
|
|
00D4A9 1 A5 13 lda InputState1 ; $D4A9: A5 13
|
|
00D4AB 1 10 F9 bpl WaitForFielderInput
|
|
00D4AD 1 ; $D4AB: 10 F9
|
|
00D4AD 1
|
|
00D4AD 1 ; ----------------------------------------------------------------------------
|
|
00D4AD 1 ; Initialize the per-cycle counter and advance the animation.
|
|
00D4AD 1 ; ----------------------------------------------------------------------------
|
|
00D4AD 1
|
|
00D4AD 1 AdvanceFielderAnimationCycle: ; $D4AD
|
|
00D4AD 1 A9 03 lda #$03 ; $D4AD: A9 03
|
|
00D4AF 1 85 0C sta $0C ; $D4AF: 85 0C
|
|
00D4B1 1
|
|
00D4B1 1 EE B3 03 inc $03B3 ; $D4B1: EE B3 03
|
|
00D4B4 1
|
|
00D4B4 1 ; ----------------------------------------------------------------------------
|
|
00D4B4 1 ; A state condition at $82/$87 can branch to the next routine at $D4FF.
|
|
00D4B4 1 ; ----------------------------------------------------------------------------
|
|
00D4B4 1
|
|
00D4B4 1 CheckFielderAnimationState: ; $D4B4
|
|
00D4B4 1 A5 82 lda ActorActionComplete ; $D4B4: A5 82
|
|
00D4B6 1 D0 06 bne UpdateFielderAnimationFrame ; $D4B6: D0 06
|
|
00D4B8 1
|
|
00D4B8 1 A5 87 lda ObjectProximityState ; $D4B8: A5 87
|
|
00D4BA 1 C9 01 cmp #$01 ; $D4BA: C9 01
|
|
00D4BC 1 F0 41 beq SelectRandomMotionParameters ; $D4BC: F0 41
|
|
00D4BE 1
|
|
00D4BE 1 ; ----------------------------------------------------------------------------
|
|
00D4BE 1 ; Wait one frame and compare the animation value against five.
|
|
00D4BE 1 ; ----------------------------------------------------------------------------
|
|
00D4BE 1
|
|
00D4BE 1 UpdateFielderAnimationFrame: ; $D4BE
|
|
00D4BE 1 20 48 EB jsr SelectObjectEventBank1 ; $D4BE: 20 48 EB
|
|
00D4C1 1
|
|
00D4C1 1 38 sec ; $D4C1: 38
|
|
00D4C2 1
|
|
00D4C2 1 AD B3 03 lda $03B3 ; $D4C2: AD B3 03
|
|
00D4C5 1 E9 05 sbc #$05 ; $D4C5: E9 05
|
|
00D4C7 1 F0 1E beq ReverseFielderAnimation ; $D4C7: F0 1E
|
|
00D4C9 1
|
|
00D4C9 1 ; ----------------------------------------------------------------------------
|
|
00D4C9 1 ; Adjust $8D according to the sign of $13.
|
|
00D4C9 1 ; ----------------------------------------------------------------------------
|
|
00D4C9 1
|
|
00D4C9 1 A5 13 lda InputState1 ; $D4C9: A5 13
|
|
00D4CB 1 30 08 bmi UpdateFielderAnimationCounters
|
|
00D4CD 1 ; $D4CB: 30 08
|
|
00D4CD 1
|
|
00D4CD 1 C6 8D dec FielderInputBalance ; $D4CD: C6 8D
|
|
00D4CF 1 10 E3 bpl CheckFielderAnimationState ; $D4CF: 10 E3
|
|
00D4D1 1
|
|
00D4D1 1 E6 8D inc FielderInputBalance ; $D4D1: E6 8D
|
|
00D4D3 1 10 DF bpl CheckFielderAnimationState ; $D4D3: 10 DF
|
|
00D4D5 1
|
|
00D4D5 1 ; ----------------------------------------------------------------------------
|
|
00D4D5 1 ; Update loop counters.
|
|
00D4D5 1 ; ----------------------------------------------------------------------------
|
|
00D4D5 1
|
|
00D4D5 1 UpdateFielderAnimationCounters: ; $D4D5
|
|
00D4D5 1 E6 8D inc FielderInputBalance ; $D4D5: E6 8D
|
|
00D4D7 1
|
|
00D4D7 1 C6 8C dec FielderAnimationCountdown ; $D4D7: C6 8C
|
|
00D4D9 1 C6 0C dec $0C ; $D4D9: C6 0C
|
|
00D4DB 1 D0 D7 bne CheckFielderAnimationState ; $D4DB: D0 D7
|
|
00D4DD 1
|
|
00D4DD 1 ; ----------------------------------------------------------------------------
|
|
00D4DD 1 ; Repeat until the animation value reaches five.
|
|
00D4DD 1 ; ----------------------------------------------------------------------------
|
|
00D4DD 1
|
|
00D4DD 1 AE B3 03 ldx $03B3 ; $D4DD: AE B3 03
|
|
00D4E0 1 E0 05 cpx #$05 ; $D4E0: E0 05
|
|
00D4E2 1 F0 DA beq UpdateFielderAnimationFrame ; $D4E2: F0 DA
|
|
00D4E4 1
|
|
00D4E4 1 4C AD D4 jmp AdvanceFielderAnimationCycle ; $D4E4: 4C AD D4
|
|
00D4E7 1
|
|
00D4E7 1 ; ----------------------------------------------------------------------------
|
|
00D4E7 1 ; Handle animation value five.
|
|
00D4E7 1 ; ----------------------------------------------------------------------------
|
|
00D4E7 1
|
|
00D4E7 1 ReverseFielderAnimation: ; $D4E7
|
|
00D4E7 1 85 8D sta FielderInputBalance ; $D4E7: 85 8D
|
|
00D4E9 1 ; A is zero after SBC #$05 succeeded.
|
|
00D4E9 1
|
|
00D4E9 1 A5 13 lda InputState1 ; $D4E9: A5 13
|
|
00D4EB 1 30 D1 bmi UpdateFielderAnimationFrame ; $D4EB: 30 D1
|
|
00D4ED 1
|
|
00D4ED 1 CE B3 03 dec $03B3 ; $D4ED: CE B3 03
|
|
00D4F0 1
|
|
00D4F0 1 A9 02 lda #$02 ; $D4F0: A9 02
|
|
00D4F2 1 20 41 EB jsr StoreObjectEventBankValue ; $D4F2: 20 41 EB
|
|
00D4F5 1
|
|
00D4F5 1 AD B3 03 lda $03B3 ; $D4F5: AD B3 03
|
|
00D4F8 1 C9 00 cmp #$00 ; $D4F8: C9 00
|
|
00D4FA 1 D0 EB bne ReverseFielderAnimation ; $D4FA: D0 EB
|
|
00D4FC 1
|
|
00D4FC 1 4C 9E D4 jmp ResetFielderAnimationCounters
|
|
00D4FF 1 ; $D4FC: 4C 9E D4
|
|
00D4FF 1
|
|
00D4FF 1
|
|
00D4FF 1 ; ============================================================================
|
|
00D4FF 1 ; $D4FF-$D51B
|
|
00D4FF 1 ; Select a threshold index and calculate a randomized value.
|
|
00D4FF 1 ; ============================================================================
|
|
00D4FF 1
|
|
00D4FF 1 SelectRandomMotionParameters: ; $D4FF
|
|
00D4FF 1 A2 05 ldx #$05 ; $D4FF: A2 05
|
|
00D501 1
|
|
00D501 1 ; ----------------------------------------------------------------------------
|
|
00D501 1 ; Generate one random value.
|
|
00D501 1 ;
|
|
00D501 1 ; The same random value is compared against multiple thresholds while X
|
|
00D501 1 ; counts downward. The loop at $D50A returns to the CMP at $D504, not to the
|
|
00D501 1 ; random-number call.
|
|
00D501 1 ; ----------------------------------------------------------------------------
|
|
00D501 1
|
|
00D501 1 20 F5 E5 jsr AdvanceRandomState ; $D501: 20 F5 E5
|
|
00D504 1
|
|
00D504 1 SearchMotionThreshold: ; $D504
|
|
00D504 1 DD BD D5 cmp $D5BD,x ; $D504: DD BD D5
|
|
00D507 1 B0 07 bcs StartRandomMotion ; $D507: B0 07
|
|
00D509 1
|
|
00D509 1 CA dex ; $D509: CA
|
|
00D50A 1 D0 F8 bne SearchMotionThreshold
|
|
00D50C 1 ; $D50A: D0 F8
|
|
00D50C 1
|
|
00D50C 1 ; ----------------------------------------------------------------------------
|
|
00D50C 1 ; No nonzero threshold index was selected.
|
|
00D50C 1 ;
|
|
00D50C 1 ; X is zero here. Save it to $81 and branch back to the earlier wait loop.
|
|
00D50C 1 ; ----------------------------------------------------------------------------
|
|
00D50C 1
|
|
00D50C 1 86 81 stx RandomValue81 ; $D50C: 86 81
|
|
00D50E 1 F0 AE beq UpdateFielderAnimationFrame ; $D50E: F0 AE
|
|
00D510 1 ; Always taken because X is zero.
|
|
00D510 1
|
|
00D510 1 ; ----------------------------------------------------------------------------
|
|
00D510 1 ; A threshold was selected.
|
|
00D510 1 ;
|
|
00D510 1 ; Advance state and combine a new random value with the indexed base value at
|
|
00D510 1 ; $D5B8,X.
|
|
00D510 1 ; ----------------------------------------------------------------------------
|
|
00D510 1
|
|
00D510 1 StartRandomMotion: ; $D510
|
|
00D510 1 E6 46 inc StateSequenceActive ; $D510: E6 46
|
|
00D512 1
|
|
00D512 1 20 F5 E5 jsr AdvanceRandomState ; $D512: 20 F5 E5
|
|
00D515 1 29 1F and #$1F ; $D515: 29 1F
|
|
00D517 1
|
|
00D517 1 7D B8 D5 adc $D5B8,x ; $D517: 7D B8 D5
|
|
00D51A 1 85 8E sta RandomHorizontalMotion ; $D51A: 85 8E
|
|
00D51C 1
|
|
00D51C 1 ; ============================================================================
|
|
00D51C 1 ; $D51C-$D53F
|
|
00D51C 1 ; Select a second table index and perform the first signed calculation.
|
|
00D51C 1 ; ============================================================================
|
|
00D51C 1
|
|
00D51C 1 A2 0A ldx #$0A ; $D51C: A2 0A
|
|
00D51E 1
|
|
00D51E 1 A5 8D lda FielderInputBalance ; $D51E: A5 8D
|
|
00D520 1 85 88 sta MotionDirectionState ; $D520: 85 88
|
|
00D522 1 F0 09 beq SelectRandomMotionOffset
|
|
00D524 1 ; $D522: F0 09
|
|
00D524 1
|
|
00D524 1 ; ----------------------------------------------------------------------------
|
|
00D524 1 ; Generate random values until one satisfies a threshold selected from the
|
|
00D524 1 ; table using base address $D5CE.
|
|
00D524 1 ;
|
|
00D524 1 ; X is decremented before each comparison.
|
|
00D524 1 ; ----------------------------------------------------------------------------
|
|
00D524 1
|
|
00D524 1 SearchMotionAngleThreshold: ; $D524
|
|
00D524 1 20 F5 E5 jsr AdvanceRandomState ; $D524: 20 F5 E5
|
|
00D527 1
|
|
00D527 1 CompareMotionAngleThreshold: ; $D527
|
|
00D527 1 CA dex ; $D527: CA
|
|
00D528 1
|
|
00D528 1 DD CE D5 cmp $D5CE,x ; $D528: DD CE D5
|
|
00D52B 1 90 FA bcc CompareMotionAngleThreshold
|
|
00D52D 1 ; $D52B: 90 FA
|
|
00D52D 1
|
|
00D52D 1 ; ----------------------------------------------------------------------------
|
|
00D52D 1 ; Generate another random value. Its low bit is added to the indexed value
|
|
00D52D 1 ; read using table base $D5C3.
|
|
00D52D 1 ; ----------------------------------------------------------------------------
|
|
00D52D 1
|
|
00D52D 1 SelectRandomMotionOffset: ; $D52D
|
|
00D52D 1 20 F5 E5 jsr AdvanceRandomState ; $D52D: 20 F5 E5
|
|
00D530 1
|
|
00D530 1 29 01 and #$01 ; $D530: 29 01
|
|
00D532 1 7D C3 D5 adc $D5C3,x ; $D532: 7D C3 D5
|
|
00D535 1 A8 tay ; $D535: A8
|
|
00D536 1
|
|
00D536 1 ; ----------------------------------------------------------------------------
|
|
00D536 1 ; Pass A = $8E, X = 0, and the selected Y value to the math helper at $E855.
|
|
00D536 1 ;
|
|
00D536 1 ; Save the returned Y value in $8F and preserve A on the stack.
|
|
00D536 1 ; ----------------------------------------------------------------------------
|
|
00D536 1
|
|
00D536 1 A2 00 ldx #$00 ; $D536: A2 00
|
|
00D538 1
|
|
00D538 1 A5 8E lda RandomHorizontalMotion ; $D538: A5 8E
|
|
00D53A 1 20 55 E8 jsr CalculateVectorFromRotatedMask ; $D53A: 20 55 E8
|
|
00D53D 1
|
|
00D53D 1 84 8F sty CalculatedVerticalMotion ; $D53D: 84 8F
|
|
00D53F 1 48 pha ; $D53F: 48
|
|
00D540 1
|
|
00D540 1 ; ============================================================================
|
|
00D540 1 ; $D540-$D560
|
|
00D540 1 ; Construct a randomized signed value in $90, perform a second calculation,
|
|
00D540 1 ; then pass both calculated values to InitializeBaseMotion.
|
|
00D540 1 ;
|
|
00D540 1 ; Entry:
|
|
00D540 1 ; A contains the first result from $E855, preserved on the stack.
|
|
00D540 1 ; Y contains the corresponding secondary result.
|
|
00D540 1 ; ============================================================================
|
|
00D540 1
|
|
00D540 1 38 sec ; $D540: 38
|
|
00D541 1
|
|
00D541 1 A5 8C lda FielderAnimationCountdown ; $D541: A5 8C
|
|
00D543 1 E9 05 sbc #$05 ; $D543: E9 05
|
|
00D545 1
|
|
00D545 1 ; ----------------------------------------------------------------------------
|
|
00D545 1 ; Scale the signed result.
|
|
00D545 1 ;
|
|
00D545 1 ; SEC followed by ROL shifts the value left while forcing bit zero to one.
|
|
00D545 1 ; Three additional ASL instructions multiply the result by eight.
|
|
00D545 1 ; ----------------------------------------------------------------------------
|
|
00D545 1
|
|
00D545 1 38 sec ; $D545: 38
|
|
00D546 1 2A rol ; $D546: 2A
|
|
00D547 1 0A asl ; $D547: 0A
|
|
00D548 1 0A asl ; $D548: 0A
|
|
00D549 1 0A asl ; $D549: 0A
|
|
00D54A 1
|
|
00D54A 1 85 90 sta RandomVerticalMotion ; $D54A: 85 90
|
|
00D54C 1
|
|
00D54C 1 ; ----------------------------------------------------------------------------
|
|
00D54C 1 ; Add a random five-bit value, then conditionally mirror/sign-adjust it using
|
|
00D54C 1 ; the value at $4C.
|
|
00D54C 1 ; ----------------------------------------------------------------------------
|
|
00D54C 1
|
|
00D54C 1 20 F5 E5 jsr AdvanceRandomState ; $D54C: 20 F5 E5
|
|
00D54F 1 29 1F and #$1F ; $D54F: 29 1F
|
|
00D551 1
|
|
00D551 1 65 90 adc RandomVerticalMotion ; $D551: 65 90
|
|
00D553 1 45 4C eor HorizontalDirectionMask ; $D553: 45 4C
|
|
00D555 1 85 90 sta RandomVerticalMotion ; $D555: 85 90
|
|
00D557 1
|
|
00D557 1 ; ----------------------------------------------------------------------------
|
|
00D557 1 ; Run the signed math helper again.
|
|
00D557 1 ;
|
|
00D557 1 ; X is cleared, A contains $90, and Y remains the result from the previous
|
|
00D557 1 ; $E855 call.
|
|
00D557 1 ; ----------------------------------------------------------------------------
|
|
00D557 1
|
|
00D557 1 A2 00 ldx #$00 ; $D557: A2 00
|
|
00D559 1
|
|
00D559 1 20 55 E8 jsr CalculateVectorFromRotatedMask ; $D559: 20 55 E8
|
|
00D55C 1 AA tax ; $D55C: AA
|
|
00D55D 1 ; Preserve the second result in X.
|
|
00D55D 1
|
|
00D55D 1 68 pla ; $D55D: 68
|
|
00D55E 1 ; Restore the first result in A.
|
|
00D55E 1
|
|
00D55E 1 20 2A CA jsr InitializeBaseMotion ; $D55E: 20 2A CA
|
|
00D561 1
|
|
00D561 1 ; ============================================================================
|
|
00D561 1 ; $D561-$D57A
|
|
00D561 1 ; Configure transition state, process event slot four, wait for a frame,
|
|
00D561 1 ; and dispatch two inline command records.
|
|
00D561 1 ; ============================================================================
|
|
00D561 1
|
|
00D561 1 C6 86 dec TrajectoryEvaluationEnabled ; $D561: C6 86
|
|
00D563 1
|
|
00D563 1 A9 10 lda #$10 ; $D563: A9 10
|
|
00D565 1 85 FE sta PendingAudioFlags ; $D565: 85 FE
|
|
00D567 1
|
|
00D567 1 ; ----------------------------------------------------------------------------
|
|
00D567 1 ; Process event slot four.
|
|
00D567 1 ; ----------------------------------------------------------------------------
|
|
00D567 1
|
|
00D567 1 A0 04 ldy #$04 ; $D567: A0 04
|
|
00D569 1 20 66 EB jsr DispatchNextQueuedEvent ; $D569: 20 66 EB
|
|
00D56C 1
|
|
00D56C 1 ; ----------------------------------------------------------------------------
|
|
00D56C 1 ; Synchronize with the frame/update system.
|
|
00D56C 1 ; ----------------------------------------------------------------------------
|
|
00D56C 1
|
|
00D56C 1 20 48 EB jsr SelectObjectEventBank1 ; $D56C: 20 48 EB
|
|
00D56F 1
|
|
00D56F 1 ; ----------------------------------------------------------------------------
|
|
00D56F 1 ; Dispatch the first inline command record.
|
|
00D56F 1 ; ----------------------------------------------------------------------------
|
|
00D56F 1
|
|
00D56F 1 20 0A EB jsr QueueInlineObjectEvent ; $D56F: 20 0A EB
|
|
00D572 1
|
|
00D572 1 25 30 DC .byte $25,$30,$DC ; $D572-$D574
|
|
00D575 1
|
|
00D575 1 ; ----------------------------------------------------------------------------
|
|
00D575 1 ; Dispatch the second inline command record.
|
|
00D575 1 ; ----------------------------------------------------------------------------
|
|
00D575 1
|
|
00D575 1 20 0A EB jsr QueueInlineObjectEvent ; $D575: 20 0A EB
|
|
00D578 1
|
|
00D578 1 29 4C CB .byte $29,$4C,$CB ; $D578-$D57A
|
|
00D57B 1
|
|
00D57B 1 ; ============================================================================
|
|
00D57B 1 ; $D57B-$D598
|
|
00D57B 1 ; Short delay followed by an animation loop.
|
|
00D57B 1 ; ============================================================================
|
|
00D57B 1
|
|
00D57B 1 A9 02 lda #$02 ; $D57B: A9 02
|
|
00D57D 1 20 41 EB jsr StoreObjectEventBankValue ; $D57D: 20 41 EB
|
|
00D580 1
|
|
00D580 1 A9 40 lda #$40 ; $D580: A9 40
|
|
00D582 1 85 FE sta PendingAudioFlags ; $D582: 85 FE
|
|
00D584 1
|
|
00D584 1 ; ----------------------------------------------------------------------------
|
|
00D584 1 ; If the current animation value is already five or greater, skip the loop
|
|
00D584 1 ; and continue at $D599.
|
|
00D584 1 ; ----------------------------------------------------------------------------
|
|
00D584 1
|
|
00D584 1 UpdateMotionEndAnimation: ; $D584
|
|
00D584 1 AD B3 03 lda $03B3 ; $D584: AD B3 03
|
|
00D587 1 C9 05 cmp #$05 ; $D587: C9 05
|
|
00D589 1 B0 0E bcs FinishRandomMotionSequence
|
|
00D58B 1 ; $D589: B0 0E
|
|
00D58B 1
|
|
00D58B 1 ; ----------------------------------------------------------------------------
|
|
00D58B 1 ; Increment the animation value, wait eight ticks, and reduce $8D by two.
|
|
00D58B 1 ;
|
|
00D58B 1 ; Continue while the second decrement leaves $8D nonnegative.
|
|
00D58B 1 ; ----------------------------------------------------------------------------
|
|
00D58B 1
|
|
00D58B 1 EE B3 03 inc $03B3 ; $D58B: EE B3 03
|
|
00D58E 1
|
|
00D58E 1 A9 08 lda #$08 ; $D58E: A9 08
|
|
00D590 1 20 41 EB jsr StoreObjectEventBankValue ; $D590: 20 41 EB
|
|
00D593 1
|
|
00D593 1 C6 8D dec FielderInputBalance ; $D593: C6 8D
|
|
00D595 1 C6 8D dec FielderInputBalance ; $D595: C6 8D
|
|
00D597 1
|
|
00D597 1 10 EB bpl UpdateMotionEndAnimation
|
|
00D599 1 ; $D597: 10 EB
|
|
00D599 1 ; ============================================================================
|
|
00D599 1 ; $D599-$D5B8
|
|
00D599 1 ; Process two event slots, dispatch two inline commands, wait, advance state,
|
|
00D599 1 ; and leave through the common engine exit.
|
|
00D599 1 ; ============================================================================
|
|
00D599 1
|
|
00D599 1 FinishRandomMotionSequence: ; $D599
|
|
00D599 1 A0 13 ldy #$13 ; $D599: A0 13
|
|
00D59B 1 20 66 EB jsr DispatchNextQueuedEvent ; $D59B: 20 66 EB
|
|
00D59E 1
|
|
00D59E 1 A0 0F ldy #$0F ; $D59E: A0 0F
|
|
00D5A0 1 20 66 EB jsr DispatchNextQueuedEvent ; $D5A0: 20 66 EB
|
|
00D5A3 1
|
|
00D5A3 1 ; ----------------------------------------------------------------------------
|
|
00D5A3 1 ; Dispatch the first inline command record.
|
|
00D5A3 1 ; ----------------------------------------------------------------------------
|
|
00D5A3 1
|
|
00D5A3 1 20 0A EB jsr QueueInlineObjectEvent ; $D5A3: 20 0A EB
|
|
00D5A6 1
|
|
00D5A6 1 06 ED D9 .byte $06,$ED,$D9 ; $D5A6-$D5A8
|
|
00D5A9 1
|
|
00D5A9 1 ; ----------------------------------------------------------------------------
|
|
00D5A9 1 ; Dispatch the second inline command record.
|
|
00D5A9 1 ; ----------------------------------------------------------------------------
|
|
00D5A9 1
|
|
00D5A9 1 20 0A EB jsr QueueInlineObjectEvent ; $D5A9: 20 0A EB
|
|
00D5AC 1
|
|
00D5AC 1 11 D7 D5 .byte $11,$D7,$D5 ; $D5AC-$D5AE
|
|
00D5AF 1
|
|
00D5AF 1 ; ----------------------------------------------------------------------------
|
|
00D5AF 1 ; Wait $3C ticks, advance $A2, and leave through the common exit.
|
|
00D5AF 1 ; ----------------------------------------------------------------------------
|
|
00D5AF 1
|
|
00D5AF 1 A9 3C lda #$3C ; $D5AF: A9 3C
|
|
00D5B1 1 20 41 EB jsr StoreObjectEventBankValue ; $D5B1: 20 41 EB
|
|
00D5B4 1
|
|
00D5B4 1 E6 A2 inc ObjectSequenceState ; $D5B4: E6 A2
|
|
00D5B6 1
|
|
00D5B6 1 4C 6A EB jmp CommonEngineExit ; $D5B6: 4C 6A EB
|
|
00D5B9 1
|
|
00D5B9 1 ; ============================================================================
|
|
00D5B9 1 ; $D5B9-$D5D7
|
|
00D5B9 1 ; Lookup data used by SelectRandomMotionParameters.
|
|
00D5B9 1 ;
|
|
00D5B9 1 ; Several instructions intentionally use base addresses immediately before
|
|
00D5B9 1 ; these tables. The labels below reflect the actual bytes, while the code
|
|
00D5B9 1 ; continues to use the original literal operand addresses:
|
|
00D5B9 1 ;
|
|
00D5B9 1 ; ADC $D5B8,X
|
|
00D5B9 1 ; CMP $D5BD,X
|
|
00D5B9 1 ; ADC $D5C3,X
|
|
00D5B9 1 ; CMP $D5CE,X
|
|
00D5B9 1 ; ============================================================================
|
|
00D5B9 1
|
|
00D5B9 1 ; ----------------------------------------------------------------------------
|
|
00D5B9 1 ; $D5B9-$D5BD
|
|
00D5B9 1 ; Five randomized base values.
|
|
00D5B9 1 ;
|
|
00D5B9 1 ; Accessed through:
|
|
00D5B9 1 ;
|
|
00D5B9 1 ; ADC $D5B8,X
|
|
00D5B9 1 ;
|
|
00D5B9 1 ; Expected X values are $01-$05:
|
|
00D5B9 1 ;
|
|
00D5B9 1 ; X=$01 -> $D5B9 = $C0
|
|
00D5B9 1 ; X=$02 -> $D5BA = $E0
|
|
00D5B9 1 ; X=$03 -> $D5BB = $00
|
|
00D5B9 1 ; X=$04 -> $D5BC = $40
|
|
00D5B9 1 ; X=$05 -> $D5BD = $60
|
|
00D5B9 1 ; ----------------------------------------------------------------------------
|
|
00D5B9 1
|
|
00D5B9 1 RandomMotionBaseTable: ; $D5B9
|
|
00D5B9 1 C0 E0 00 40 .byte $C0,$E0,$00,$40,$60
|
|
00D5BD 1 60
|
|
00D5BE 1
|
|
00D5BE 1 ; ----------------------------------------------------------------------------
|
|
00D5BE 1 ; $D5BE-$D5C2
|
|
00D5BE 1 ; Five threshold values.
|
|
00D5BE 1 ;
|
|
00D5BE 1 ; Accessed through:
|
|
00D5BE 1 ;
|
|
00D5BE 1 ; CMP $D5BD,X
|
|
00D5BE 1 ;
|
|
00D5BE 1 ; Expected X values are $01-$05:
|
|
00D5BE 1 ;
|
|
00D5BE 1 ; X=$01 -> $D5BE = $00
|
|
00D5BE 1 ; X=$02 -> $D5BF = $4B
|
|
00D5BE 1 ; X=$03 -> $D5C0 = $85
|
|
00D5BE 1 ; X=$04 -> $D5C1 = $BC
|
|
00D5BE 1 ; X=$05 -> $D5C2 = $F0
|
|
00D5BE 1 ; ----------------------------------------------------------------------------
|
|
00D5BE 1
|
|
00D5BE 1 RandomMotionThresholdTable: ; $D5BE
|
|
00D5BE 1 00 4B 85 BC .byte $00,$4B,$85,$BC,$F0
|
|
00D5C2 1 F0
|
|
00D5C3 1
|
|
00D5C3 1 ; ----------------------------------------------------------------------------
|
|
00D5C3 1 ; $D5C3-$D5CC
|
|
00D5C3 1 ; Ten offset/result values.
|
|
00D5C3 1 ;
|
|
00D5C3 1 ; Accessed directly through:
|
|
00D5C3 1 ;
|
|
00D5C3 1 ; ADC $D5C3,X
|
|
00D5C3 1 ; ----------------------------------------------------------------------------
|
|
00D5C3 1
|
|
00D5C3 1 RandomMotionAngleTable: ; $D5C3
|
|
00D5C3 1 01 06 09 0C .byte $01,$06,$09,$0C,$12
|
|
00D5C7 1 12
|
|
00D5C8 1 16 18 1C 1E .byte $16,$18,$1C,$1E,$20
|
|
00D5CC 1 20
|
|
00D5CD 1
|
|
00D5CD 1 ; ----------------------------------------------------------------------------
|
|
00D5CD 1 ; $D5CD
|
|
00D5CD 1 ; Standalone value immediately before the next threshold table.
|
|
00D5CD 1 ;
|
|
00D5CD 1 ; Its use is not yet confirmed during the first pass.
|
|
00D5CD 1 ; ----------------------------------------------------------------------------
|
|
00D5CD 1
|
|
00D5CD 1 RandomMotionAnglePadding: ; $D5CD
|
|
00D5CD 1 02 .byte $02
|
|
00D5CE 1
|
|
00D5CE 1 ; ----------------------------------------------------------------------------
|
|
00D5CE 1 ; $D5CE-$D5D7
|
|
00D5CE 1 ; Ten threshold values.
|
|
00D5CE 1 ;
|
|
00D5CE 1 ; Accessed through:
|
|
00D5CE 1 ;
|
|
00D5CE 1 ; CMP $D5CE,X
|
|
00D5CE 1 ;
|
|
00D5CE 1 ; The search starts with X=$0A and decrements X before comparing, so the first
|
|
00D5CE 1 ; access uses X=$09 and reads $D5D7.
|
|
00D5CE 1 ; ----------------------------------------------------------------------------
|
|
00D5CE 1
|
|
00D5CE 1 RandomMotionAngleThresholdTable: ; $D5CE
|
|
00D5CE 1 00 0A 19 37 .byte $00,$0A,$19,$37,$55
|
|
00D5D2 1 55
|
|
00D5D3 1 87 B9 DC EB .byte $87,$B9,$DC,$EB,$F5
|
|
00D5D7 1 F5
|
|
00D5D8 1
|
|
00D5D8 1 ; ============================================================================
|
|
00D5D8 1 ; $D5D8-$D60F
|
|
00D5D8 1 ; Wait for a group of state and movement fields to clear.
|
|
00D5D8 1 ;
|
|
00D5D8 1 ; The routine initializes a $3C-frame countdown in $76. While any monitored
|
|
00D5D8 1 ; field remains nonzero, the countdown is reset to $3C. Once every field is
|
|
00D5D8 1 ; zero, $76 counts down to zero.
|
|
00D5D8 1 ; ============================================================================
|
|
00D5D8 1
|
|
00D5D8 1 WaitForMotionToSettle: ; $D5D8
|
|
00D5D8 1 A9 3C lda #$3C ; $D5D8: A9 3C
|
|
00D5DA 1 85 76 sta MotionSettledCountdown ; $D5DA: 85 76
|
|
00D5DC 1
|
|
00D5DC 1 ; ----------------------------------------------------------------------------
|
|
00D5DC 1 ; Wait for the next frame/update.
|
|
00D5DC 1 ; ----------------------------------------------------------------------------
|
|
00D5DC 1
|
|
00D5DC 1 Routine_D5DC_WaitFrame: ; $D5DC
|
|
00D5DC 1 20 48 EB jsr SelectObjectEventBank1 ; $D5DC: 20 48 EB
|
|
00D5DF 1
|
|
00D5DF 1 ; ----------------------------------------------------------------------------
|
|
00D5DF 1 ; Combine the monitored state fields.
|
|
00D5DF 1 ;
|
|
00D5DF 1 ; Any nonzero field restarts the routine at $D5D8, resetting the countdown.
|
|
00D5DF 1 ; ----------------------------------------------------------------------------
|
|
00D5DF 1
|
|
00D5DF 1 A5 6F lda PendingEvent ; $D5DF: A5 6F
|
|
00D5E1 1
|
|
00D5E1 1 0D 73 05 ora $0573 ; $D5E1: 0D 73 05
|
|
00D5E4 1 0D 74 05 ora $0574 ; $D5E4: 0D 74 05
|
|
00D5E7 1 0D 75 05 ora $0575 ; $D5E7: 0D 75 05
|
|
00D5EA 1 0D 76 05 ora $0576 ; $D5EA: 0D 76 05
|
|
00D5ED 1 0D 77 05 ora $0577 ; $D5ED: 0D 77 05
|
|
00D5F0 1 0D 78 05 ora $0578 ; $D5F0: 0D 78 05
|
|
00D5F3 1 0D 79 05 ora $0579 ; $D5F3: 0D 79 05
|
|
00D5F6 1 0D 7A 05 ora $057A ; $D5F6: 0D 7A 05
|
|
00D5F9 1
|
|
00D5F9 1 0D 08 05 ora $0508 ; $D5F9: 0D 08 05
|
|
00D5FC 1 0D 39 05 ora $0539 ; $D5FC: 0D 39 05
|
|
00D5FF 1 0D 6A 05 ora $056A ; $D5FF: 0D 6A 05
|
|
00D602 1
|
|
00D602 1 D0 D4 bne WaitForMotionToSettle ; $D602: D0 D4
|
|
00D604 1
|
|
00D604 1 ; ----------------------------------------------------------------------------
|
|
00D604 1 ; All monitored values are zero. Count down $76 while continuing to wait for
|
|
00D604 1 ; frames and recheck every field.
|
|
00D604 1 ; ----------------------------------------------------------------------------
|
|
00D604 1
|
|
00D604 1 C6 76 dec MotionSettledCountdown ; $D604: C6 76
|
|
00D606 1 D0 D4 bne Routine_D5DC_WaitFrame ; $D606: D0 D4
|
|
00D608 1
|
|
00D608 1 ; ----------------------------------------------------------------------------
|
|
00D608 1 ; Process command $08 and leave through the common engine exit.
|
|
00D608 1 ; ----------------------------------------------------------------------------
|
|
00D608 1
|
|
00D608 1 A2 08 ldx #$08 ; $D608: A2 08
|
|
00D60A 1 20 2A EB jsr ProcessQueuedObjectEvent ; $D60A: 20 2A EB
|
|
00D60D 1
|
|
00D60D 1 4C 6A EB jmp CommonEngineExit ; $D60D: 4C 6A EB
|
|
00D610 1
|
|
00D610 1 ; ============================================================================
|
|
00D610 1 ; $D610-$D65D
|
|
00D610 1 ; Initialize animation values, create three indexed object records, and select
|
|
00D610 1 ; an additional record according to the active object-state entries.
|
|
00D610 1 ; ============================================================================
|
|
00D610 1
|
|
00D610 1 ; ----------------------------------------------------------------------------
|
|
00D610 1 ; Contract:
|
|
00D610 1 ; Description: Initializes Secondary Actors.
|
|
00D610 1 ; Entry: Registers: A; Memory: $059b, $059a, $0599, $0598
|
|
00D610 1 ; Returns/products: Registers/clobbers: A, X
|
|
00D610 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00D610 1 ; Memory effects: $03b4, $03b5, $03b6, $039f, $03a0, $03a1
|
|
00D610 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00D610 1 ; comparison, load, or store path and are not a stable API product.
|
|
00D610 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00D610 1 ; ----------------------------------------------------------------------------
|
|
00D610 1 InitializeSecondaryActors: ; $D610
|
|
00D610 1 A9 7A lda #$7A ; $D610: A9 7A
|
|
00D612 1
|
|
00D612 1 ; ----------------------------------------------------------------------------
|
|
00D612 1 ; Initialize three animation/state entries in each of two arrays.
|
|
00D612 1 ; ----------------------------------------------------------------------------
|
|
00D612 1
|
|
00D612 1 8D B4 03 sta $03B4 ; $D612: 8D B4 03
|
|
00D615 1 8D B5 03 sta $03B5 ; $D615: 8D B5 03
|
|
00D618 1 8D B6 03 sta $03B6 ; $D618: 8D B6 03
|
|
00D61B 1
|
|
00D61B 1 8D 9F 03 sta $039F ; $D61B: 8D 9F 03
|
|
00D61E 1 8D A0 03 sta $03A0 ; $D61E: 8D A0 03
|
|
00D621 1 8D A1 03 sta $03A1 ; $D621: 8D A1 03
|
|
00D624 1
|
|
00D624 1 ; ----------------------------------------------------------------------------
|
|
00D624 1 ; Initialize object offset $08.
|
|
00D624 1 ;
|
|
00D624 1 ; Routine $C9A7 consumes five inline bytes:
|
|
00D624 1 ;
|
|
00D624 1 ; $08 object offset/metadata
|
|
00D624 1 ; $00,$04,$00,$F6 four field values
|
|
00D624 1 ; ----------------------------------------------------------------------------
|
|
00D624 1
|
|
00D624 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D627 1 ; $D624: 20 A7 C9
|
|
00D627 1
|
|
00D627 1 08 .byte $08 ; $D627
|
|
00D628 1 00 04 00 F6 .byte $00,$04,$00,$F6 ; $D628-$D62B
|
|
00D62C 1
|
|
00D62C 1 ; ----------------------------------------------------------------------------
|
|
00D62C 1 ; Initialize object offset $0A.
|
|
00D62C 1 ; ----------------------------------------------------------------------------
|
|
00D62C 1
|
|
00D62C 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D62F 1 ; $D62C: 20 A7 C9
|
|
00D62F 1
|
|
00D62F 1 0A .byte $0A ; $D62F
|
|
00D630 1 00 05 00 F6 .byte $00,$05,$00,$F6 ; $D630-$D633
|
|
00D634 1
|
|
00D634 1 ; ----------------------------------------------------------------------------
|
|
00D634 1 ; Initialize object offset $0C.
|
|
00D634 1 ; ----------------------------------------------------------------------------
|
|
00D634 1
|
|
00D634 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D637 1 ; $D634: 20 A7 C9
|
|
00D637 1
|
|
00D637 1 0C .byte $0C ; $D637
|
|
00D638 1 00 06 00 F6 .byte $00,$06,$00,$F6 ; $D638-$D63B
|
|
00D63C 1
|
|
00D63C 1 ; ----------------------------------------------------------------------------
|
|
00D63C 1 ; Search the object-state entries $059B through $0598 for value $06.
|
|
00D63C 1 ;
|
|
00D63C 1 ; If any entry contains $06, execution continues at $D656. Otherwise, A is
|
|
00D63C 1 ; changed to $FF and execution branches forward to $D66A.
|
|
00D63C 1 ; ----------------------------------------------------------------------------
|
|
00D63C 1
|
|
00D63C 1 A9 06 lda #$06 ; $D63C: A9 06
|
|
00D63E 1
|
|
00D63E 1 CD 9B 05 cmp $059B ; $D63E: CD 9B 05
|
|
00D641 1 F0 13 beq InitializeState6Actor
|
|
00D643 1 ; $D641: F0 13
|
|
00D643 1
|
|
00D643 1 CD 9A 05 cmp $059A ; $D643: CD 9A 05
|
|
00D646 1 F0 0E beq InitializeState6Actor
|
|
00D648 1 ; $D646: F0 0E
|
|
00D648 1
|
|
00D648 1 CD 99 05 cmp $0599 ; $D648: CD 99 05
|
|
00D64B 1 F0 09 beq InitializeState6Actor
|
|
00D64D 1 ; $D64B: F0 09
|
|
00D64D 1
|
|
00D64D 1 CD 98 05 cmp $0598 ; $D64D: CD 98 05
|
|
00D650 1 F0 04 beq InitializeState6Actor
|
|
00D652 1 ; $D650: F0 04
|
|
00D652 1
|
|
00D652 1 A9 FF lda #$FF ; $D652: A9 FF
|
|
00D654 1 D0 14 bne StoreState6Actor ; $D654: D0 14
|
|
00D656 1 ; Always taken because A is nonzero.
|
|
00D656 1
|
|
00D656 1 ; ----------------------------------------------------------------------------
|
|
00D656 1 ; Initialize object offset $0C with an alternate field set when state $06 was
|
|
00D656 1 ; found in one of the four object-state entries.
|
|
00D656 1 ; ----------------------------------------------------------------------------
|
|
00D656 1
|
|
00D656 1 InitializeState6Actor: ; $D656
|
|
00D656 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D659 1 ; $D656: 20 A7 C9
|
|
00D659 1
|
|
00D659 1 0C .byte $0C ; $D659
|
|
00D65A 1 80 F8 80 00 .byte $80,$F8,$80,$00 ; $D65A-$D65D
|
|
00D65E 1
|
|
00D65E 1 ; ============================================================================
|
|
00D65E 1 ; $D65E-$D69A
|
|
00D65E 1 ; Configure object $0C, search active object-state entries for value $04,
|
|
00D65E 1 ; optionally initialize object $0A, and update animation values.
|
|
00D65E 1 ; ============================================================================
|
|
00D65E 1
|
|
00D65E 1 A9 1A lda #$1A ; $D65E: A9 1A
|
|
00D660 1 8D B6 03 sta $03B6 ; $D660: 8D B6 03
|
|
00D663 1
|
|
00D663 1 A9 4F lda #$4F ; $D663: A9 4F
|
|
00D665 1 8D A1 03 sta $03A1 ; $D665: 8D A1 03
|
|
00D668 1
|
|
00D668 1 ; ----------------------------------------------------------------------------
|
|
00D668 1 ; Set object-state entry $059B and zero-page working state $A1 to $06.
|
|
00D668 1 ; ----------------------------------------------------------------------------
|
|
00D668 1
|
|
00D668 1 A9 06 lda #$06 ; $D668: A9 06
|
|
00D66A 1
|
|
00D66A 1 StoreState6Actor: ; $D66A
|
|
00D66A 1 8D 9B 05 sta $059B ; $D66A: 8D 9B 05
|
|
00D66D 1 85 A1 sta SecondaryActorState2 ; $D66D: 85 A1
|
|
00D66F 1
|
|
00D66F 1 ; ----------------------------------------------------------------------------
|
|
00D66F 1 ; Update object offset $0C.
|
|
00D66F 1 ; ----------------------------------------------------------------------------
|
|
00D66F 1
|
|
00D66F 1 A2 0C ldx #$0C ; $D66F: A2 0C
|
|
00D671 1 20 B7 E6 jsr ClearMovementTransforms ; $D671: 20 B7 E6
|
|
00D674 1
|
|
00D674 1 ; ----------------------------------------------------------------------------
|
|
00D674 1 ; Search state entries $059A-$0598 for value $04.
|
|
00D674 1 ;
|
|
00D674 1 ; If no entry contains $04, A becomes $FF and execution branches to $D69D.
|
|
00D674 1 ; That branch intentionally skips the LDA #$04 at $D69B while entering the
|
|
00D674 1 ; following STA instruction.
|
|
00D674 1 ; ----------------------------------------------------------------------------
|
|
00D674 1
|
|
00D674 1 A9 04 lda #$04 ; $D674: A9 04
|
|
00D676 1
|
|
00D676 1 CD 9A 05 cmp $059A ; $D676: CD 9A 05
|
|
00D679 1 F0 0E beq InitializeState4Actor
|
|
00D67B 1 ; $D679: F0 0E
|
|
00D67B 1
|
|
00D67B 1 CD 99 05 cmp $0599 ; $D67B: CD 99 05
|
|
00D67E 1 F0 09 beq InitializeState4Actor
|
|
00D680 1 ; $D67E: F0 09
|
|
00D680 1
|
|
00D680 1 CD 98 05 cmp $0598 ; $D680: CD 98 05
|
|
00D683 1 F0 04 beq InitializeState4Actor
|
|
00D685 1 ; $D683: F0 04
|
|
00D685 1
|
|
00D685 1 A9 FF lda #$FF ; $D685: A9 FF
|
|
00D687 1 D0 14 bne StoreState4Actor ; $D687: D0 14
|
|
00D689 1 ; Always taken because A is nonzero.
|
|
00D689 1
|
|
00D689 1 ; ----------------------------------------------------------------------------
|
|
00D689 1 ; Initialize object offset $0A when state $04 was found.
|
|
00D689 1 ;
|
|
00D689 1 ; Routine $C9A7 consumes five inline bytes:
|
|
00D689 1 ;
|
|
00D689 1 ; $0A object offset/metadata
|
|
00D689 1 ; $00,$FF,$00,$08 four field values
|
|
00D689 1 ; ----------------------------------------------------------------------------
|
|
00D689 1
|
|
00D689 1 InitializeState4Actor: ; $D689
|
|
00D689 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D68C 1 ; $D689: 20 A7 C9
|
|
00D68C 1
|
|
00D68C 1 0A .byte $0A ; $D68C
|
|
00D68D 1 00 FF 00 08 .byte $00,$FF,$00,$08 ; $D68D-$D690
|
|
00D691 1
|
|
00D691 1 ; ----------------------------------------------------------------------------
|
|
00D691 1 ; Update the corresponding animation values.
|
|
00D691 1 ; ----------------------------------------------------------------------------
|
|
00D691 1
|
|
00D691 1 A9 1D lda #$1D ; $D691: A9 1D
|
|
00D693 1 8D B5 03 sta $03B5 ; $D693: 8D B5 03
|
|
00D696 1
|
|
00D696 1 A9 55 lda #$55 ; $D696: A9 55
|
|
00D698 1 8D A0 03 sta $03A0 ; $D698: 8D A0 03
|
|
00D69B 1 ; ============================================================================
|
|
00D69B 1 ; $D69B-$D6DA
|
|
00D69B 1 ; Configure object $0A, search for state $02, optionally initialize object
|
|
00D69B 1 ; $08, configure its animation fields, and clear $0598.
|
|
00D69B 1 ; ============================================================================
|
|
00D69B 1
|
|
00D69B 1 A9 04 lda #$04 ; $D69B: A9 04
|
|
00D69D 1
|
|
00D69D 1 ; ----------------------------------------------------------------------------
|
|
00D69D 1 ; Shared entry from the earlier state search.
|
|
00D69D 1 ;
|
|
00D69D 1 ; Normal flow stores $04. The branch from $D687 enters here with A = $FF.
|
|
00D69D 1 ; ----------------------------------------------------------------------------
|
|
00D69D 1
|
|
00D69D 1 StoreState4Actor: ; $D69D
|
|
00D69D 1 8D 9A 05 sta $059A ; $D69D: 8D 9A 05
|
|
00D6A0 1 85 A0 sta SecondaryActorState1 ; $D6A0: 85 A0
|
|
00D6A2 1
|
|
00D6A2 1 ; ----------------------------------------------------------------------------
|
|
00D6A2 1 ; Update object offset $0A.
|
|
00D6A2 1 ; ----------------------------------------------------------------------------
|
|
00D6A2 1
|
|
00D6A2 1 A2 0A ldx #$0A ; $D6A2: A2 0A
|
|
00D6A4 1 20 B7 E6 jsr ClearMovementTransforms ; $D6A4: 20 B7 E6
|
|
00D6A7 1
|
|
00D6A7 1 ; ----------------------------------------------------------------------------
|
|
00D6A7 1 ; Search state entries $0599 and $0598 for value $02.
|
|
00D6A7 1 ;
|
|
00D6A7 1 ; If neither entry contains $02, A becomes $FF and execution enters the shared
|
|
00D6A7 1 ; store at $D6CB.
|
|
00D6A7 1 ; ----------------------------------------------------------------------------
|
|
00D6A7 1
|
|
00D6A7 1 A9 02 lda #$02 ; $D6A7: A9 02
|
|
00D6A9 1
|
|
00D6A9 1 CD 99 05 cmp $0599 ; $D6A9: CD 99 05
|
|
00D6AC 1 F0 09 beq InitializeState2Actor
|
|
00D6AE 1 ; $D6AC: F0 09
|
|
00D6AE 1
|
|
00D6AE 1 CD 98 05 cmp $0598 ; $D6AE: CD 98 05
|
|
00D6B1 1 F0 04 beq InitializeState2Actor
|
|
00D6B3 1 ; $D6B1: F0 04
|
|
00D6B3 1
|
|
00D6B3 1 A9 FF lda #$FF ; $D6B3: A9 FF
|
|
00D6B5 1 D0 14 bne StoreState2Actor ; $D6B5: D0 14
|
|
00D6B7 1 ; Always taken because A is nonzero.
|
|
00D6B7 1
|
|
00D6B7 1 ; ----------------------------------------------------------------------------
|
|
00D6B7 1 ; Initialize object offset $08 when state $02 was found.
|
|
00D6B7 1 ;
|
|
00D6B7 1 ; Routine $C9A7 consumes five inline bytes:
|
|
00D6B7 1 ;
|
|
00D6B7 1 ; $08 object offset/metadata
|
|
00D6B7 1 ; $00,$07,$80,$00 four field values
|
|
00D6B7 1 ; ----------------------------------------------------------------------------
|
|
00D6B7 1
|
|
00D6B7 1 InitializeState2Actor: ; $D6B7
|
|
00D6B7 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D6BA 1 ; $D6B7: 20 A7 C9
|
|
00D6BA 1
|
|
00D6BA 1 08 .byte $08 ; $D6BA
|
|
00D6BB 1 00 07 80 00 .byte $00,$07,$80,$00 ; $D6BB-$D6BE
|
|
00D6BF 1
|
|
00D6BF 1 ; ----------------------------------------------------------------------------
|
|
00D6BF 1 ; Configure the object's animation values.
|
|
00D6BF 1 ; ----------------------------------------------------------------------------
|
|
00D6BF 1
|
|
00D6BF 1 A9 1D lda #$1D ; $D6BF: A9 1D
|
|
00D6C1 1 8D B4 03 sta $03B4 ; $D6C1: 8D B4 03
|
|
00D6C4 1
|
|
00D6C4 1 A9 55 lda #$55 ; $D6C4: A9 55
|
|
00D6C6 1 8D 9F 03 sta $039F ; $D6C6: 8D 9F 03
|
|
00D6C9 1
|
|
00D6C9 1 A9 02 lda #$02 ; $D6C9: A9 02
|
|
00D6CB 1
|
|
00D6CB 1 ; ----------------------------------------------------------------------------
|
|
00D6CB 1 ; Shared store.
|
|
00D6CB 1 ;
|
|
00D6CB 1 ; Normal flow stores $02. The branch from $D6B5 enters with A = $FF.
|
|
00D6CB 1 ; ----------------------------------------------------------------------------
|
|
00D6CB 1
|
|
00D6CB 1 StoreState2Actor: ; $D6CB
|
|
00D6CB 1 8D 99 05 sta $0599 ; $D6CB: 8D 99 05
|
|
00D6CE 1 85 9F sta SecondaryActorState0 ; $D6CE: 85 9F
|
|
00D6D0 1
|
|
00D6D0 1 ; ----------------------------------------------------------------------------
|
|
00D6D0 1 ; Update object offset $08.
|
|
00D6D0 1 ; ----------------------------------------------------------------------------
|
|
00D6D0 1
|
|
00D6D0 1 A2 08 ldx #$08 ; $D6D0: A2 08
|
|
00D6D2 1 20 B7 E6 jsr ClearMovementTransforms ; $D6D2: 20 B7 E6
|
|
00D6D5 1
|
|
00D6D5 1 ; ----------------------------------------------------------------------------
|
|
00D6D5 1 ; Clear the first state entry and return.
|
|
00D6D5 1 ; ----------------------------------------------------------------------------
|
|
00D6D5 1
|
|
00D6D5 1 A9 00 lda #$00 ; $D6D5: A9 00
|
|
00D6D7 1 8D 98 05 sta $0598 ; $D6D7: 8D 98 05
|
|
00D6DA 1
|
|
00D6DA 1 60 rts ; $D6DA: 60
|
|
00D6DB 1
|
|
00D6DB 1 ; ============================================================================
|
|
00D6DB 1 ; $D6DB-$D6F8
|
|
00D6DB 1 ; Initial delay and frame-loop setup.
|
|
00D6DB 1 ; ============================================================================
|
|
00D6DB 1
|
|
00D6DB 1 RunObjectApproachSequence: ; $D6DB
|
|
00D6DB 1 A9 1E lda #$1E ; $D6DB: A9 1E
|
|
00D6DD 1 20 41 EB jsr StoreObjectEventBankValue ; $D6DD: 20 41 EB
|
|
00D6E0 1
|
|
00D6E0 1 ; ----------------------------------------------------------------------------
|
|
00D6E0 1 ; Clear state $82 and initialize countdown $78 to $1E.
|
|
00D6E0 1 ; ----------------------------------------------------------------------------
|
|
00D6E0 1
|
|
00D6E0 1 A9 00 lda #$00 ; $D6E0: A9 00
|
|
00D6E2 1 85 82 sta ActorActionComplete ; $D6E2: 85 82
|
|
00D6E4 1 ResetObjectApproachTimer:
|
|
00D6E4 1 A9 1E lda #$1E ; $D6E4: A9 1E
|
|
00D6E6 1 85 78 sta StateTimer78 ; $D6E6: 85 78
|
|
00D6E8 1
|
|
00D6E8 1 ; ----------------------------------------------------------------------------
|
|
00D6E8 1 ; Decrement the countdown and wait for a frame.
|
|
00D6E8 1 ; ----------------------------------------------------------------------------
|
|
00D6E8 1
|
|
00D6E8 1 UpdateObjectApproachTimer: ; $D6E8
|
|
00D6E8 1 C6 78 dec StateTimer78 ; $D6E8: C6 78
|
|
00D6EA 1 UpdateObjectApproachFrame:
|
|
00D6EA 1 20 48 EB jsr SelectObjectEventBank1 ; $D6EA: 20 48 EB
|
|
00D6ED 1
|
|
00D6ED 1 ; ----------------------------------------------------------------------------
|
|
00D6ED 1 ; Increment $83 while $8C is below nine.
|
|
00D6ED 1 ; ----------------------------------------------------------------------------
|
|
00D6ED 1
|
|
00D6ED 1 A5 8C lda FielderAnimationCountdown ; $D6ED: A5 8C
|
|
00D6EF 1 C9 09 cmp #$09 ; $D6EF: C9 09
|
|
00D6F1 1 B0 02 bcs CheckObjectApproachState ; $D6F1: B0 02
|
|
00D6F3 1
|
|
00D6F3 1 E6 83 inc ObjectApproachCount ; $D6F3: E6 83
|
|
00D6F5 1
|
|
00D6F5 1 ; ----------------------------------------------------------------------------
|
|
00D6F5 1 ; If state $82 is nonzero, branch forward to $D745.
|
|
00D6F5 1 ; ----------------------------------------------------------------------------
|
|
00D6F5 1
|
|
00D6F5 1 CheckObjectApproachState: ; $D6F5
|
|
00D6F5 1 A5 82 lda ActorActionComplete ; $D6F5: A5 82
|
|
00D6F7 1 D0 4C bne EvaluateObjectApproachCompletion ; $D6F7: D0 4C
|
|
00D6F9 1
|
|
00D6F9 1 ; ============================================================================
|
|
00D6F9 1 ; $D6F9-$D744
|
|
00D6F9 1 ; Compare base and object-six coordinates, update $87 when horizontal
|
|
00D6F9 1 ; separation exceeds a threshold, and derive a flag in $84.
|
|
00D6F9 1 ; ============================================================================
|
|
00D6F9 1
|
|
00D6F9 1 AC 3A 05 ldy $053A ; $D6F9: AC 3A 05
|
|
00D6FC 1 AD 3B 05 lda $053B ; $D6FC: AD 3B 05
|
|
00D6FF 1
|
|
00D6FF 1 ; ----------------------------------------------------------------------------
|
|
00D6FF 1 ; Subtract object-six's vertical coordinate from the base coordinate.
|
|
00D6FF 1 ;
|
|
00D6FF 1 ; Low bytes:
|
|
00D6FF 1 ; $053A - $0540
|
|
00D6FF 1 ;
|
|
00D6FF 1 ; High bytes:
|
|
00D6FF 1 ; $053B - $0541
|
|
00D6FF 1 ; ----------------------------------------------------------------------------
|
|
00D6FF 1
|
|
00D6FF 1 CC 40 05 cpy $0540 ; $D6FF: CC 40 05
|
|
00D702 1 ED 41 05 sbc $0541 ; $D702: ED 41 05
|
|
00D705 1
|
|
00D705 1 C9 00 cmp #$00 ; $D705: C9 00
|
|
00D707 1 10 2D bpl UpdateObjectCoordinateFlag
|
|
00D709 1 ; $D707: 10 2D
|
|
00D709 1
|
|
00D709 1 ; ----------------------------------------------------------------------------
|
|
00D709 1 ; Perform the distance check only while $8C is below nine.
|
|
00D709 1 ; ----------------------------------------------------------------------------
|
|
00D709 1
|
|
00D709 1 A5 8C lda FielderAnimationCountdown ; $D709: A5 8C
|
|
00D70B 1 C9 09 cmp #$09 ; $D70B: C9 09
|
|
00D70D 1 B0 23 bcs AddDoubleObjectProximityCount
|
|
00D70F 1 ; $D70D: B0 23
|
|
00D70F 1
|
|
00D70F 1 ; ----------------------------------------------------------------------------
|
|
00D70F 1 ; Calculate the horizontal difference:
|
|
00D70F 1 ;
|
|
00D70F 1 ; ($0509/$050A) - ($050F/$0510)
|
|
00D70F 1 ;
|
|
00D70F 1 ; Each result byte is XORed with $4C.
|
|
00D70F 1 ; ----------------------------------------------------------------------------
|
|
00D70F 1
|
|
00D70F 1 38 sec ; $D70F: 38
|
|
00D710 1
|
|
00D710 1 AD 09 05 lda $0509 ; $D710: AD 09 05
|
|
00D713 1 ED 0F 05 sbc $050F ; $D713: ED 0F 05
|
|
00D716 1 45 4C eor HorizontalDirectionMask ; $D716: 45 4C
|
|
00D718 1 A8 tay ; $D718: A8
|
|
00D719 1
|
|
00D719 1 AD 0A 05 lda $050A ; $D719: AD 0A 05
|
|
00D71C 1 ED 10 05 sbc $0510 ; $D71C: ED 10 05
|
|
00D71F 1 45 4C eor HorizontalDirectionMask ; $D71F: 45 4C
|
|
00D721 1 AA tax ; $D721: AA
|
|
00D722 1
|
|
00D722 1 ; ----------------------------------------------------------------------------
|
|
00D722 1 ; Subtract $0180 from the signed 16-bit difference in X:Y.
|
|
00D722 1 ; ----------------------------------------------------------------------------
|
|
00D722 1
|
|
00D722 1 38 sec ; $D722: 38
|
|
00D723 1
|
|
00D723 1 98 tya ; $D723: 98
|
|
00D724 1 E9 80 sbc #$80 ; $D724: E9 80
|
|
00D726 1 A8 tay ; $D726: A8
|
|
00D727 1
|
|
00D727 1 8A txa ; $D727: 8A
|
|
00D728 1 E9 00 sbc #$00 ; $D728: E9 00
|
|
00D72A 1 AA tax ; $D72A: AA
|
|
00D72B 1
|
|
00D72B 1 ; ----------------------------------------------------------------------------
|
|
00D72B 1 ; Compare the adjusted value against $0110.
|
|
00D72B 1 ;
|
|
00D72B 1 ; Carry is established by CPY #$10 and used by SBC #$01.
|
|
00D72B 1 ; If the value is below the threshold, skip the first increment of $87.
|
|
00D72B 1 ; ----------------------------------------------------------------------------
|
|
00D72B 1
|
|
00D72B 1 C0 10 cpy #$10 ; $D72B: C0 10
|
|
00D72D 1
|
|
00D72D 1 8A txa ; $D72D: 8A
|
|
00D72E 1 E9 01 sbc #$01 ; $D72E: E9 01
|
|
00D730 1 90 02 bcc AddObjectProximityCount
|
|
00D732 1 ; $D730: 90 02
|
|
00D732 1
|
|
00D732 1 AddDoubleObjectProximityCount: ; $D732
|
|
00D732 1 E6 87 inc ObjectProximityState ; $D732: E6 87
|
|
00D734 1
|
|
00D734 1 AddObjectProximityCount: ; $D734
|
|
00D734 1 E6 87 inc ObjectProximityState ; $D734: E6 87
|
|
00D736 1
|
|
00D736 1 ; ----------------------------------------------------------------------------
|
|
00D736 1 ; Normalize the base horizontal coordinate and derive a flag in $84.
|
|
00D736 1 ; ----------------------------------------------------------------------------
|
|
00D736 1
|
|
00D736 1 UpdateObjectCoordinateFlag: ; $D736
|
|
00D736 1 AC 09 05 ldy $0509 ; $D736: AC 09 05
|
|
00D739 1 AD 0A 05 lda $050A ; $D739: AD 0A 05
|
|
00D73C 1
|
|
00D73C 1 20 CB E7 jsr AbsoluteValueAY ; $D73C: 20 CB E7
|
|
00D73F 1
|
|
00D73F 1 C0 60 cpy #$60 ; $D73F: C0 60
|
|
00D741 1 E9 00 sbc #$00 ; $D741: E9 00
|
|
00D743 1
|
|
00D743 1 66 84 ror ObjectApproachDirectionFlag ; $D743: 66 84
|
|
00D745 1
|
|
00D745 1 ; ============================================================================
|
|
00D745 1 ; $D745-$D768
|
|
00D745 1 ; Evaluate countdown and state flags after the coordinate checks.
|
|
00D745 1 ; ============================================================================
|
|
00D745 1
|
|
00D745 1 EvaluateObjectApproachCompletion: ; $D745
|
|
00D745 1 A5 82 lda ActorActionComplete ; $D745: A5 82
|
|
00D747 1 F0 9B beq ResetObjectApproachTimer ; $D747: F0 9B
|
|
00D749 1
|
|
00D749 1 ; ----------------------------------------------------------------------------
|
|
00D749 1 ; Return to the main frame loop while countdown $78 remains nonzero.
|
|
00D749 1 ; ----------------------------------------------------------------------------
|
|
00D749 1
|
|
00D749 1 A5 78 lda StateTimer78 ; $D749: A5 78
|
|
00D74B 1 D0 9B bne UpdateObjectApproachTimer ; $D74B: D0 9B
|
|
00D74D 1
|
|
00D74D 1 ; ----------------------------------------------------------------------------
|
|
00D74D 1 ; Shift $8D right once.
|
|
00D74D 1 ;
|
|
00D74D 1 ; If the result is nonzero, return to the frame wait at $D6EA.
|
|
00D74D 1 ; ----------------------------------------------------------------------------
|
|
00D74D 1
|
|
00D74D 1 A5 8D lda FielderInputBalance ; $D74D: A5 8D
|
|
00D74F 1 4A lsr ; $D74F: 4A
|
|
00D750 1 D0 98 bne UpdateObjectApproachFrame ; $D750: D0 98
|
|
00D752 1
|
|
00D752 1 ; ----------------------------------------------------------------------------
|
|
00D752 1 ; If $83 is already nonzero, continue at AdvanceObjectApproachState.
|
|
00D752 1 ; ----------------------------------------------------------------------------
|
|
00D752 1
|
|
00D752 1 A5 83 lda ObjectApproachCount ; $D752: A5 83
|
|
00D754 1 D0 13 bne AdvanceObjectApproachState ; $D754: D0 13
|
|
00D756 1
|
|
00D756 1 ; ----------------------------------------------------------------------------
|
|
00D756 1 ; If $84 is nonnegative, continue at AdvanceObjectApproachState.
|
|
00D756 1 ; Otherwise, invoke the state-transition helper at $CC01.
|
|
00D756 1 ; ----------------------------------------------------------------------------
|
|
00D756 1
|
|
00D756 1 A5 84 lda ObjectApproachDirectionFlag ; $D756: A5 84
|
|
00D758 1 10 0F bpl AdvanceObjectApproachState ; $D758: 10 0F
|
|
00D75A 1
|
|
00D75A 1 20 01 CC jsr AdvancePrimaryStateSequence ; $D75A: 20 01 CC
|
|
00D75D 1
|
|
00D75D 1 ; ----------------------------------------------------------------------------
|
|
00D75D 1 ; When $63 equals four, increment $6E and $46.
|
|
00D75D 1 ; All other cases continue at $D783.
|
|
00D75D 1 ; ----------------------------------------------------------------------------
|
|
00D75D 1
|
|
00D75D 1 A5 63 lda TransitionSequenceState ; $D75D: A5 63
|
|
00D75F 1 C9 04 cmp #$04 ; $D75F: C9 04
|
|
00D761 1 D0 20 bne ExitObjectApproachState ; $D761: D0 20
|
|
00D763 1
|
|
00D763 1 E6 6E inc ObjectTransitionState ; $D763: E6 6E
|
|
00D765 1 E6 46 inc StateSequenceActive ; $D765: E6 46
|
|
00D767 1
|
|
00D767 1 D0 1A bne ExitObjectApproachState ; $D767: D0 1A
|
|
00D769 1 ; Normally unconditional after INC $46.
|
|
00D769 1
|
|
00D769 1 ; ============================================================================
|
|
00D769 1 ; Temporary external labels referenced by this stride.
|
|
00D769 1 ;
|
|
00D769 1 ; Remove each alias when its containing block is decoded.
|
|
00D769 1 ; ============================================================================
|
|
00D769 1
|
|
00D769 1 ; ============================================================================
|
|
00D769 1 ; $D769-$D785
|
|
00D769 1 ; Advance the dual-state sequence after the monitored object conditions have
|
|
00D769 1 ; completed.
|
|
00D769 1 ;
|
|
00D769 1 ; This path:
|
|
00D769 1 ; 1. Advances the $62/$64 state sequence.
|
|
00D769 1 ; 2. Checks whether $62 reached state three.
|
|
00D769 1 ; 3. If so, activates state flag $46.
|
|
00D769 1 ; 4. Waits $1E ticks.
|
|
00D769 1 ; 5. Sets animation/frame $03B3 to $7A.
|
|
00D769 1 ; 6. Processes event slot $0D.
|
|
00D769 1 ; 7. Leaves through the common engine exit.
|
|
00D769 1 ; ============================================================================
|
|
00D769 1
|
|
00D769 1 AdvanceObjectApproachState: ; $D769
|
|
00D769 1 20 7A CC jsr AdvanceDualStateSequence
|
|
00D76C 1 ; $D769: 20 7A CC
|
|
00D76C 1
|
|
00D76C 1 A5 62 lda PrimarySequenceState ; $D76C: A5 62
|
|
00D76E 1 C9 03 cmp #$03 ; $D76E: C9 03
|
|
00D770 1 D0 11 bne ExitObjectApproachState ; $D770: D0 11
|
|
00D772 1
|
|
00D772 1 ; ----------------------------------------------------------------------------
|
|
00D772 1 ; State $62 reached three.
|
|
00D772 1 ; Activate the next state and run a short timed animation.
|
|
00D772 1 ; ----------------------------------------------------------------------------
|
|
00D772 1
|
|
00D772 1 E6 46 inc StateSequenceActive ; $D772: E6 46
|
|
00D774 1
|
|
00D774 1 A9 1E lda #$1E ; $D774: A9 1E
|
|
00D776 1 20 41 EB jsr StoreObjectEventBankValue ; $D776: 20 41 EB
|
|
00D779 1
|
|
00D779 1 A9 7A lda #$7A ; $D779: A9 7A
|
|
00D77B 1 8D B3 03 sta $03B3 ; $D77B: 8D B3 03
|
|
00D77E 1
|
|
00D77E 1 ; ----------------------------------------------------------------------------
|
|
00D77E 1 ; Process event slot $0D.
|
|
00D77E 1 ; ----------------------------------------------------------------------------
|
|
00D77E 1
|
|
00D77E 1 A0 0D ldy #$0D ; $D77E: A0 0D
|
|
00D780 1 20 66 EB jsr DispatchNextQueuedEvent ; $D780: 20 66 EB
|
|
00D783 1
|
|
00D783 1 ; ----------------------------------------------------------------------------
|
|
00D783 1 ; Common exit.
|
|
00D783 1 ;
|
|
00D783 1 ; The BNE at $D770 branches directly here.
|
|
00D783 1 ; ----------------------------------------------------------------------------
|
|
00D783 1
|
|
00D783 1 ExitObjectApproachState: ; $D783
|
|
00D783 1 4C 6A EB jmp CommonEngineExit ; $D783: 4C 6A EB
|
|
00D786 1
|
|
00D786 1 ; ============================================================================
|
|
00D786 1 ; $D786-$D7AA
|
|
00D786 1 ; Wait for the base vertical coordinate to reach $F6, clear motion state,
|
|
00D786 1 ; advance the object state, and dispatch two inline commands.
|
|
00D786 1 ; ============================================================================
|
|
00D786 1
|
|
00D786 1 WaitForVerticalPositionF6: ; $D786
|
|
00D786 1 20 48 EB jsr SelectObjectEventBank1 ; $D786: 20 48 EB
|
|
00D789 1
|
|
00D789 1 A2 04 ldx #$04 ; $D789: A2 04
|
|
00D78B 1 38 sec ; $D78B: 38
|
|
00D78C 1
|
|
00D78C 1 AD 3B 05 lda $053B ; $D78C: AD 3B 05
|
|
00D78F 1 E9 F6 sbc #$F6 ; $D78F: E9 F6
|
|
00D791 1 D0 F3 bne WaitForVerticalPositionF6
|
|
00D793 1 ; $D791: D0 F3
|
|
00D793 1
|
|
00D793 1 ; ----------------------------------------------------------------------------
|
|
00D793 1 ; Clear active motion and value state, then advance $82.
|
|
00D793 1 ; ----------------------------------------------------------------------------
|
|
00D793 1
|
|
00D793 1 85 5C sta BaseMotionActive ; $D793: 85 5C
|
|
00D795 1 ; A is zero after the successful comparison.
|
|
00D795 1
|
|
00D795 1 85 81 sta RandomValue81 ; $D795: 85 81
|
|
00D797 1
|
|
00D797 1 E6 82 inc ActorActionComplete ; $D797: E6 82
|
|
00D799 1
|
|
00D799 1 20 E6 E3 jsr InitializeBaseObjectFromCurrent ; $D799: 20 E6 E3
|
|
00D79C 1
|
|
00D79C 1 ; ----------------------------------------------------------------------------
|
|
00D79C 1 ; Dispatch two inline command records.
|
|
00D79C 1 ; ----------------------------------------------------------------------------
|
|
00D79C 1
|
|
00D79C 1 20 0A EB jsr QueueInlineObjectEvent ; $D79C: 20 0A EB
|
|
00D79F 1
|
|
00D79F 1 11 D7 D5 .byte $11,$D7,$D5 ; $D79F-$D7A1
|
|
00D7A2 1
|
|
00D7A2 1 20 0A EB jsr QueueInlineObjectEvent ; $D7A2: 20 0A EB
|
|
00D7A5 1
|
|
00D7A5 1 1D AA D7 .byte $1D,$AA,$D7 ; $D7A5-$D7A7
|
|
00D7A8 1
|
|
00D7A8 1 4C 8B E0 jmp ObjectStateDispatch_NextPath ; $D7A8: 4C 8B E0
|
|
00D7AB 1
|
|
00D7AB 1 ; ============================================================================
|
|
00D7AB 1 ; $D7AB-$D7C9
|
|
00D7AB 1 ; Initialize an object timer, wait for four monitored object fields to clear,
|
|
00D7AB 1 ; then count the timer down to zero.
|
|
00D7AB 1 ;
|
|
00D7AB 1 ; Entry:
|
|
00D7AB 1 ; CurrentObjectIndex selects the timer at $05B1,X.
|
|
00D7AB 1 ; ============================================================================
|
|
00D7AB 1
|
|
00D7AB 1 WaitForObjectFieldsToClear: ; $D7AB
|
|
00D7AB 1 A6 E1 ldx CurrentObjectIndex ; $D7AB: A6 E1
|
|
00D7AD 1
|
|
00D7AD 1 A9 32 lda #$32 ; $D7AD: A9 32
|
|
00D7AF 1 9D B1 05 sta $05B1,x ; $D7AF: 9D B1 05
|
|
00D7B2 1
|
|
00D7B2 1 WaitForObjectFieldsFrame: ; $D7B2
|
|
00D7B2 1 20 48 EB jsr SelectObjectEventBank1 ; $D7B2: 20 48 EB
|
|
00D7B5 1
|
|
00D7B5 1 AD 73 05 lda $0573 ; $D7B5: AD 73 05
|
|
00D7B8 1 0D 75 05 ora $0575 ; $D7B8: 0D 75 05
|
|
00D7BB 1 0D 77 05 ora $0577 ; $D7BB: 0D 77 05
|
|
00D7BE 1 0D 79 05 ora $0579 ; $D7BE: 0D 79 05
|
|
00D7C1 1
|
|
00D7C1 1 D0 E8 bne WaitForObjectFieldsToClear
|
|
00D7C3 1 ; $D7C1: D0 E8
|
|
00D7C3 1
|
|
00D7C3 1 ; ----------------------------------------------------------------------------
|
|
00D7C3 1 ; Once all monitored fields are zero, count down $05B1,X.
|
|
00D7C3 1 ;
|
|
00D7C3 1 ; If the countdown remains nonzero, wait for another frame but do not
|
|
00D7C3 1 ; reinitialize the timer.
|
|
00D7C3 1 ; ----------------------------------------------------------------------------
|
|
00D7C3 1
|
|
00D7C3 1 A6 E1 ldx CurrentObjectIndex ; $D7C3: A6 E1
|
|
00D7C5 1
|
|
00D7C5 1 DE B1 05 dec $05B1,x ; $D7C5: DE B1 05
|
|
00D7C8 1 D0 E8 bne WaitForObjectFieldsFrame
|
|
00D7CA 1 ; $D7C8: D0 E8
|
|
00D7CA 1
|
|
00D7CA 1 ; ============================================================================
|
|
00D7CA 1 ; $D7CA-$D800
|
|
00D7CA 1 ; Process event slots, initialize animation and movement, wait for a vertical
|
|
00D7CA 1 ; position condition, then clear the active action state.
|
|
00D7CA 1 ; ============================================================================
|
|
00D7CA 1
|
|
00D7CA 1 A0 11 ldy #$11 ; $D7CA: A0 11
|
|
00D7CC 1 20 66 EB jsr DispatchNextQueuedEvent ; $D7CC: 20 66 EB
|
|
00D7CF 1
|
|
00D7CF 1 A0 04 ldy #$04 ; $D7CF: A0 04
|
|
00D7D1 1 20 66 EB jsr DispatchNextQueuedEvent ; $D7D1: 20 66 EB
|
|
00D7D4 1
|
|
00D7D4 1 ; ----------------------------------------------------------------------------
|
|
00D7D4 1 ; Clear the sequence counter and wait $14 ticks.
|
|
00D7D4 1 ; ----------------------------------------------------------------------------
|
|
00D7D4 1
|
|
00D7D4 1 A9 00 lda #$00 ; $D7D4: A9 00
|
|
00D7D6 1 85 7E sta ActionSequenceCounter ; $D7D6: 85 7E
|
|
00D7D8 1
|
|
00D7D8 1 A9 14 lda #$14 ; $D7D8: A9 14
|
|
00D7DA 1 20 41 EB jsr StoreObjectEventBankValue ; $D7DA: 20 41 EB
|
|
00D7DD 1
|
|
00D7DD 1 ; ----------------------------------------------------------------------------
|
|
00D7DD 1 ; Advance animation state and initialize base motion.
|
|
00D7DD 1 ; ----------------------------------------------------------------------------
|
|
00D7DD 1
|
|
00D7DD 1 EE B2 03 inc $03B2 ; $D7DD: EE B2 03
|
|
00D7E0 1
|
|
00D7E0 1 A9 10 lda #$10 ; $D7E0: A9 10
|
|
00D7E2 1 8D B7 03 sta $03B7 ; $D7E2: 8D B7 03
|
|
00D7E5 1
|
|
00D7E5 1 A2 00 ldx #$00 ; $D7E5: A2 00
|
|
00D7E7 1 A0 20 ldy #$20 ; $D7E7: A0 20
|
|
00D7E9 1
|
|
00D7E9 1 20 23 CA jsr InitializeBaseMotionZero
|
|
00D7EC 1 ; $D7E9: 20 23 CA
|
|
00D7EC 1
|
|
00D7EC 1 ; ----------------------------------------------------------------------------
|
|
00D7EC 1 ; Wait until the signed vertical high byte becomes nonnegative and reaches at
|
|
00D7EC 1 ; least $02.
|
|
00D7EC 1 ; ----------------------------------------------------------------------------
|
|
00D7EC 1
|
|
00D7EC 1 WaitForVerticalPosition02: ; $D7EC
|
|
00D7EC 1 20 48 EB jsr SelectObjectEventBank1 ; $D7EC: 20 48 EB
|
|
00D7EF 1
|
|
00D7EF 1 AD 3B 05 lda $053B ; $D7EF: AD 3B 05
|
|
00D7F2 1 C9 02 cmp #$02 ; $D7F2: C9 02
|
|
00D7F4 1 30 F6 bmi WaitForVerticalPosition02
|
|
00D7F6 1 ; $D7F4: 30 F6
|
|
00D7F6 1
|
|
00D7F6 1 ; ----------------------------------------------------------------------------
|
|
00D7F6 1 ; Run the helper for object offset $0E, then clear action and motion state.
|
|
00D7F6 1 ; ----------------------------------------------------------------------------
|
|
00D7F6 1
|
|
00D7F6 1 A2 0E ldx #$0E ; $D7F6: A2 0E
|
|
00D7F8 1 20 E8 E3 jsr CopyCurrentObjectPositionToBaseAfterIndex ; $D7F8: 20 E8 E3
|
|
00D7FB 1
|
|
00D7FB 1 A9 00 lda #$00 ; $D7FB: A9 00
|
|
00D7FD 1 85 9D sta CurrentActionState ; $D7FD: 85 9D
|
|
00D7FF 1 85 5C sta BaseMotionActive ; $D7FF: 85 5C
|
|
00D801 1
|
|
00D801 1 20 0A EB jsr QueueInlineObjectEvent ; $D801: 20 0A EB
|
|
00D804 1
|
|
00D804 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D804 1 17 AC D2 .byte $17,$AC,$D2 ; $D804-$D806
|
|
00D807 1
|
|
00D807 1 20 0A EB jsr QueueInlineObjectEvent ; $D807: 20 0A EB
|
|
00D80A 1
|
|
00D80A 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D80A 1 11 D7 D5 .byte $11,$D7,$D5 ; $D80A-$D80C
|
|
00D80D 1
|
|
00D80D 1 4C 6A EB jmp CommonEngineExit ; $D80D: 4C 6A EB
|
|
00D810 1
|
|
00D810 1 ; ============================================================================
|
|
00D810 1 ; $D810-$D836
|
|
00D810 1 ; Select an animation frame and delay using table-driven state.
|
|
00D810 1 ;
|
|
00D810 1 ; Entry:
|
|
00D810 1 ; A = base state or animation index
|
|
00D810 1 ; X = object/sprite-array index
|
|
00D810 1 ; $CB = additional index offset
|
|
00D810 1 ;
|
|
00D810 1 ; Operation:
|
|
00D810 1 ; 1. Add $CB to A and preserve the resulting table index.
|
|
00D810 1 ; 2. Update the object through $E6B7.
|
|
00D810 1 ; 3. Depending on carry and the current animation frame, optionally select
|
|
00D810 1 ; a replacement frame from the table at $D837.
|
|
00D810 1 ; 4. Load a delay from the table at $D84F.
|
|
00D810 1 ; 5. Tail-call the delay helper at $EB41.
|
|
00D810 1 ; ============================================================================
|
|
00D810 1
|
|
00D810 1 SelectAnimationFrameAndDelay: ; $D810
|
|
00D810 1 18 clc ; $D810: 18
|
|
00D811 1 65 CB adc $CB ; $D811: 65 CB
|
|
00D813 1 48 pha ; $D813: 48
|
|
00D814 1 ; Preserve the calculated table index.
|
|
00D814 1
|
|
00D814 1 20 B7 E6 jsr ClearMovementTransforms ; $D814: 20 B7 E6
|
|
00D817 1
|
|
00D817 1 68 pla ; $D817: 68
|
|
00D818 1 A8 tay ; $D818: A8
|
|
00D819 1 ; Y = table index.
|
|
00D819 1
|
|
00D819 1 ; ----------------------------------------------------------------------------
|
|
00D819 1 ; Carry from $E6B7 selects whether the animation-frame update is skipped.
|
|
00D819 1 ; ----------------------------------------------------------------------------
|
|
00D819 1
|
|
00D819 1 B0 16 bcs SelectAnimationDelay ; $D819: B0 16
|
|
00D81B 1
|
|
00D81B 1 ; ----------------------------------------------------------------------------
|
|
00D81B 1 ; Read the current animation frame, then increment it.
|
|
00D81B 1 ;
|
|
00D81B 1 ; The original value remains in A for the following table comparisons.
|
|
00D81B 1 ; ----------------------------------------------------------------------------
|
|
00D81B 1
|
|
00D81B 1 BD 9A 03 lda $039A,x ; $D81B: BD 9A 03
|
|
00D81E 1 FE 9A 03 inc $039A,x ; $D81E: FE 9A 03
|
|
00D821 1
|
|
00D821 1 ; ----------------------------------------------------------------------------
|
|
00D821 1 ; Compare the original frame against two table thresholds.
|
|
00D821 1 ;
|
|
00D821 1 ; If it falls within the selected range, replace the animation frame with a
|
|
00D821 1 ; value from the table at $D837.
|
|
00D821 1 ; ----------------------------------------------------------------------------
|
|
00D821 1
|
|
00D821 1 D9 43 D8 cmp AnimationFrameLimitTable,y ; $D821: D9 43 D8
|
|
00D824 1 B0 05 bcs CheckLowerFrameBound ; $D824: B0 05
|
|
00D826 1
|
|
00D826 1 D9 37 D8 cmp AnimationFrameBaseTable,y ; $D826: D9 37 D8
|
|
00D829 1 B0 06 bcs SelectAnimationDelay ; $D829: B0 06
|
|
00D82B 1
|
|
00D82B 1 CheckLowerFrameBound: ; $D82B
|
|
00D82B 1 B9 37 D8 lda AnimationFrameBaseTable,y ; $D82B: B9 37 D8
|
|
00D82E 1 9D 9A 03 sta $039A,x ; $D82E: 9D 9A 03
|
|
00D831 1
|
|
00D831 1 ; ----------------------------------------------------------------------------
|
|
00D831 1 ; Select the delay associated with the table entry and tail-call $EB41.
|
|
00D831 1 ; ----------------------------------------------------------------------------
|
|
00D831 1
|
|
00D831 1 SelectAnimationDelay: ; $D831
|
|
00D831 1 B9 4F D8 lda AnimationFrameDelayTable,y ; $D831: B9 4F D8
|
|
00D834 1 4C 41 EB jmp StoreObjectEventBankValue ; $D834: 4C 41 EB
|
|
00D837 1
|
|
00D837 1 ; ============================================================================
|
|
00D837 1 ; $D837-$D85A
|
|
00D837 1 ; Parallel animation-frame and delay lookup tables.
|
|
00D837 1 ;
|
|
00D837 1 ; SelectAnimationFrameAndDelay uses the same Y index with all three tables:
|
|
00D837 1 ;
|
|
00D837 1 ; AnimationFrameBaseTable,Y = replacement or lower animation frame
|
|
00D837 1 ; AnimationFrameLimitTable,Y = upper animation-frame threshold
|
|
00D837 1 ; AnimationFrameDelayTable,Y = animation delay
|
|
00D837 1 ;
|
|
00D837 1 ; Each table contains twelve entries.
|
|
00D837 1 ; ============================================================================
|
|
00D837 1
|
|
00D837 1 ; ----------------------------------------------------------------------------
|
|
00D837 1 ; Replacement/lower animation frames.
|
|
00D837 1 ; ----------------------------------------------------------------------------
|
|
00D837 1
|
|
00D837 1 AnimationFrameBaseTable: ; $D837
|
|
00D837 1 4D 50 53 56 .byte $4D,$50,$53,$56
|
|
00D83B 1 5C 61 1A 1E .byte $5C,$61,$1A,$1E
|
|
00D83F 1 23 27 2F 32 .byte $23,$27,$2F,$32
|
|
00D843 1
|
|
00D843 1 ; ----------------------------------------------------------------------------
|
|
00D843 1 ; Upper animation-frame thresholds.
|
|
00D843 1 ; ----------------------------------------------------------------------------
|
|
00D843 1
|
|
00D843 1 AnimationFrameLimitTable: ; $D843
|
|
00D843 1 4F 52 55 58 .byte $4F,$52,$55,$58
|
|
00D847 1 5D 63 1C 20 .byte $5D,$63,$1C,$20
|
|
00D84B 1 25 29 31 34 .byte $25,$29,$31,$34
|
|
00D84F 1
|
|
00D84F 1 ; ----------------------------------------------------------------------------
|
|
00D84F 1 ; Delay associated with each animation range.
|
|
00D84F 1 ;
|
|
00D84F 1 ; Most ranges wait six ticks. Entry four uses nine ticks.
|
|
00D84F 1 ; ----------------------------------------------------------------------------
|
|
00D84F 1
|
|
00D84F 1 AnimationFrameDelayTable: ; $D84F
|
|
00D84F 1 06 06 06 06 .byte $06,$06,$06,$06
|
|
00D853 1 09 06 06 06 .byte $09,$06,$06,$06
|
|
00D857 1 06 06 06 06 .byte $06,$06,$06,$06
|
|
00D85B 1
|
|
00D85B 1 ; ============================================================================
|
|
00D85B 1 ; $D85B-$D884
|
|
00D85B 1 ; Process three object-state entries.
|
|
00D85B 1 ;
|
|
00D85B 1 ; For each nonnegative entry in $0599-$059B:
|
|
00D85B 1 ; 1. Dispatch an object-specific inline command.
|
|
00D85B 1 ; 2. Wait for the next frame before checking the following entry.
|
|
00D85B 1 ;
|
|
00D85B 1 ; Negative entries are inactive and skip their associated command.
|
|
00D85B 1 ; ============================================================================
|
|
00D85B 1
|
|
00D85B 1 ProcessSecondaryObjectStates: ; $D85B
|
|
00D85B 1 AD 99 05 lda $0599 ; $D85B: AD 99 05
|
|
00D85E 1 30 06 bmi CheckObjectState059A ; $D85E: 30 06
|
|
00D860 1
|
|
00D860 1 20 0A EB jsr QueueInlineObjectEvent ; $D860: 20 0A EB
|
|
00D863 1
|
|
00D863 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D863 1 08 84 D8 .byte $08,$84,$D8 ; $D863-$D865
|
|
00D866 1
|
|
00D866 1 ; ----------------------------------------------------------------------------
|
|
00D866 1 ; Wait for a frame before processing the second state entry.
|
|
00D866 1 ;
|
|
00D866 1 ; A negative first entry branches directly here.
|
|
00D866 1 ; ----------------------------------------------------------------------------
|
|
00D866 1
|
|
00D866 1 CheckObjectState059A: ; $D866
|
|
00D866 1 20 48 EB jsr SelectObjectEventBank1 ; $D866: 20 48 EB
|
|
00D869 1
|
|
00D869 1 AD 9A 05 lda $059A ; $D869: AD 9A 05
|
|
00D86C 1 30 06 bmi CheckObjectState059B ; $D86C: 30 06
|
|
00D86E 1
|
|
00D86E 1 20 0A EB jsr QueueInlineObjectEvent ; $D86E: 20 0A EB
|
|
00D871 1
|
|
00D871 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D871 1 0A 84 D8 .byte $0A,$84,$D8 ; $D871-$D873
|
|
00D874 1
|
|
00D874 1 ; ----------------------------------------------------------------------------
|
|
00D874 1 ; Wait for a frame before processing the third state entry.
|
|
00D874 1 ;
|
|
00D874 1 ; A negative second entry branches directly here.
|
|
00D874 1 ; ----------------------------------------------------------------------------
|
|
00D874 1
|
|
00D874 1 CheckObjectState059B: ; $D874
|
|
00D874 1 20 48 EB jsr SelectObjectEventBank1 ; $D874: 20 48 EB
|
|
00D877 1
|
|
00D877 1 AD 9B 05 lda $059B ; $D877: AD 9B 05
|
|
00D87A 1 30 06 bmi FinishSecondaryObjectStates
|
|
00D87C 1 ; $D87A: 30 06
|
|
00D87C 1
|
|
00D87C 1 20 0A EB jsr QueueInlineObjectEvent ; $D87C: 20 0A EB
|
|
00D87F 1
|
|
00D87F 1 ; Inline command record consumed by QueueInlineObjectEvent.
|
|
00D87F 1 0C 84 D8 .byte $0C,$84,$D8 ; $D87F-$D881
|
|
00D882 1
|
|
00D882 1 ; ----------------------------------------------------------------------------
|
|
00D882 1 ; Leave through the common engine exit.
|
|
00D882 1 ; ----------------------------------------------------------------------------
|
|
00D882 1
|
|
00D882 1 FinishSecondaryObjectStates: ; $D882
|
|
00D882 1 4C 6A EB jmp CommonEngineExit ; $D882: 4C 6A EB
|
|
00D885 1
|
|
00D885 1 ; ============================================================================
|
|
00D885 1 ; $D885-$D8C2
|
|
00D885 1 ; Update one secondary object's active state.
|
|
00D885 1 ;
|
|
00D885 1 ; Entry:
|
|
00D885 1 ; X = object-array offset supplied by the inline command record:
|
|
00D885 1 ; $08, $0A, or $0C
|
|
00D885 1 ;
|
|
00D885 1 ; The routine updates the indexed timer/state fields, performs collision or
|
|
00D885 1 ; geometry checks, waits for frame updates, and dispatches to later state paths.
|
|
00D885 1 ; ============================================================================
|
|
00D885 1
|
|
00D885 1 UpdateSecondaryObjectState: ; $D885
|
|
00D885 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00D888 1 ; $D885: 20 68 DA
|
|
00D888 1
|
|
00D888 1 ; ----------------------------------------------------------------------------
|
|
00D888 1 ; Increment this object's state/timer at $0595,X.
|
|
00D888 1 ;
|
|
00D888 1 ; If the incremented value is nonzero, skip the initialization delay and
|
|
00D888 1 ; continue at $D897.
|
|
00D888 1 ; ----------------------------------------------------------------------------
|
|
00D888 1
|
|
00D888 1 FE 95 05 inc $0595,x ; $D888: FE 95 05
|
|
00D88B 1 D0 0A bne SecondaryObject_CheckRegion
|
|
00D88D 1 ; $D88B: D0 0A
|
|
00D88D 1
|
|
00D88D 1 ; ----------------------------------------------------------------------------
|
|
00D88D 1 ; Handle wraparound from $FF to $00.
|
|
00D88D 1 ;
|
|
00D88D 1 ; The helper at $DBB8 returns a delay value in A, which is passed directly to
|
|
00D88D 1 ; the timing helper at $EB41.
|
|
00D88D 1 ; ----------------------------------------------------------------------------
|
|
00D88D 1 SecondaryObject_RetryDelay:
|
|
00D88D 1 20 B8 DB jsr SelectSecondaryObjectDelay ; $D88D: 20 B8 DB
|
|
00D890 1 20 41 EB jsr StoreObjectEventBankValue ; $D890: 20 41 EB
|
|
00D893 1
|
|
00D893 1 A5 7F lda SelectedStateCount ; $D893: A5 7F
|
|
00D895 1 D0 2C bne SecondaryObject_ActivateTimer
|
|
00D897 1 ; $D895: D0 2C
|
|
00D897 1
|
|
00D897 1 ; ----------------------------------------------------------------------------
|
|
00D897 1 ; Run the object's geometry/update helpers.
|
|
00D897 1 ;
|
|
00D897 1 ; If $E55F returns carry set, restart at $D88D and choose another delay.
|
|
00D897 1 ; ----------------------------------------------------------------------------
|
|
00D897 1
|
|
00D897 1 SecondaryObject_CheckRegion: ; $D897
|
|
00D897 1 20 81 E4 jsr SelectGeometryRecord_44 ; $D897: 20 81 E4
|
|
00D89A 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $D89A: 20 5F E5
|
|
00D89D 1 B0 EE bcs SecondaryObject_RetryDelay
|
|
00D89F 1 ; $D89D: B0 EE
|
|
00D89F 1
|
|
00D89F 1 ; ----------------------------------------------------------------------------
|
|
00D89F 1 ; Update object data, recalculate X, then clear $96,X.
|
|
00D89F 1 ;
|
|
00D89F 1 ; The helper at GetCurrentObjectStateIndex appears to restore or derive the
|
|
00D89F 1 ; object-relative index required by the indexed store.
|
|
00D89F 1 ; ----------------------------------------------------------------------------
|
|
00D89F 1
|
|
00D89F 1 20 81 DA jsr UpdateCurrentObjectAnimation
|
|
00D8A2 1 ; $D89F: 20 81 DA
|
|
00D8A2 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00D8A5 1 ; $D8A2: 20 68 DA
|
|
00D8A5 1
|
|
00D8A5 1 A9 00 lda #$00 ; $D8A5: A9 00
|
|
00D8A7 1 95 96 sta $96,x ; $D8A7: 95 96
|
|
00D8A9 1
|
|
00D8A9 1 ; ----------------------------------------------------------------------------
|
|
00D8A9 1 ; Wait for the next frame and evaluate the current global state.
|
|
00D8A9 1 ; ----------------------------------------------------------------------------
|
|
00D8A9 1
|
|
00D8A9 1 SecondaryObject_WaitFrame: ; $D8A9
|
|
00D8A9 1 20 48 EB jsr SelectObjectEventBank1 ; $D8A9: 20 48 EB
|
|
00D8AC 1
|
|
00D8AC 1 A5 86 lda TrajectoryEvaluationEnabled ; $D8AC: A5 86
|
|
00D8AE 1 F0 03 beq SecondaryObject_CheckFlags
|
|
00D8B0 1 ; $D8AE: F0 03
|
|
00D8B0 1
|
|
00D8B0 1 4C 44 D9 jmp SecondaryObject_State86Path
|
|
00D8B3 1 ; $D8B0: 4C 44 D9
|
|
00D8B3 1
|
|
00D8B3 1 ; ----------------------------------------------------------------------------
|
|
00D8B3 1 ; When either $82 or $7F is nonzero, continue at the timer activation path.
|
|
00D8B3 1 ; ----------------------------------------------------------------------------
|
|
00D8B3 1
|
|
00D8B3 1 SecondaryObject_CheckFlags: ; $D8B3
|
|
00D8B3 1 A5 82 lda ActorActionComplete ; $D8B3: A5 82
|
|
00D8B5 1 D0 0C bne SecondaryObject_ActivateTimer
|
|
00D8B7 1 ; $D8B5: D0 0C
|
|
00D8B7 1
|
|
00D8B7 1 A5 7F lda SelectedStateCount ; $D8B7: A5 7F
|
|
00D8B9 1 D0 08 bne SecondaryObject_ActivateTimer
|
|
00D8BB 1 ; $D8B9: D0 08
|
|
00D8BB 1
|
|
00D8BB 1 ; ----------------------------------------------------------------------------
|
|
00D8BB 1 ; Run the helper at $DB18.
|
|
00D8BB 1 ;
|
|
00D8BB 1 ; A nonnegative result returns to the frame wait. A negative result transfers
|
|
00D8BB 1 ; to the later state path at $DA25.
|
|
00D8BB 1 ; ----------------------------------------------------------------------------
|
|
00D8BB 1
|
|
00D8BB 1 20 18 DB jsr TestCurrentObjectInput ; $D8BB: 20 18 DB
|
|
00D8BE 1 10 E9 bpl SecondaryObject_WaitFrame
|
|
00D8C0 1 ; $D8BE: 10 E9
|
|
00D8C0 1
|
|
00D8C0 1 4C 25 DA jmp SecondaryObject_NegativeResultPath
|
|
00D8C3 1 ; $D8C0: 4C 25 DA
|
|
00D8C3 1
|
|
00D8C3 1
|
|
00D8C3 1 ; ============================================================================
|
|
00D8C3 1 ; $D8C3-$D905
|
|
00D8C3 1 ; Secondary-object timer path.
|
|
00D8C3 1 ;
|
|
00D8C3 1 ; This path initializes the object's timer, waits for state conditions,
|
|
00D8C3 1 ; processes the object each frame, performs a collision/region check when the
|
|
00D8C3 1 ; timer expires, and dispatches to the appropriate result path.
|
|
00D8C3 1 ; ============================================================================
|
|
00D8C3 1
|
|
00D8C3 1 SecondaryObject_ActivateTimer: ; $D8C3
|
|
00D8C3 1 A9 01 lda #$01 ; $D8C3: A9 01
|
|
00D8C5 1 SecondaryObject_SetTimer:
|
|
00D8C5 1 A6 E1 ldx CurrentObjectIndex ; $D8C5: A6 E1
|
|
00D8C7 1 9D B1 05 sta $05B1,x ; $D8C7: 9D B1 05
|
|
00D8CA 1
|
|
00D8CA 1 ; ----------------------------------------------------------------------------
|
|
00D8CA 1 ; Wait for the next frame and derive the current object-relative index.
|
|
00D8CA 1 ; ----------------------------------------------------------------------------
|
|
00D8CA 1
|
|
00D8CA 1 SecondaryObject_TimerLoop: ; $D8CA
|
|
00D8CA 1 20 48 EB jsr SelectObjectEventBank1 ; $D8CA: 20 48 EB
|
|
00D8CD 1
|
|
00D8CD 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00D8D0 1 ; $D8CD: 20 68 DA
|
|
00D8D0 1
|
|
00D8D0 1 ; ----------------------------------------------------------------------------
|
|
00D8D0 1 ; If the indexed state at $96,X is nonzero, continue with normal object
|
|
00D8D0 1 ; processing.
|
|
00D8D0 1 ; ----------------------------------------------------------------------------
|
|
00D8D0 1
|
|
00D8D0 1 B5 96 lda $96,x ; $D8D0: B5 96
|
|
00D8D2 1 D0 08 bne SecondaryObject_ProcessFrame
|
|
00D8D4 1 ; $D8D2: D0 08
|
|
00D8D4 1
|
|
00D8D4 1 ; ----------------------------------------------------------------------------
|
|
00D8D4 1 ; Otherwise, run the helper at $DB18.
|
|
00D8D4 1 ;
|
|
00D8D4 1 ; A nonnegative result continues normal processing. A negative result transfers
|
|
00D8D4 1 ; to the common negative-result path at $DA25.
|
|
00D8D4 1 ; ----------------------------------------------------------------------------
|
|
00D8D4 1
|
|
00D8D4 1 20 18 DB jsr TestCurrentObjectInput ; $D8D4: 20 18 DB
|
|
00D8D7 1 10 03 bpl SecondaryObject_ProcessFrame
|
|
00D8D9 1 ; $D8D7: 10 03
|
|
00D8D9 1
|
|
00D8D9 1 4C 25 DA jmp SecondaryObject_NegativeResultPath
|
|
00D8DC 1 ; $D8D9: 4C 25 DA
|
|
00D8DC 1
|
|
00D8DC 1 ; ----------------------------------------------------------------------------
|
|
00D8DC 1 ; Run the per-frame object helper.
|
|
00D8DC 1 ; ----------------------------------------------------------------------------
|
|
00D8DC 1
|
|
00D8DC 1 SecondaryObject_ProcessFrame: ; $D8DC
|
|
00D8DC 1 20 BC DA jsr CheckCurrentObjectSelector ; $D8DC: 20 BC DA
|
|
00D8DF 1
|
|
00D8DF 1 ; ----------------------------------------------------------------------------
|
|
00D8DF 1 ; Count down this object's timer at $05B1,X.
|
|
00D8DF 1 ;
|
|
00D8DF 1 ; Continue the frame loop until the timer reaches zero.
|
|
00D8DF 1 ; ----------------------------------------------------------------------------
|
|
00D8DF 1
|
|
00D8DF 1 A6 E1 ldx CurrentObjectIndex ; $D8DF: A6 E1
|
|
00D8E1 1
|
|
00D8E1 1 DE B1 05 dec $05B1,x ; $D8E1: DE B1 05
|
|
00D8E4 1 D0 E4 bne SecondaryObject_TimerLoop
|
|
00D8E6 1 ; $D8E4: D0 E4
|
|
00D8E6 1
|
|
00D8E6 1 ; ----------------------------------------------------------------------------
|
|
00D8E6 1 ; Timer expired. Run geometry/collision helpers.
|
|
00D8E6 1 ; ----------------------------------------------------------------------------
|
|
00D8E6 1
|
|
00D8E6 1 20 A5 E4 jsr SelectGeometryRecord_24 ; $D8E6: 20 A5 E4
|
|
00D8E9 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $D8E9: 20 5F E5
|
|
00D8EC 1
|
|
00D8EC 1 90 06 bcc SecondaryObject_NoCollision
|
|
00D8EE 1 ; $D8EC: 90 06
|
|
00D8EE 1
|
|
00D8EE 1 ; ----------------------------------------------------------------------------
|
|
00D8EE 1 ; Collision or region test succeeded.
|
|
00D8EE 1 ;
|
|
00D8EE 1 ; Select a delay and re-enter the object-processing path at $D8C5. This entry
|
|
00D8EE 1 ; reloads X from CurrentObjectIndex and stores the selected delay in $05B1,X.
|
|
00D8EE 1 ; ----------------------------------------------------------------------------
|
|
00D8EE 1
|
|
00D8EE 1 20 B8 DB jsr SelectSecondaryObjectDelay ; $D8EE: 20 B8 DB
|
|
00D8F1 1 4C C5 D8 jmp SecondaryObject_SetTimer
|
|
00D8F4 1 ; $D8F1: 4C C5 D8
|
|
00D8F4 1
|
|
00D8F4 1 ; ----------------------------------------------------------------------------
|
|
00D8F4 1 ; Collision or region test did not succeed.
|
|
00D8F4 1 ;
|
|
00D8F4 1 ; Decrement the indexed object state and process the resulting transition.
|
|
00D8F4 1 ; ----------------------------------------------------------------------------
|
|
00D8F4 1
|
|
00D8F4 1 SecondaryObject_NoCollision: ; $D8F4
|
|
00D8F4 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00D8F7 1 ; $D8F4: 20 68 DA
|
|
00D8F7 1
|
|
00D8F7 1 DE 95 05 dec $0595,x ; $D8F7: DE 95 05
|
|
00D8FA 1
|
|
00D8FA 1 20 A4 DA jsr CountMatchingObjectStates ; $D8FA: 20 A4 DA
|
|
00D8FD 1 20 F7 DA jsr UpdateCurrentObjectSelectorState ; $D8FD: 20 F7 DA
|
|
00D900 1 20 EB DA jsr StoreCurrentObjectSelector ; $D900: 20 EB DA
|
|
00D903 1
|
|
00D903 1 4C 0C D9 jmp SecondaryObject_Continue
|
|
00D906 1 ; $D903: 4C 0C D9
|
|
00D906 1
|
|
00D906 1 ; ============================================================================
|
|
00D906 1 ; $D906-$D943
|
|
00D906 1 ; Retry object geometry processing, update indexed state, and select the next
|
|
00D906 1 ; secondary-object transition path.
|
|
00D906 1 ; ============================================================================
|
|
00D906 1
|
|
00D906 1 SecondaryObject_RetryGeometry: ; $D906
|
|
00D906 1 20 B8 DB jsr SelectSecondaryObjectDelay ; $D906: 20 B8 DB
|
|
00D909 1 20 41 EB jsr StoreObjectEventBankValue ; $D909: 20 41 EB
|
|
00D90C 1
|
|
00D90C 1 ; ----------------------------------------------------------------------------
|
|
00D90C 1 ; Run geometry/region helpers.
|
|
00D90C 1 ;
|
|
00D90C 1 ; If the region test returns carry set, select another delay and retry.
|
|
00D90C 1 ; ----------------------------------------------------------------------------
|
|
00D90C 1
|
|
00D90C 1 SecondaryObject_Continue: ; $D90C
|
|
00D90C 1 20 8F E4 jsr SelectGeometryRecord_34 ; $D90C: 20 8F E4
|
|
00D90F 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $D90F: 20 5F E5
|
|
00D912 1
|
|
00D912 1 B0 F2 bcs SecondaryObject_RetryGeometry
|
|
00D914 1 ; $D912: B0 F2
|
|
00D914 1
|
|
00D914 1 ; ----------------------------------------------------------------------------
|
|
00D914 1 ; Update object state, wait for the next frame, and derive the current
|
|
00D914 1 ; object-relative index.
|
|
00D914 1 ; ----------------------------------------------------------------------------
|
|
00D914 1
|
|
00D914 1 20 81 DA jsr UpdateCurrentObjectAnimation
|
|
00D917 1 ; $D914: 20 81 DA
|
|
00D917 1
|
|
00D917 1 SecondaryObject_StateLoop: ; $D917
|
|
00D917 1 20 48 EB jsr SelectObjectEventBank1 ; $D917: 20 48 EB
|
|
00D91A 1
|
|
00D91A 1 20 6D DA jsr MarkMatchingObjectState ; $D91A: 20 6D DA
|
|
00D91D 1
|
|
00D91D 1 ; ----------------------------------------------------------------------------
|
|
00D91D 1 ; If state $6E is nonzero, evaluate the current indexed object condition.
|
|
00D91D 1 ; A negative result branches to the transition path at $D941.
|
|
00D91D 1 ; ----------------------------------------------------------------------------
|
|
00D91D 1
|
|
00D91D 1 A5 6E lda ObjectTransitionState ; $D91D: A5 6E
|
|
00D91F 1 F0 0A beq SecondaryObject_CheckState6D
|
|
00D921 1 ; $D91F: F0 0A
|
|
00D921 1
|
|
00D921 1 20 5F DA jsr GetCurrentObjectSelector; $D921: 20 5F DA
|
|
00D924 1 30 1B bmi SecondaryObject_Transition
|
|
00D926 1 ; $D924: 30 1B
|
|
00D926 1
|
|
00D926 1 ; ----------------------------------------------------------------------------
|
|
00D926 1 ; Increment the indexed object-state byte at $96,X.
|
|
00D926 1 ; ----------------------------------------------------------------------------
|
|
00D926 1
|
|
00D926 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00D929 1 ; $D926: 20 68 DA
|
|
00D929 1 F6 96 inc $96,x ; $D929: F6 96
|
|
00D92B 1
|
|
00D92B 1 ; ----------------------------------------------------------------------------
|
|
00D92B 1 ; State $6D immediately selects the transition path when nonzero.
|
|
00D92B 1 ; ----------------------------------------------------------------------------
|
|
00D92B 1
|
|
00D92B 1 SecondaryObject_CheckState6D: ; $D92B
|
|
00D92B 1 A5 6D lda SpecialSequenceState ; $D92B: A5 6D
|
|
00D92D 1 D0 12 bne SecondaryObject_Transition
|
|
00D92F 1 ; $D92D: D0 12
|
|
00D92F 1
|
|
00D92F 1 ; ----------------------------------------------------------------------------
|
|
00D92F 1 ; If both BaseMotionPhase and PendingStateTransition are zero, evaluate GetCurrentObjectSelector.
|
|
00D92F 1 ;
|
|
00D92F 1 ; A negative result selects the transition path.
|
|
00D92F 1 ; ----------------------------------------------------------------------------
|
|
00D92F 1
|
|
00D92F 1 A5 5D lda BaseMotionPhase ; $D92F: A5 5D
|
|
00D931 1 F0 09 beq SecondaryObject_CheckResult
|
|
00D933 1 ; $D931: F0 09
|
|
00D933 1
|
|
00D933 1 A5 60 lda PendingStateTransition ; $D933: A5 60
|
|
00D935 1 D0 05 bne SecondaryObject_CheckResult
|
|
00D937 1 ; $D935: D0 05
|
|
00D937 1
|
|
00D937 1 20 5F DA jsr GetCurrentObjectSelector; $D937: 20 5F DA
|
|
00D93A 1 30 05 bmi SecondaryObject_Transition
|
|
00D93C 1 ; $D93A: 30 05
|
|
00D93C 1
|
|
00D93C 1 ; ----------------------------------------------------------------------------
|
|
00D93C 1 ; Continue waiting while $DB18 returns a nonnegative result.
|
|
00D93C 1 ; ----------------------------------------------------------------------------
|
|
00D93C 1
|
|
00D93C 1 SecondaryObject_CheckResult: ; $D93C
|
|
00D93C 1 20 18 DB jsr TestCurrentObjectInput ; $D93C: 20 18 DB
|
|
00D93F 1 10 D6 bpl SecondaryObject_StateLoop
|
|
00D941 1 ; $D93F: 10 D6
|
|
00D941 1
|
|
00D941 1 ; ----------------------------------------------------------------------------
|
|
00D941 1 ; Transfer to the later transition handler.
|
|
00D941 1 ; ----------------------------------------------------------------------------
|
|
00D941 1
|
|
00D941 1 SecondaryObject_Transition: ; $D941
|
|
00D941 1 4C E6 D9 jmp SecondaryObject_TransitionHandler ; $D941: 4C E6 D9
|
|
00D944 1
|
|
00D944 1 ; ============================================================================
|
|
00D944 1 ; $D944-$D95F
|
|
00D944 1 ; State-86 path for the secondary-object handler.
|
|
00D944 1 ; ============================================================================
|
|
00D944 1
|
|
00D944 1 SecondaryObject_State86Path: ; $D944
|
|
00D944 1 A5 64 lda SecondarySequenceState ; $D944: A5 64
|
|
00D946 1 C9 02 cmp #$02 ; $D946: C9 02
|
|
00D948 1 F0 10 beq SecondaryObject_JumpToNegativeResult
|
|
00D94A 1 ; $D948: F0 10
|
|
00D94A 1
|
|
00D94A 1 ; ----------------------------------------------------------------------------
|
|
00D94A 1 ; Wait for the next frame.
|
|
00D94A 1 ; ----------------------------------------------------------------------------
|
|
00D94A 1
|
|
00D94A 1 SecondaryObject_State86Wait: ; $D94A
|
|
00D94A 1 20 48 EB jsr SelectObjectEventBank1 ; $D94A: 20 48 EB
|
|
00D94D 1
|
|
00D94D 1 ; ----------------------------------------------------------------------------
|
|
00D94D 1 ; If the sequence-state counter is nonzero, return to the timer path.
|
|
00D94D 1 ; ----------------------------------------------------------------------------
|
|
00D94D 1
|
|
00D94D 1 A5 A2 lda ObjectSequenceState ; $D94D: A5 A2
|
|
00D94F 1 D0 0C bne SecondaryObject_TimerPath
|
|
00D951 1 ; $D94F: D0 0C
|
|
00D951 1
|
|
00D951 1 ; ----------------------------------------------------------------------------
|
|
00D951 1 ; Continue waiting while BaseMotionPhase is zero.
|
|
00D951 1 ; ----------------------------------------------------------------------------
|
|
00D951 1
|
|
00D951 1 A5 5D lda BaseMotionPhase ; $D951: A5 5D
|
|
00D953 1 F0 F5 beq SecondaryObject_State86Wait
|
|
00D955 1 ; $D953: F0 F5
|
|
00D955 1
|
|
00D955 1 ; ----------------------------------------------------------------------------
|
|
00D955 1 ; Evaluate the current object result.
|
|
00D955 1 ;
|
|
00D955 1 ; A nonnegative result returns to the timer path. A negative result falls
|
|
00D955 1 ; through to a trampoline that jumps to the real handler at $DA25.
|
|
00D955 1 ; ----------------------------------------------------------------------------
|
|
00D955 1
|
|
00D955 1 20 5F DA jsr GetCurrentObjectSelector; $D955: 20 5F DA
|
|
00D958 1 10 03 bpl SecondaryObject_TimerPath
|
|
00D95A 1 ; $D958: 10 03
|
|
00D95A 1
|
|
00D95A 1 SecondaryObject_JumpToNegativeResult: ; $D95A
|
|
00D95A 1 4C 25 DA jmp SecondaryObject_NegativeResultPath
|
|
00D95D 1 ; $D95A: 4C 25 DA
|
|
00D95D 1
|
|
00D95D 1 ; ----------------------------------------------------------------------------
|
|
00D95D 1 ; Re-enter the timer initialization path.
|
|
00D95D 1 ; ----------------------------------------------------------------------------
|
|
00D95D 1
|
|
00D95D 1 SecondaryObject_TimerPath: ; $D95D
|
|
00D95D 1 4C C3 D8 jmp SecondaryObject_ActivateTimer
|
|
00D960 1 ; $D95D: 4C C3 D8
|
|
00D960 1
|
|
00D960 1 ; ============================================================================
|
|
00D960 1 ; $D960-$D966
|
|
00D960 1 ; Route according to the global action state.
|
|
00D960 1 ; ============================================================================
|
|
00D960 1
|
|
00D960 1 SecondaryObject_ActionStatePath: ; $D960
|
|
00D960 1 A5 9D lda CurrentActionState ; $D960: A5 9D
|
|
00D962 1 D0 33 bne SecondaryObject_ActionActive
|
|
00D964 1 ; $D962: D0 33
|
|
00D964 1
|
|
00D964 1 4C 85 D8 jmp UpdateSecondaryObjectState
|
|
00D967 1 ; $D964: 4C 85 D8
|
|
00D967 1
|
|
00D967 1 ; ============================================================================
|
|
00D967 1 ; $D967-$D990
|
|
00D967 1 ; Advance the indexed secondary-object state, run its update helpers, and
|
|
00D967 1 ; select the next path using the current event and object indices.
|
|
00D967 1 ; ============================================================================
|
|
00D967 1
|
|
00D967 1 SecondaryObject_AdvanceIndexedState: ; $D967
|
|
00D967 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00D96A 1 ; $D967: 20 68 DA
|
|
00D96A 1
|
|
00D96A 1 ; ----------------------------------------------------------------------------
|
|
00D96A 1 ; Advance the indexed state byte at $0595,X.
|
|
00D96A 1 ; ----------------------------------------------------------------------------
|
|
00D96A 1
|
|
00D96A 1 FE 95 05 inc $0595,x ; $D96A: FE 95 05
|
|
00D96D 1
|
|
00D96D 1 ; ----------------------------------------------------------------------------
|
|
00D96D 1 ; Derive an object/event selector in Y.
|
|
00D96D 1 ;
|
|
00D96D 1 ; A selector value of eight transfers to the special path at $D9B3.
|
|
00D96D 1 ; ----------------------------------------------------------------------------
|
|
00D96D 1
|
|
00D96D 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00D970 1 ; $D96D: 20 DC E3
|
|
00D970 1
|
|
00D970 1 C0 08 cpy #$08 ; $D970: C0 08
|
|
00D972 1 F0 3F beq SecondaryObject_SelectorEight
|
|
00D974 1 ; $D972: F0 3F
|
|
00D974 1
|
|
00D974 1 ; ----------------------------------------------------------------------------
|
|
00D974 1 ; Run the normal indexed-object update helpers.
|
|
00D974 1 ; ----------------------------------------------------------------------------
|
|
00D974 1
|
|
00D974 1 20 A4 DA jsr CountMatchingObjectStates ; $D974: 20 A4 DA
|
|
00D977 1 20 F7 DA jsr UpdateCurrentObjectSelectorState ; $D977: 20 F7 DA
|
|
00D97A 1 20 EB DA jsr StoreCurrentObjectSelector ; $D97A: 20 EB DA
|
|
00D97D 1
|
|
00D97D 1 ; ----------------------------------------------------------------------------
|
|
00D97D 1 ; If state $6D is zero, return to the action-state dispatcher at $D960.
|
|
00D97D 1 ; ----------------------------------------------------------------------------
|
|
00D97D 1
|
|
00D97D 1 A5 6D lda SpecialSequenceState ; $D97D: A5 6D
|
|
00D97F 1 F0 DF beq SecondaryObject_ActionStatePath
|
|
00D981 1 ; $D97F: F0 DF
|
|
00D981 1
|
|
00D981 1 ; ----------------------------------------------------------------------------
|
|
00D981 1 ; Recalculate the event selector and convert it into an object-related index.
|
|
00D981 1 ;
|
|
00D981 1 ; Calculation:
|
|
00D981 1 ;
|
|
00D981 1 ; A = ((Y >> 1) + 4 - SpecialSequenceState) * 2
|
|
00D981 1 ; ----------------------------------------------------------------------------
|
|
00D981 1 SecondaryObject_RecalculateSelector:
|
|
00D981 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00D984 1 ; $D981: 20 DC E3
|
|
00D984 1
|
|
00D984 1 98 tya ; $D984: 98
|
|
00D985 1 4A lsr ; $D985: 4A
|
|
00D986 1
|
|
00D986 1 69 04 adc #$04 ; $D986: 69 04
|
|
00D988 1 E5 6D sbc SpecialSequenceState ; $D988: E5 6D
|
|
00D98A 1
|
|
00D98A 1 0A asl ; $D98A: 0A
|
|
00D98B 1
|
|
00D98B 1 ; ----------------------------------------------------------------------------
|
|
00D98B 1 ; Compare the calculated object offset against CurrentObjectIndex.
|
|
00D98B 1 ;
|
|
00D98B 1 ; If the calculated offset is below the current object index, branch to the
|
|
00D98B 1 ; transition handler at $D9E6. Otherwise, continue at $D997.
|
|
00D98B 1 ;
|
|
00D98B 1 ; The BCS at $D98F is effectively unconditional if the preceding BCC was not
|
|
00D98B 1 ; taken because CMP establishes carry.
|
|
00D98B 1 ; ----------------------------------------------------------------------------
|
|
00D98B 1
|
|
00D98B 1 C5 E1 cmp CurrentObjectIndex ; $D98B: C5 E1
|
|
00D98D 1 90 57 bcc SecondaryObject_TransitionHandler
|
|
00D98F 1 ; $D98D: 90 57
|
|
00D98F 1
|
|
00D98F 1 B0 06 bcs SecondaryObject_ActionActive
|
|
00D991 1 ; $D98F: B0 06
|
|
00D991 1
|
|
00D991 1 ; ============================================================================
|
|
00D991 1 ; $D991-$D9B2
|
|
00D991 1 ; Secondary-object delay retry and action-active paths.
|
|
00D991 1 ;
|
|
00D991 1 ; The retry path repeatedly selects a delay and performs a geometry test.
|
|
00D991 1 ; Once the test succeeds, the action-active path updates the object and waits
|
|
00D991 1 ; until another state condition selects either the normal loop or transition.
|
|
00D991 1 ; ============================================================================
|
|
00D991 1
|
|
00D991 1 SecondaryObject_RetryPath: ; $D991
|
|
00D991 1 20 B8 DB jsr SelectSecondaryObjectDelay ; $D991: 20 B8 DB
|
|
00D994 1 ; Select a delay value in A.
|
|
00D994 1
|
|
00D994 1 20 41 EB jsr StoreObjectEventBankValue ; $D994: 20 41 EB
|
|
00D997 1 ; Wait for the selected delay.
|
|
00D997 1
|
|
00D997 1 ; ----------------------------------------------------------------------------
|
|
00D997 1 ; Real entry for the action-active path.
|
|
00D997 1 ;
|
|
00D997 1 ; The BCS at $D98F branches here when the calculated object offset is greater
|
|
00D997 1 ; than or equal to CurrentObjectIndex.
|
|
00D997 1 ; ----------------------------------------------------------------------------
|
|
00D997 1
|
|
00D997 1 SecondaryObject_ActionActive: ; $D997
|
|
00D997 1 20 8F E4 jsr SelectGeometryRecord_34 ; $D997: 20 8F E4
|
|
00D99A 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $D99A: 20 5F E5
|
|
00D99D 1
|
|
00D99D 1 B0 F2 bcs SecondaryObject_RetryPath
|
|
00D99F 1 ; $D99D: B0 F2
|
|
00D99F 1
|
|
00D99F 1 ; ----------------------------------------------------------------------------
|
|
00D99F 1 ; Geometry test succeeded. Update the current object and wait for a frame.
|
|
00D99F 1 ; ----------------------------------------------------------------------------
|
|
00D99F 1
|
|
00D99F 1 20 81 DA jsr UpdateCurrentObjectAnimation
|
|
00D9A2 1 ; $D99F: 20 81 DA
|
|
00D9A2 1
|
|
00D9A2 1 SecondaryObject_ActionWait: ; $D9A2
|
|
00D9A2 1 20 48 EB jsr SelectObjectEventBank1 ; $D9A2: 20 48 EB
|
|
00D9A5 1
|
|
00D9A5 1 ; ----------------------------------------------------------------------------
|
|
00D9A5 1 ; If SpecialSequenceState is nonzero, return to the selector calculation at $D981.
|
|
00D9A5 1 ; ----------------------------------------------------------------------------
|
|
00D9A5 1
|
|
00D9A5 1 A5 6D lda SpecialSequenceState ; $D9A5: A5 6D
|
|
00D9A7 1 D0 D8 bne SecondaryObject_RecalculateSelector
|
|
00D9A9 1 ; $D9A7: D0 D8
|
|
00D9A9 1
|
|
00D9A9 1 ; ----------------------------------------------------------------------------
|
|
00D9A9 1 ; Run the per-frame object helper, then evaluate the result from $DB18.
|
|
00D9A9 1 ; ----------------------------------------------------------------------------
|
|
00D9A9 1
|
|
00D9A9 1 20 BC DA jsr CheckCurrentObjectSelector ; $D9A9: 20 BC DA
|
|
00D9AC 1
|
|
00D9AC 1 20 18 DB jsr TestCurrentObjectInput ; $D9AC: 20 18 DB
|
|
00D9AF 1 10 F1 bpl SecondaryObject_ActionWait
|
|
00D9B1 1 ; $D9AF: 10 F1
|
|
00D9B1 1
|
|
00D9B1 1 ; ----------------------------------------------------------------------------
|
|
00D9B1 1 ; A negative result transfers to the transition handler at $D9E6.
|
|
00D9B1 1 ; ----------------------------------------------------------------------------
|
|
00D9B1 1
|
|
00D9B1 1 30 33 bmi SecondaryObject_TransitionHandler
|
|
00D9B3 1 ; $D9B1: 30 33
|
|
00D9B3 1
|
|
00D9B3 1 ; ============================================================================
|
|
00D9B3 1 ; $D9B3-$D9E5
|
|
00D9B3 1 ; Handle selector value eight, update pending state, and retry the geometry
|
|
00D9B3 1 ; test until the secondary object can complete its transition.
|
|
00D9B3 1 ; ============================================================================
|
|
00D9B3 1
|
|
00D9B3 1 SecondaryObject_SelectorEight: ; $D9B3
|
|
00D9B3 1 20 F7 DA jsr UpdateCurrentObjectSelectorState ; $D9B3: 20 F7 DA
|
|
00D9B6 1 20 EB DA jsr StoreCurrentObjectSelector ; $D9B6: 20 EB DA
|
|
00D9B9 1
|
|
00D9B9 1 ; ----------------------------------------------------------------------------
|
|
00D9B9 1 ; When SecondarySequenceState has not reached three, increment PendingScoreIncrement.
|
|
00D9B9 1 ;
|
|
00D9B9 1 ; If CurrentActionState is zero, immediately apply the pending increment to the
|
|
00D9B9 1 ; counters/display and clear PendingScoreIncrement.
|
|
00D9B9 1 ; ----------------------------------------------------------------------------
|
|
00D9B9 1
|
|
00D9B9 1 A5 64 lda SecondarySequenceState ; $D9B9: A5 64
|
|
00D9BB 1 C9 03 cmp #$03 ; $D9BB: C9 03
|
|
00D9BD 1 F0 0D beq SecondaryObject_RunFrameHelper
|
|
00D9BF 1 ; $D9BD: F0 0D
|
|
00D9BF 1
|
|
00D9BF 1 E6 65 inc PendingScoreIncrement ; $D9BF: E6 65
|
|
00D9C1 1
|
|
00D9C1 1 A5 9D lda CurrentActionState ; $D9C1: A5 9D
|
|
00D9C3 1 D0 07 bne SecondaryObject_RunFrameHelper
|
|
00D9C5 1 ; $D9C3: D0 07
|
|
00D9C5 1
|
|
00D9C5 1 20 A6 CF jsr UpdateCountersAndDisplay
|
|
00D9C8 1 ; $D9C5: 20 A6 CF
|
|
00D9C8 1
|
|
00D9C8 1 A9 00 lda #$00 ; $D9C8: A9 00
|
|
00D9CA 1 85 65 sta PendingScoreIncrement ; $D9CA: 85 65
|
|
00D9CC 1
|
|
00D9CC 1 ; ----------------------------------------------------------------------------
|
|
00D9CC 1 ; Run the per-frame secondary-object helper and repeat the geometry test.
|
|
00D9CC 1 ; ----------------------------------------------------------------------------
|
|
00D9CC 1
|
|
00D9CC 1 SecondaryObject_RunFrameHelper: ; $D9CC
|
|
00D9CC 1 20 BC DA jsr CheckCurrentObjectSelector ; $D9CC: 20 BC DA
|
|
00D9CF 1
|
|
00D9CF 1 20 8F E4 jsr SelectGeometryRecord_34 ; $D9CF: 20 8F E4
|
|
00D9D2 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $D9D2: 20 5F E5
|
|
00D9D5 1
|
|
00D9D5 1 90 09 bcc SecondaryObject_FinishSelectorEight
|
|
00D9D7 1 ; $D9D5: 90 09
|
|
00D9D7 1
|
|
00D9D7 1 ; ----------------------------------------------------------------------------
|
|
00D9D7 1 ; Geometry test still blocks completion.
|
|
00D9D7 1 ;
|
|
00D9D7 1 ; Select a delay, wait, and retry from the per-frame helper at $D9CC.
|
|
00D9D7 1 ; ----------------------------------------------------------------------------
|
|
00D9D7 1
|
|
00D9D7 1 20 B8 DB jsr SelectSecondaryObjectDelay ; $D9D7: 20 B8 DB
|
|
00D9DA 1 20 41 EB jsr StoreObjectEventBankValue ; $D9DA: 20 41 EB
|
|
00D9DD 1
|
|
00D9DD 1 4C CC D9 jmp SecondaryObject_RunFrameHelper
|
|
00D9E0 1 ; $D9DD: 4C CC D9
|
|
00D9E0 1
|
|
00D9E0 1 ; ----------------------------------------------------------------------------
|
|
00D9E0 1 ; Geometry test completed. Update the object and leave through the common
|
|
00D9E0 1 ; engine exit.
|
|
00D9E0 1 ; ----------------------------------------------------------------------------
|
|
00D9E0 1
|
|
00D9E0 1 SecondaryObject_FinishSelectorEight: ; $D9E0
|
|
00D9E0 1 20 81 DA jsr UpdateCurrentObjectAnimation
|
|
00D9E3 1 ; $D9E0: 20 81 DA
|
|
00D9E3 1
|
|
00D9E3 1 4C 6A EB jmp CommonEngineExit ; $D9E3: 4C 6A EB
|
|
00D9E6 1
|
|
00D9E6 1 ; ============================================================================
|
|
00D9E6 1 ; $D9E6-$DA0E
|
|
00D9E6 1 ; Secondary-object transition handler.
|
|
00D9E6 1 ;
|
|
00D9E6 1 ; Entry:
|
|
00D9E6 1 ; X is restored or derived by GetCurrentObjectStateIndex.
|
|
00D9E6 1 ;
|
|
00D9E6 1 ; The handler advances the indexed object state. If that state becomes
|
|
00D9E6 1 ; nonzero, it transfers directly to the shared negative-result path at $DA25.
|
|
00D9E6 1 ; If the state wraps to zero, it loads a new inline position record and begins
|
|
00D9E6 1 ; a new object-processing cycle.
|
|
00D9E6 1 ; ============================================================================
|
|
00D9E6 1
|
|
00D9E6 1 SecondaryObject_TransitionHandler: ; $D9E6
|
|
00D9E6 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00D9E9 1 ; $D9E6: 20 68 DA
|
|
00D9E9 1
|
|
00D9E9 1 ; ----------------------------------------------------------------------------
|
|
00D9E9 1 ; Advance the indexed state byte at $0595,X.
|
|
00D9E9 1 ;
|
|
00D9E9 1 ; A nonzero result transfers to the shared path at $DA25.
|
|
00D9E9 1 ; ----------------------------------------------------------------------------
|
|
00D9E9 1
|
|
00D9E9 1 FE 95 05 inc $0595,x ; $D9E9: FE 95 05
|
|
00D9EC 1 D0 37 bne SecondaryObject_NegativeResultPath
|
|
00D9EE 1 ; $D9EC: D0 37
|
|
00D9EE 1
|
|
00D9EE 1 ; ----------------------------------------------------------------------------
|
|
00D9EE 1 ; The indexed state wrapped from $FF to zero.
|
|
00D9EE 1 ;
|
|
00D9EE 1 ; Initialize object offset $06 with a new position record:
|
|
00D9EE 1 ;
|
|
00D9EE 1 ; $0509,$X = $00
|
|
00D9EE 1 ; $050A,$X = $01
|
|
00D9EE 1 ; $053A,$X = $00
|
|
00D9EE 1 ; $053B,$X = $F8
|
|
00D9EE 1 ; ----------------------------------------------------------------------------
|
|
00D9EE 1
|
|
00D9EE 1 20 A7 C9 jsr LoadObjectPositionInline
|
|
00D9F1 1 ; $D9EE: 20 A7 C9
|
|
00D9F1 1
|
|
00D9F1 1 06 .byte $06 ; $D9F1: object offset/metadata
|
|
00D9F2 1 00 01 00 F8 .byte $00,$01,$00,$F8 ; $D9F2-$D9F5: position fields
|
|
00D9F6 1
|
|
00D9F6 1 ; ----------------------------------------------------------------------------
|
|
00D9F6 1 ; Recalculate the indexed object state and advance $0595,X again.
|
|
00D9F6 1 ; ----------------------------------------------------------------------------
|
|
00D9F6 1
|
|
00D9F6 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00D9F9 1 ; $D9F6: 20 68 DA
|
|
00D9F9 1
|
|
00D9F9 1 FE 95 05 inc $0595,x ; $D9F9: FE 95 05
|
|
00D9FC 1 85 95 sta $95 ; $D9FC: 85 95
|
|
00D9FE 1 D0 06 bne SecondaryObject_RunFrameHelper_DA06
|
|
00DA00 1 ; $D9FE: D0 06
|
|
00DA00 1
|
|
00DA00 1 ; ----------------------------------------------------------------------------
|
|
00DA00 1 ; If A is zero, select a delay and wait before continuing.
|
|
00DA00 1 ; ----------------------------------------------------------------------------
|
|
00DA00 1 SecondaryObject_SelectRetryDelay:
|
|
00DA00 1 20 B8 DB jsr SelectSecondaryObjectDelay ; $DA00: 20 B8 DB
|
|
00DA03 1 20 41 EB jsr StoreObjectEventBankValue ; $DA03: 20 41 EB
|
|
00DA06 1
|
|
00DA06 1 ; ----------------------------------------------------------------------------
|
|
00DA06 1 ; Run the per-frame helper, then begin another geometry/region test.
|
|
00DA06 1 ; ----------------------------------------------------------------------------
|
|
00DA06 1
|
|
00DA06 1 SecondaryObject_RunFrameHelper_DA06: ; $DA06
|
|
00DA06 1 20 BC DA jsr CheckCurrentObjectSelector ; $DA06: 20 BC DA
|
|
00DA09 1
|
|
00DA09 1 20 B0 E4 jsr UseFixedGeometryRecord54 ; $DA09: 20 B0 E4
|
|
00DA0C 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $DA0C: 20 5F E5
|
|
00DA0F 1
|
|
00DA0F 1 ; ============================================================================
|
|
00DA0F 1 ; $DA0F-$DA10
|
|
00DA0F 1 ; Complete the geometry retry path begun at $DA06.
|
|
00DA0F 1 ;
|
|
00DA0F 1 ; Carry set returns to $DA00, where a new delay is selected before retrying.
|
|
00DA0F 1 ; ============================================================================
|
|
00DA0F 1
|
|
00DA0F 1 B0 EF bcs SecondaryObject_SelectRetryDelay
|
|
00DA11 1 ; $DA0F: B0 EF
|
|
00DA11 1
|
|
00DA11 1 ; ============================================================================
|
|
00DA11 1 ; $DA11-$DA24
|
|
00DA11 1 ; Wait while the secondary object remains in an active motion/state phase.
|
|
00DA11 1 ; ============================================================================
|
|
00DA11 1
|
|
00DA11 1 SecondaryObject_WaitForState: ; $DA11
|
|
00DA11 1 20 48 EB jsr SelectObjectEventBank1 ; $DA11: 20 48 EB
|
|
00DA14 1 20 BC DA jsr CheckCurrentObjectSelector ; $DA14: 20 BC DA
|
|
00DA17 1
|
|
00DA17 1 ; ----------------------------------------------------------------------------
|
|
00DA17 1 ; SpecialSequenceState or ObjectTransitionState immediately selects the timer path at $DA25.
|
|
00DA17 1 ; ----------------------------------------------------------------------------
|
|
00DA17 1
|
|
00DA17 1 A5 6D lda SpecialSequenceState ; $DA17: A5 6D
|
|
00DA19 1 05 6E ora ObjectTransitionState ; $DA19: 05 6E
|
|
00DA1B 1 D0 08 bne SecondaryObject_NegativeResultPath
|
|
00DA1D 1 ; $DA1B: D0 08
|
|
00DA1D 1
|
|
00DA1D 1 ; ----------------------------------------------------------------------------
|
|
00DA1D 1 ; Continue waiting while BaseMotionPhase is zero.
|
|
00DA1D 1 ; ----------------------------------------------------------------------------
|
|
00DA1D 1
|
|
00DA1D 1 A5 5D lda BaseMotionPhase ; $DA1D: A5 5D
|
|
00DA1F 1 F0 F0 beq SecondaryObject_WaitForState
|
|
00DA21 1 ; $DA1F: F0 F0
|
|
00DA21 1
|
|
00DA21 1 ; ----------------------------------------------------------------------------
|
|
00DA21 1 ; Continue waiting while PendingStateTransition is nonzero.
|
|
00DA21 1 ; ----------------------------------------------------------------------------
|
|
00DA21 1
|
|
00DA21 1 A5 60 lda PendingStateTransition ; $DA21: A5 60
|
|
00DA23 1 D0 EC bne SecondaryObject_WaitForState
|
|
00DA25 1 ; $DA23: D0 EC
|
|
00DA25 1
|
|
00DA25 1 ; ============================================================================
|
|
00DA25 1 ; $DA25-$DA5E
|
|
00DA25 1 ; Shared secondary-object timer and transition path.
|
|
00DA25 1 ;
|
|
00DA25 1 ; This is the real destination used by several earlier jumps and branches.
|
|
00DA25 1 ; ============================================================================
|
|
00DA25 1
|
|
00DA25 1 SecondaryObject_NegativeResultPath: ; $DA25
|
|
00DA25 1 A6 E1 ldx CurrentObjectIndex ; $DA25: A6 E1
|
|
00DA27 1
|
|
00DA27 1 A9 01 lda #$01 ; $DA27: A9 01
|
|
00DA29 1 9D B1 05 sta $05B1,x ; $DA29: 9D B1 05
|
|
00DA2C 1
|
|
00DA2C 1 ; ----------------------------------------------------------------------------
|
|
00DA2C 1 ; Wait for a frame, process the object, and count down its timer.
|
|
00DA2C 1 ; ----------------------------------------------------------------------------
|
|
00DA2C 1
|
|
00DA2C 1 SecondaryObject_DA2C_TimerLoop: ; $DA2C
|
|
00DA2C 1 20 48 EB jsr SelectObjectEventBank1 ; $DA2C: 20 48 EB
|
|
00DA2F 1 20 BC DA jsr CheckCurrentObjectSelector ; $DA2F: 20 BC DA
|
|
00DA32 1
|
|
00DA32 1 A6 E1 ldx CurrentObjectIndex ; $DA32: A6 E1
|
|
00DA34 1
|
|
00DA34 1 DE B1 05 dec $05B1,x ; $DA34: DE B1 05
|
|
00DA37 1 D0 10 bne SecondaryObject_DA49_CheckSelector
|
|
00DA39 1 ; $DA37: D0 10
|
|
00DA39 1
|
|
00DA39 1 ; ----------------------------------------------------------------------------
|
|
00DA39 1 ; Timer expired. Run the alternate geometry test.
|
|
00DA39 1 ; ----------------------------------------------------------------------------
|
|
00DA39 1
|
|
00DA39 1 20 9A E4 jsr SelectGeometryRecord_28 ; $DA39: 20 9A E4
|
|
00DA3C 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $DA3C: 20 5F E5
|
|
00DA3F 1
|
|
00DA3F 1 90 1B bcc SecondaryObject_DA5C_ReturnToIndexedPath
|
|
00DA41 1 ; $DA3F: 90 1B
|
|
00DA41 1
|
|
00DA41 1 ; ----------------------------------------------------------------------------
|
|
00DA41 1 ; Geometry test remains active.
|
|
00DA41 1 ;
|
|
00DA41 1 ; Select a new timer value and store it into $05B1,X.
|
|
00DA41 1 ; ----------------------------------------------------------------------------
|
|
00DA41 1
|
|
00DA41 1 20 B8 DB jsr SelectSecondaryObjectDelay ; $DA41: 20 B8 DB
|
|
00DA44 1
|
|
00DA44 1 A6 E1 ldx CurrentObjectIndex ; $DA44: A6 E1
|
|
00DA46 1 9D B1 05 sta $05B1,x ; $DA46: 9D B1 05
|
|
00DA49 1
|
|
00DA49 1 ; ----------------------------------------------------------------------------
|
|
00DA49 1 ; Derive the current selector.
|
|
00DA49 1 ;
|
|
00DA49 1 ; Selector one, or a nonzero SpecialSequenceState, returns to the timer loop.
|
|
00DA49 1 ; ----------------------------------------------------------------------------
|
|
00DA49 1
|
|
00DA49 1 SecondaryObject_DA49_CheckSelector: ; $DA49
|
|
00DA49 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00DA4C 1 ; $DA49: 20 DC E3
|
|
00DA4C 1
|
|
00DA4C 1 C0 01 cpy #$01 ; $DA4C: C0 01
|
|
00DA4E 1 F0 DC beq SecondaryObject_DA2C_TimerLoop
|
|
00DA50 1 ; $DA4E: F0 DC
|
|
00DA50 1
|
|
00DA50 1 A5 6D lda SpecialSequenceState ; $DA50: A5 6D
|
|
00DA52 1 D0 D8 bne SecondaryObject_DA2C_TimerLoop
|
|
00DA54 1 ; $DA52: D0 D8
|
|
00DA54 1
|
|
00DA54 1 ; ----------------------------------------------------------------------------
|
|
00DA54 1 ; Continue the timer loop while $DB18 returns carry clear.
|
|
00DA54 1 ;
|
|
00DA54 1 ; Carry set returns to the timer initialization path at $D8C3.
|
|
00DA54 1 ; ----------------------------------------------------------------------------
|
|
00DA54 1
|
|
00DA54 1 20 18 DB jsr TestCurrentObjectInput ; $DA54: 20 18 DB
|
|
00DA57 1 90 D3 bcc SecondaryObject_DA2C_TimerLoop
|
|
00DA59 1 ; $DA57: 90 D3
|
|
00DA59 1
|
|
00DA59 1 4C C3 D8 jmp SecondaryObject_ActivateTimer
|
|
00DA5C 1 ; $DA59: 4C C3 D8
|
|
00DA5C 1
|
|
00DA5C 1 ; ----------------------------------------------------------------------------
|
|
00DA5C 1 ; The alternate geometry test completed.
|
|
00DA5C 1 ;
|
|
00DA5C 1 ; Return to the indexed-state path at $D967.
|
|
00DA5C 1 ; ----------------------------------------------------------------------------
|
|
00DA5C 1
|
|
00DA5C 1 SecondaryObject_DA5C_ReturnToIndexedPath: ; $DA5C
|
|
00DA5C 1 4C 67 D9 jmp SecondaryObject_AdvanceIndexedState
|
|
00DA5F 1 ; $DA5C: 4C 67 D9
|
|
00DA5F 1
|
|
00DA5F 1 ; ============================================================================
|
|
00DA5F 1 ; $DA5F-$DA67
|
|
00DA5F 1 ; Convert CurrentObjectIndex into a smaller selector and tail-call $E246.
|
|
00DA5F 1 ;
|
|
00DA5F 1 ; Calculation:
|
|
00DA5F 1 ;
|
|
00DA5F 1 ; Y = (CurrentObjectIndex >> 1) - 1 - !C
|
|
00DA5F 1 ;
|
|
00DA5F 1 ; The SBC intentionally uses carry left by LSR.
|
|
00DA5F 1 ; ============================================================================
|
|
00DA5F 1
|
|
00DA5F 1 ; ----------------------------------------------------------------------------
|
|
00DA5F 1 ; Contract:
|
|
00DA5F 1 ; Description: Implements Get Current Object Selector.
|
|
00DA5F 1 ; Entry: Registers: A; Memory: currentobjectindex
|
|
00DA5F 1 ; Returns/products: Registers/clobbers: A, Y; Flags: condition flags may carry result state
|
|
00DA5F 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DA5F 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00DA5F 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DA5F 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DA5F 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00DA5F 1 ; ----------------------------------------------------------------------------
|
|
00DA5F 1 GetCurrentObjectSelector: ; $DA5F
|
|
00DA5F 1 A5 E1 lda CurrentObjectIndex ; $DA5F: A5 E1
|
|
00DA61 1 4A lsr ; $DA61: 4A
|
|
00DA62 1
|
|
00DA62 1 E9 01 sbc #$01 ; $DA62: E9 01
|
|
00DA64 1 A8 tay ; $DA64: A8
|
|
00DA65 1
|
|
00DA65 1 4C 46 E2 jmp FindObjectStateForSelector ; $DA65: 4C 46 E2
|
|
00DA68 1
|
|
00DA68 1 ; ============================================================================
|
|
00DA68 1 ; $DA68-$DA6C
|
|
00DA68 1 ; Convert CurrentObjectIndex into an object-state array index.
|
|
00DA68 1 ;
|
|
00DA68 1 ; Exit:
|
|
00DA68 1 ; A = CurrentObjectIndex >> 1
|
|
00DA68 1 ; X = CurrentObjectIndex >> 1
|
|
00DA68 1 ; ============================================================================
|
|
00DA68 1
|
|
00DA68 1 GetCurrentObjectStateIndex: ; $DA68
|
|
00DA68 1 A5 E1 lda CurrentObjectIndex ; $DA68: A5 E1
|
|
00DA6A 1 4A lsr ; $DA6A: 4A
|
|
00DA6B 1 AA tax ; $DA6B: AA
|
|
00DA6C 1
|
|
00DA6C 1 60 rts ; $DA6C: 60
|
|
00DA6D 1
|
|
00DA6D 1 ; ============================================================================
|
|
00DA6D 1 ; $DA6D-$DA80
|
|
00DA6D 1 ; Compare the current event selector against the object's derived selector.
|
|
00DA6D 1 ;
|
|
00DA6D 1 ; When they match, mark the corresponding zero-page object state at $95,X
|
|
00DA6D 1 ; as active by storing $01.
|
|
00DA6D 1 ; ============================================================================
|
|
00DA6D 1
|
|
00DA6D 1 ; ----------------------------------------------------------------------------
|
|
00DA6D 1 ; Contract:
|
|
00DA6D 1 ; Description: Implements Mark Matching Object State.
|
|
00DA6D 1 ; Entry: Registers: A, X, Y; Memory: mathtemp05
|
|
00DA6D 1 ; Returns/products: Registers/clobbers: A, X
|
|
00DA6D 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DA6D 1 ; Memory effects: mathtemp05, $95
|
|
00DA6D 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DA6D 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DA6D 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00DA6D 1 ; ----------------------------------------------------------------------------
|
|
00DA6D 1 MarkMatchingObjectState: ; $DA6D
|
|
00DA6D 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00DA70 1 ; $DA6D: 20 DC E3
|
|
00DA70 1 ; Returns an event/object selector in X and Y.
|
|
00DA70 1
|
|
00DA70 1 8A txa ; $DA70: 8A
|
|
00DA71 1 38 sec ; $DA71: 38
|
|
00DA72 1 E9 06 sbc #$06 ; $DA72: E9 06
|
|
00DA74 1 85 05 sta MathTemp05 ; $DA74: 85 05
|
|
00DA76 1
|
|
00DA76 1 C4 05 cpy MathTemp05 ; $DA76: C4 05
|
|
00DA78 1 D0 06 bne MarkMatchingObjectState_Return
|
|
00DA7A 1 ; $DA78: D0 06
|
|
00DA7A 1
|
|
00DA7A 1 ; ----------------------------------------------------------------------------
|
|
00DA7A 1 ; The selectors match.
|
|
00DA7A 1 ;
|
|
00DA7A 1 ; Convert A to the corresponding indexed state slot and set $95,X to one.
|
|
00DA7A 1 ; ----------------------------------------------------------------------------
|
|
00DA7A 1
|
|
00DA7A 1 4A lsr ; $DA7A: 4A
|
|
00DA7B 1 AA tax ; $DA7B: AA
|
|
00DA7C 1
|
|
00DA7C 1 A9 01 lda #$01 ; $DA7C: A9 01
|
|
00DA7E 1 95 95 sta $95,x ; $DA7E: 95 95
|
|
00DA80 1
|
|
00DA80 1 MarkMatchingObjectState_Return: ; $DA80
|
|
00DA80 1 60 rts ; $DA80: 60
|
|
00DA81 1
|
|
00DA81 1 ; ============================================================================
|
|
00DA81 1 ; $DA81-$DA9B
|
|
00DA81 1 ; Update the current object's animation and sprite-state values.
|
|
00DA81 1 ;
|
|
00DA81 1 ; This routine:
|
|
00DA81 1 ; 1. Updates the object through $E6B7.
|
|
00DA81 1 ; 2. Derives an event selector through GetCurrentObjectSelectorAndState.
|
|
00DA81 1 ; 3. Converts Y and X to compact table indices.
|
|
00DA81 1 ; 4. Stores table-selected values into $03B0,X and $039B,X.
|
|
00DA81 1 ;
|
|
00DA81 1 ; The table loads intentionally use bases one byte before the visible tables:
|
|
00DA81 1 ;
|
|
00DA81 1 ; $DA9B,Y
|
|
00DA81 1 ; $DA9F,Y
|
|
00DA81 1 ; ============================================================================
|
|
00DA81 1
|
|
00DA81 1 UpdateCurrentObjectAnimation: ; $DA81
|
|
00DA81 1 A6 E1 ldx CurrentObjectIndex ; $DA81: A6 E1
|
|
00DA83 1 20 B7 E6 jsr ClearMovementTransforms ; $DA83: 20 B7 E6
|
|
00DA86 1
|
|
00DA86 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00DA89 1 ; $DA86: 20 DC E3
|
|
00DA89 1
|
|
00DA89 1 ; ----------------------------------------------------------------------------
|
|
00DA89 1 ; Convert the Y selector to a four-entry table index.
|
|
00DA89 1 ; ----------------------------------------------------------------------------
|
|
00DA89 1
|
|
00DA89 1 98 tya ; $DA89: 98
|
|
00DA8A 1 4A lsr ; $DA8A: 4A
|
|
00DA8B 1 A8 tay ; $DA8B: A8
|
|
00DA8C 1
|
|
00DA8C 1 ; ----------------------------------------------------------------------------
|
|
00DA8C 1 ; Convert the X selector to its sprite-array index.
|
|
00DA8C 1 ; ----------------------------------------------------------------------------
|
|
00DA8C 1
|
|
00DA8C 1 8A txa ; $DA8C: 8A
|
|
00DA8D 1 4A lsr ; $DA8D: 4A
|
|
00DA8E 1 AA tax ; $DA8E: AA
|
|
00DA8F 1
|
|
00DA8F 1 ; ----------------------------------------------------------------------------
|
|
00DA8F 1 ; Load the table-selected animation values.
|
|
00DA8F 1 ;
|
|
00DA8F 1 ; The first table access uses base $DA9B, where byte $DA9B is the preceding
|
|
00DA8F 1 ; RTS opcode. Expected Y values begin at one.
|
|
00DA8F 1 ; ----------------------------------------------------------------------------
|
|
00DA8F 1
|
|
00DA8F 1 B9 9B DA lda $DA9B,y ; $DA8F: B9 9B DA
|
|
00DA92 1 9D B0 03 sta $03B0,x ; $DA92: 9D B0 03
|
|
00DA95 1
|
|
00DA95 1 B9 9F DA lda $DA9F,y ; $DA95: B9 9F DA
|
|
00DA98 1 9D 9B 03 sta $039B,x ; $DA98: 9D 9B 03
|
|
00DA9B 1
|
|
00DA9B 1 60 rts ; $DA9B: 60
|
|
00DA9C 1
|
|
00DA9C 1 ; ============================================================================
|
|
00DA9C 1 ; $DA9C-$DAA3
|
|
00DA9C 1 ; Parallel four-byte animation lookup tables.
|
|
00DA9C 1 ;
|
|
00DA9C 1 ; Because the code uses one-byte-earlier bases, expected Y values are $01-$04:
|
|
00DA9C 1 ;
|
|
00DA9C 1 ; LDA $DA9B,Y:
|
|
00DA9C 1 ; Y=$01 -> $DA9C
|
|
00DA9C 1 ; Y=$04 -> $DA9F
|
|
00DA9C 1 ;
|
|
00DA9C 1 ; LDA $DA9F,Y:
|
|
00DA9C 1 ; Y=$01 -> $DAA0
|
|
00DA9C 1 ; Y=$04 -> $DAA3
|
|
00DA9C 1 ; ============================================================================
|
|
00DA9C 1
|
|
00DA9C 1 ObjectAnimationAttributeTable: ; $DA9C
|
|
00DA9C 1 1D 1D 1A 7A .byte $1D,$1D,$1A,$7A
|
|
00DAA0 1
|
|
00DAA0 1 ObjectAnimationFrameTable: ; $DAA0
|
|
00DAA0 1 53 56 4D 7A .byte $53,$56,$4D,$7A
|
|
00DAA4 1
|
|
00DAA4 1 ; ============================================================================
|
|
00DAA4 1 ; $DAA4-$DABB
|
|
00DAA4 1 ; Count matching object-state entries.
|
|
00DAA4 1 ;
|
|
00DAA4 1 ; The selector returned by GetCurrentObjectSelectorAndState is compared against the four entries at
|
|
00DAA4 1 ; $0598-$059B. Carry is set on return when at least two entries match.
|
|
00DAA4 1 ;
|
|
00DAA4 1 ; Return:
|
|
00DAA4 1 ; Y = number of matching entries
|
|
00DAA4 1 ; C = set when Y >= 2
|
|
00DAA4 1 ; ============================================================================
|
|
00DAA4 1
|
|
00DAA4 1 ; ----------------------------------------------------------------------------
|
|
00DAA4 1 ; Contract:
|
|
00DAA4 1 ; Description: Implements Count Matching Object States.
|
|
00DAA4 1 ; Entry: Registers: A, X, Y; Memory: $0598
|
|
00DAA4 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00DAA4 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DAA4 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00DAA4 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DAA4 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DAA4 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00DAA4 1 ; ----------------------------------------------------------------------------
|
|
00DAA4 1 CountMatchingObjectStates: ; $DAA4
|
|
00DAA4 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00DAA7 1 ; $DAA4: 20 DC E3
|
|
00DAA7 1
|
|
00DAA7 1 98 tya ; $DAA7: 98
|
|
00DAA8 1 30 2B bmi FinishSecondaryObject ; $DAA8: 30 2B
|
|
00DAAA 1
|
|
00DAAA 1 ; ----------------------------------------------------------------------------
|
|
00DAAA 1 ; Count entries in $0598-$059B that equal A.
|
|
00DAAA 1 ; ----------------------------------------------------------------------------
|
|
00DAAA 1
|
|
00DAAA 1 A0 00 ldy #$00 ; $DAAA: A0 00
|
|
00DAAC 1 A2 03 ldx #$03 ; $DAAC: A2 03
|
|
00DAAE 1
|
|
00DAAE 1 CountMatchingObjectStates_Loop: ; $DAAE
|
|
00DAAE 1 DD 98 05 cmp $0598,x ; $DAAE: DD 98 05
|
|
00DAB1 1 D0 01 bne CountMatchingObjectStates_Next
|
|
00DAB3 1 ; $DAB1: D0 01
|
|
00DAB3 1
|
|
00DAB3 1 C8 iny ; $DAB3: C8
|
|
00DAB4 1
|
|
00DAB4 1 CountMatchingObjectStates_Next: ; $DAB4
|
|
00DAB4 1 CA dex ; $DAB4: CA
|
|
00DAB5 1 10 F7 bpl CountMatchingObjectStates_Loop
|
|
00DAB7 1 ; $DAB5: 10 F7
|
|
00DAB7 1
|
|
00DAB7 1 C0 02 cpy #$02 ; $DAB7: C0 02
|
|
00DAB9 1 B0 08 bcs DisableCurrentObject ; $DAB9: B0 08
|
|
00DABB 1
|
|
00DABB 1 60 rts ; $DABB: 60
|
|
00DABC 1
|
|
00DABC 1 ; ============================================================================
|
|
00DABC 1 ; $DABC-$DAC2
|
|
00DABC 1 ; Check whether the selector returned by GetCurrentObjectSelectorAndState is negative.
|
|
00DABC 1 ;
|
|
00DABC 1 ; Return:
|
|
00DABC 1 ; N flag reflects the selector sign.
|
|
00DABC 1 ;
|
|
00DABC 1 ; A negative selector transfers to the common secondary-object finish path.
|
|
00DABC 1 ; ============================================================================
|
|
00DABC 1
|
|
00DABC 1 ; ----------------------------------------------------------------------------
|
|
00DABC 1 ; Contract:
|
|
00DABC 1 ; Description: Implements Check Current Object Selector.
|
|
00DABC 1 ; Entry: Registers: Y
|
|
00DABC 1 ; Returns/products: Registers/clobbers: A
|
|
00DABC 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DABC 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00DABC 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DABC 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DABC 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 6.
|
|
00DABC 1 ; ----------------------------------------------------------------------------
|
|
00DABC 1 CheckCurrentObjectSelector: ; $DABC
|
|
00DABC 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00DABF 1 ; $DABC: 20 DC E3
|
|
00DABF 1
|
|
00DABF 1 98 tya ; $DABF: 98
|
|
00DAC0 1 30 13 bmi FinishSecondaryObject ; $DAC0: 30 13
|
|
00DAC2 1
|
|
00DAC2 1 60 rts ; $DAC2: 60
|
|
00DAC3 1
|
|
00DAC3 1 ; ============================================================================
|
|
00DAC3 1 ; $DAC3-$DAD4
|
|
00DAC3 1 ; Disable the current object and advance the associated state sequence.
|
|
00DAC3 1 ;
|
|
00DAC3 1 ; This path is entered when at least two object-state entries match.
|
|
00DAC3 1 ; ============================================================================
|
|
00DAC3 1
|
|
00DAC3 1 DisableCurrentObject: ; $DAC3
|
|
00DAC3 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DAC3: 20 DC E3
|
|
00DAC6 1
|
|
00DAC6 1 98 tya ; $DAC6: 98
|
|
00DAC7 1 4A lsr ; $DAC7: 4A
|
|
00DAC8 1 ; ----------------------------------------------------------------------------
|
|
00DAC8 1 ; Contract:
|
|
00DAC8 1 ; Description: Internal state-routing entry that stores A as the state selector.
|
|
00DAC8 1 ; Entry: A = state selector.
|
|
00DAC8 1 ; Returns/products: StateSelector updated; returns through parent routine flow.
|
|
00DAC8 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DAC8 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00DAC8 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DAC8 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DAC8 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00DAC8 1 ; ----------------------------------------------------------------------------
|
|
00DAC8 1 StoreStateSelector:
|
|
00DAC8 1 85 72 sta StateSelector ; $DAC8: 85 72
|
|
00DACA 1
|
|
00DACA 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DACD 1 ; $DACA: 20 68 DA
|
|
00DACD 1
|
|
00DACD 1 A9 FF lda #$FF ; $DACD: A9 FF
|
|
00DACF 1 9D 95 05 sta $0595,x ; $DACF: 9D 95 05
|
|
00DAD2 1
|
|
00DAD2 1 20 E4 CC jsr AdvanceAlternateStateSequence
|
|
00DAD5 1 ; $DAD2: 20 E4 CC
|
|
00DAD5 1
|
|
00DAD5 1 ; ============================================================================
|
|
00DAD5 1 ; $DAD5-$DAEA
|
|
00DAD5 1 ; Finish the current secondary-object sequence.
|
|
00DAD5 1 ;
|
|
00DAD5 1 ; This path:
|
|
00DAD5 1 ; 1. Calls the engine helper at $E2D3.
|
|
00DAD5 1 ; 2. Waits $1E ticks.
|
|
00DAD5 1 ; 3. Sets the current object's animation fields to $7A.
|
|
00DAD5 1 ; 4. Leaves through the common engine exit.
|
|
00DAD5 1 ; ============================================================================
|
|
00DAD5 1
|
|
00DAD5 1 FinishSecondaryObject: ; $DAD5
|
|
00DAD5 1 20 D3 E2 jsr ClearCurrentObjectMovement ; $DAD5: 20 D3 E2
|
|
00DAD8 1
|
|
00DAD8 1 A9 1E lda #$1E ; $DAD8: A9 1E
|
|
00DADA 1 20 41 EB jsr StoreObjectEventBankValue ; $DADA: 20 41 EB
|
|
00DADD 1
|
|
00DADD 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DAE0 1 ; $DADD: 20 68 DA
|
|
00DAE0 1
|
|
00DAE0 1 A9 7A lda #$7A ; $DAE0: A9 7A
|
|
00DAE2 1 9D B0 03 sta $03B0,x ; $DAE2: 9D B0 03
|
|
00DAE5 1 9D 9B 03 sta $039B,x ; $DAE5: 9D 9B 03
|
|
00DAE8 1
|
|
00DAE8 1 4C 6A EB jmp CommonEngineExit ; $DAE8: 4C 6A EB
|
|
00DAEB 1
|
|
00DAEB 1 ; ============================================================================
|
|
00DAEB 1 ; $DAEB-$DAF6
|
|
00DAEB 1 ; Store the current selector in the object-state mirror array.
|
|
00DAEB 1 ;
|
|
00DAEB 1 ; When TrajectoryEvaluationEnabled is zero, GetCurrentObjectSelectorAndState returns a selector:
|
|
00DAEB 1 ;
|
|
00DAEB 1 ; X = destination index
|
|
00DAEB 1 ; Y = selector value
|
|
00DAEB 1 ;
|
|
00DAEB 1 ; The selector is stored at $9B,X.
|
|
00DAEB 1 ; ============================================================================
|
|
00DAEB 1
|
|
00DAEB 1 ; ----------------------------------------------------------------------------
|
|
00DAEB 1 ; Contract:
|
|
00DAEB 1 ; Description: Implements Store Current Object Selector.
|
|
00DAEB 1 ; Entry: Registers: A, Y; Memory: trajectoryevaluationenabled
|
|
00DAEB 1 ; Returns/products: Registers/clobbers: A, X
|
|
00DAEB 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DAEB 1 ; Memory effects: $9b
|
|
00DAEB 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DAEB 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DAEB 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00DAEB 1 ; ----------------------------------------------------------------------------
|
|
00DAEB 1 StoreCurrentObjectSelector: ; $DAEB
|
|
00DAEB 1 A5 86 lda TrajectoryEvaluationEnabled ; $DAEB: A5 86
|
|
00DAED 1 D0 07 bne StoreCurrentObjectSelector_Return
|
|
00DAEF 1 ; $DAED: D0 07
|
|
00DAEF 1
|
|
00DAEF 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DAEF: 20 DC E3
|
|
00DAF2 1
|
|
00DAF2 1 AA tax ; $DAF2: AA
|
|
00DAF3 1 98 tya ; $DAF3: 98
|
|
00DAF4 1
|
|
00DAF4 1 95 9B sta $9B,x ; $DAF4: 95 9B
|
|
00DAF6 1
|
|
00DAF6 1 StoreCurrentObjectSelector_Return: ; $DAF6
|
|
00DAF6 1 60 rts ; $DAF6: 60
|
|
00DAF7 1
|
|
00DAF7 1 ; ============================================================================
|
|
00DAF7 1 ; $DAF7-$DB17
|
|
00DAF7 1 ; Compare the current selector against $9E and update the indexed object state.
|
|
00DAF7 1 ;
|
|
00DAF7 1 ; This routine can:
|
|
00DAF7 1 ;
|
|
00DAF7 1 ; - finish the current object sequence,
|
|
00DAF7 1 ; - disable an object and advance state,
|
|
00DAF7 1 ; - decrement $0595,X,
|
|
00DAF7 1 ; - or increment $0595,X.
|
|
00DAF7 1 ; ============================================================================
|
|
00DAF7 1
|
|
00DAF7 1 ; ----------------------------------------------------------------------------
|
|
00DAF7 1 ; Contract:
|
|
00DAF7 1 ; Description: Updates Current Object Selector State.
|
|
00DAF7 1 ; Entry: Registers: A, Y; Memory: $9e, objecttransitionstate
|
|
00DAF7 1 ; Returns/products: Registers/clobbers: A, Y; Flags: condition flags may carry result state
|
|
00DAF7 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DAF7 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00DAF7 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DAF7 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DAF7 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00DAF7 1 ; ----------------------------------------------------------------------------
|
|
00DAF7 1 UpdateCurrentObjectSelectorState: ; $DAF7
|
|
00DAF7 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DAF7: 20 DC E3
|
|
00DAFA 1
|
|
00DAFA 1 98 tya ; $DAFA: 98
|
|
00DAFB 1 30 D8 bmi FinishSecondaryObject ; $DAFB: 30 D8
|
|
00DAFD 1
|
|
00DAFD 1 ; ----------------------------------------------------------------------------
|
|
00DAFD 1 ; Compare half of the selector against $9E.
|
|
00DAFD 1 ; ----------------------------------------------------------------------------
|
|
00DAFD 1
|
|
00DAFD 1 4A lsr ; $DAFD: 4A
|
|
00DAFE 1 C5 9E cmp $9E ; $DAFE: C5 9E
|
|
00DB00 1 D0 15 bne UpdateCurrentObjectSelectorState_Return
|
|
00DB02 1 ; $DB00: D0 15
|
|
00DB02 1
|
|
00DB02 1 ; ----------------------------------------------------------------------------
|
|
00DB02 1 ; If ObjectTransitionState is zero, branch directly into DisableCurrentObject after the
|
|
00DB02 1 ; selector-to-index conversion at $DAC3.
|
|
00DB02 1 ;
|
|
00DB02 1 ; The target $DAC8 stores the current A value into StateSelector.
|
|
00DB02 1 ; ----------------------------------------------------------------------------
|
|
00DB02 1
|
|
00DB02 1 A4 6E ldy ObjectTransitionState ; $DB02: A4 6E
|
|
00DB04 1 F0 C2 beq StoreStateSelector
|
|
00DB06 1 ; $DB04: F0 C2
|
|
00DB06 1
|
|
00DB06 1 ; ----------------------------------------------------------------------------
|
|
00DB06 1 ; Decrement the indexed object state and evaluate the current result.
|
|
00DB06 1 ; ----------------------------------------------------------------------------
|
|
00DB06 1
|
|
00DB06 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DB09 1 ; $DB06: 20 68 DA
|
|
00DB09 1
|
|
00DB09 1 DE 95 05 dec $0595,x ; $DB09: DE 95 05
|
|
00DB0C 1
|
|
00DB0C 1 20 5F DA jsr GetCurrentObjectSelector
|
|
00DB0F 1 ; $DB0C: 20 5F DA
|
|
00DB0F 1
|
|
00DB0F 1 10 B2 bpl DisableCurrentObject ; $DB0F: 10 B2
|
|
00DB11 1
|
|
00DB11 1 ; ----------------------------------------------------------------------------
|
|
00DB11 1 ; A negative selector result restores the indexed object-state value.
|
|
00DB11 1 ; ----------------------------------------------------------------------------
|
|
00DB11 1
|
|
00DB11 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DB14 1 ; $DB11: 20 68 DA
|
|
00DB14 1
|
|
00DB14 1 FE 95 05 inc $0595,x ; $DB14: FE 95 05
|
|
00DB17 1
|
|
00DB17 1 UpdateCurrentObjectSelectorState_Return: ; $DB17
|
|
00DB17 1 60 rts ; $DB17: 60
|
|
00DB18 1
|
|
00DB18 1
|
|
00DB18 1 ; ============================================================================
|
|
00DB18 1 ; $DB18-$DB2D
|
|
00DB18 1 ; Test the current input against a selector-specific mask.
|
|
00DB18 1 ;
|
|
00DB18 1 ; Return behavior:
|
|
00DB18 1 ;
|
|
00DB18 1 ; ActionSequenceCounter == 0:
|
|
00DB18 1 ; A = 0
|
|
00DB18 1 ; returns after ASL
|
|
00DB18 1 ;
|
|
00DB18 1 ; DerivedControl0 == 0:
|
|
00DB18 1 ; transfers directly to the next routine at $DB2E
|
|
00DB18 1 ;
|
|
00DB18 1 ; InputState1 & InputMaskTable[Y] == 0:
|
|
00DB18 1 ; A = 0
|
|
00DB18 1 ; returns after ASL
|
|
00DB18 1 ;
|
|
00DB18 1 ; InputState1 & InputMaskTable[Y] != 0:
|
|
00DB18 1 ; A = InputAux1 << 1
|
|
00DB18 1 ; returns with flags from ASL
|
|
00DB18 1 ;
|
|
00DB18 1 ; Callers commonly test the N or C flags produced by the final ASL.
|
|
00DB18 1 ; ============================================================================
|
|
00DB18 1
|
|
00DB18 1 ; ----------------------------------------------------------------------------
|
|
00DB18 1 ; Contract:
|
|
00DB18 1 ; Description: Implements Test Current Object Input.
|
|
00DB18 1 ; Entry: Registers: A; Memory: actionsequencecounter, derivedcontrol0, inputstate1, inputmasktable, inputaux1
|
|
00DB18 1 ; Returns/products: Registers/clobbers: A; Flags: condition flags may carry result state
|
|
00DB18 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DB18 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00DB18 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DB18 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DB18 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00DB18 1 ; ----------------------------------------------------------------------------
|
|
00DB18 1 TestCurrentObjectInput: ; $DB18
|
|
00DB18 1 A5 7E lda ActionSequenceCounter ; $DB18: A5 7E
|
|
00DB1A 1 F0 10 beq TestCurrentObjectInput_Shift
|
|
00DB1C 1 ; $DB1A: F0 10
|
|
00DB1C 1
|
|
00DB1C 1 A5 0F lda DerivedControl0 ; $DB1C: A5 0F
|
|
00DB1E 1 F0 0E beq CurrentObjectInputFallback
|
|
00DB20 1 ; $DB1E: F0 0E
|
|
00DB20 1 ; Branches to $DB2E, the next routine entry.
|
|
00DB20 1
|
|
00DB20 1 ; ----------------------------------------------------------------------------
|
|
00DB20 1 ; Obtain the current object/event selector in Y.
|
|
00DB20 1 ; ----------------------------------------------------------------------------
|
|
00DB20 1
|
|
00DB20 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DB20: 20 DC E3
|
|
00DB23 1
|
|
00DB23 1 ; ----------------------------------------------------------------------------
|
|
00DB23 1 ; Test InputState1 against the selector-specific mask at $DBB0,Y.
|
|
00DB23 1 ; ----------------------------------------------------------------------------
|
|
00DB23 1
|
|
00DB23 1 A5 13 lda InputState1 ; $DB23: A5 13
|
|
00DB25 1 39 B0 DB and InputMaskTable,y ; $DB25: 39 B0 DB
|
|
00DB28 1
|
|
00DB28 1 F0 02 beq TestCurrentObjectInput_Shift
|
|
00DB2A 1 ; $DB28: F0 02
|
|
00DB2A 1
|
|
00DB2A 1 ; ----------------------------------------------------------------------------
|
|
00DB2A 1 ; Matching input was detected. Return InputAux1 shifted left once.
|
|
00DB2A 1 ; ----------------------------------------------------------------------------
|
|
00DB2A 1
|
|
00DB2A 1 A5 17 lda InputAux1 ; $DB2A: A5 17
|
|
00DB2C 1
|
|
00DB2C 1 TestCurrentObjectInput_Shift: ; $DB2C
|
|
00DB2C 1 0A asl ; $DB2C: 0A
|
|
00DB2D 1 60 rts ; $DB2D: 60
|
|
00DB2E 1
|
|
00DB2E 1 ; ============================================================================
|
|
00DB2E 1 ; $DB2E-$DB83
|
|
00DB2E 1 ; Resolve the current object's input/collision state.
|
|
00DB2E 1 ;
|
|
00DB2E 1 ; This routine combines:
|
|
00DB2E 1 ; - current object identity,
|
|
00DB2E 1 ; - object-state entries,
|
|
00DB2E 1 ; - animation state,
|
|
00DB2E 1 ; - current selector,
|
|
00DB2E 1 ; - movement state,
|
|
00DB2E 1 ; - coordinate comparisons,
|
|
00DB2E 1 ; - and the region test at $DB84.
|
|
00DB2E 1 ;
|
|
00DB2E 1 ; Return conventions:
|
|
00DB2E 1 ;
|
|
00DB2E 1 ; Carry set:
|
|
00DB2E 1 ; successful or active condition
|
|
00DB2E 1 ;
|
|
00DB2E 1 ; Carry clear, A = $00:
|
|
00DB2E 1 ; failed coordinate/region condition
|
|
00DB2E 1 ;
|
|
00DB2E 1 ; Carry clear, A = $80:
|
|
00DB2E 1 ; alternate inactive/result condition
|
|
00DB2E 1 ;
|
|
00DB2E 1 ; Carry clear, A preserved:
|
|
00DB2E 1 ; neutral state via $DB82
|
|
00DB2E 1 ; ============================================================================
|
|
00DB2E 1
|
|
00DB2E 1 CurrentObjectInputFallback: ; $DB2E
|
|
00DB2E 1 A6 E1 ldx CurrentObjectIndex ; $DB2E: A6 E1
|
|
00DB30 1
|
|
00DB30 1 ; ----------------------------------------------------------------------------
|
|
00DB30 1 ; Special-case object offset $08.
|
|
00DB30 1 ; ----------------------------------------------------------------------------
|
|
00DB30 1
|
|
00DB30 1 E0 08 cpx #$08 ; $DB30: E0 08
|
|
00DB32 1 D0 12 bne ResolveCurrentObjectSelector
|
|
00DB34 1 ; $DB32: D0 12
|
|
00DB34 1
|
|
00DB34 1 AD 9A 05 lda $059A ; $DB34: AD 9A 05
|
|
00DB37 1 10 0D bpl ResolveCurrentObjectSelector
|
|
00DB39 1 ; $DB37: 10 0D
|
|
00DB39 1
|
|
00DB39 1 AD B7 03 lda $03B7 ; $DB39: AD B7 03
|
|
00DB3C 1 C9 0D cmp #$0D ; $DB3C: C9 0D
|
|
00DB3E 1 D0 06 bne ResolveCurrentObjectSelector
|
|
00DB40 1 ; $DB3E: D0 06
|
|
00DB40 1
|
|
00DB40 1 ; ----------------------------------------------------------------------------
|
|
00DB40 1 ; When object $08 is inactive and frame $03B7 equals $0D, use a random result.
|
|
00DB40 1 ;
|
|
00DB40 1 ; A zero random result returns through the alternate result at $DB7E.
|
|
00DB40 1 ; ----------------------------------------------------------------------------
|
|
00DB40 1
|
|
00DB40 1 20 F5 E5 jsr AdvanceRandomState ; $DB40: 20 F5 E5
|
|
00DB43 1 A8 tay ; $DB43: A8
|
|
00DB44 1 F0 38 beq ResolveCurrentObject_AlternateResult
|
|
00DB46 1 ; $DB44: F0 38
|
|
00DB46 1
|
|
00DB46 1 ; ----------------------------------------------------------------------------
|
|
00DB46 1 ; Derive the current object/event selector.
|
|
00DB46 1 ; ----------------------------------------------------------------------------
|
|
00DB46 1
|
|
00DB46 1 ResolveCurrentObjectSelector: ; $DB46
|
|
00DB46 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DB46: 20 DC E3
|
|
00DB49 1
|
|
00DB49 1 98 tya ; $DB49: 98
|
|
00DB4A 1 4A lsr ; $DB4A: 4A
|
|
00DB4B 1
|
|
00DB4B 1 ; ----------------------------------------------------------------------------
|
|
00DB4B 1 ; If half the selector equals $BB, use the secondary region-test path.
|
|
00DB4B 1 ; ----------------------------------------------------------------------------
|
|
00DB4B 1
|
|
00DB4B 1 C5 BB cmp $BB ; $DB4B: C5 BB
|
|
00DB4D 1 F0 2A beq ResolveCurrentObject_SecondaryRegion
|
|
00DB4F 1 ; $DB4D: F0 2A
|
|
00DB4F 1
|
|
00DB4F 1 ; ----------------------------------------------------------------------------
|
|
00DB4F 1 ; BaseMotionPhase equal to zero returns through the neutral carry-clear path.
|
|
00DB4F 1 ; ----------------------------------------------------------------------------
|
|
00DB4F 1
|
|
00DB4F 1 A5 5D lda BaseMotionPhase ; $DB4F: A5 5D
|
|
00DB51 1 F0 2F beq ResolveCurrentObject_Neutral
|
|
00DB53 1 ; $DB51: F0 2F
|
|
00DB53 1
|
|
00DB53 1 ; ----------------------------------------------------------------------------
|
|
00DB53 1 ; BaseMotionEventCount equal to zero returns the alternate $80 result.
|
|
00DB53 1 ; ----------------------------------------------------------------------------
|
|
00DB53 1
|
|
00DB53 1 A5 5E lda BaseMotionEventCount ; $DB53: A5 5E
|
|
00DB55 1 F0 27 beq ResolveCurrentObject_AlternateResult
|
|
00DB57 1 ; $DB55: F0 27
|
|
00DB57 1
|
|
00DB57 1 ; ----------------------------------------------------------------------------
|
|
00DB57 1 ; A negative current-object selector returns through the neutral path.
|
|
00DB57 1 ; ----------------------------------------------------------------------------
|
|
00DB57 1
|
|
00DB57 1 20 5F DA jsr GetCurrentObjectSelector
|
|
00DB5A 1 ; $DB57: 20 5F DA
|
|
00DB5A 1
|
|
00DB5A 1 30 26 bmi ResolveCurrentObject_Neutral
|
|
00DB5C 1 ; $DB5A: 30 26
|
|
00DB5C 1
|
|
00DB5C 1 ; ----------------------------------------------------------------------------
|
|
00DB5C 1 ; Run the region test at $DB84.
|
|
00DB5C 1 ;
|
|
00DB5C 1 ; Carry clear selects the zero-result path at $DB75.
|
|
00DB5C 1 ; ----------------------------------------------------------------------------
|
|
00DB5C 1
|
|
00DB5C 1 20 84 DB jsr TestCurrentObjectRegion ; $DB5C: 20 84 DB
|
|
00DB5F 1 90 14 bcc ResolveCurrentObject_ZeroResult
|
|
00DB61 1 ; $DB5F: 90 14
|
|
00DB61 1
|
|
00DB61 1 ; ----------------------------------------------------------------------------
|
|
00DB61 1 ; Compare the current object's high X coordinate against a selector-indexed
|
|
00DB61 1 ; threshold table at $E021,Y.
|
|
00DB61 1 ; ----------------------------------------------------------------------------
|
|
00DB61 1
|
|
00DB61 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DB61: 20 DC E3
|
|
00DB64 1
|
|
00DB64 1 98 tya ; $DB64: 98
|
|
00DB65 1 4A lsr ; $DB65: 4A
|
|
00DB66 1 A8 tay ; $DB66: A8
|
|
00DB67 1
|
|
00DB67 1 BD 0A 05 lda $050A,x ; $DB67: BD 0A 05
|
|
00DB6A 1 D9 21 E0 cmp $E021,y ; $DB6A: D9 21 E0
|
|
00DB6D 1
|
|
00DB6D 1 ; ----------------------------------------------------------------------------
|
|
00DB6D 1 ; Convert comparison carry, selector range, and ADC carry into one final test.
|
|
00DB6D 1 ; ----------------------------------------------------------------------------
|
|
00DB6D 1
|
|
00DB6D 1 2A rol ; $DB6D: 2A
|
|
00DB6E 1
|
|
00DB6E 1 C0 03 cpy #$03 ; $DB6E: C0 03
|
|
00DB70 1 69 00 adc #$00 ; $DB70: 69 00
|
|
00DB72 1
|
|
00DB72 1 4A lsr ; $DB72: 4A
|
|
00DB73 1 90 09 bcc ResolveCurrentObject_AlternateResult
|
|
00DB75 1 ; $DB73: 90 09
|
|
00DB75 1
|
|
00DB75 1 ; ----------------------------------------------------------------------------
|
|
00DB75 1 ; Return carry clear with A = $00.
|
|
00DB75 1 ; ----------------------------------------------------------------------------
|
|
00DB75 1
|
|
00DB75 1 ResolveCurrentObject_ZeroResult: ; $DB75
|
|
00DB75 1 38 sec ; $DB75: 38
|
|
00DB76 1 A9 00 lda #$00 ; $DB76: A9 00
|
|
00DB78 1 60 rts ; $DB78: 60
|
|
00DB79 1 ; LDA preserves carry set, despite the path
|
|
00DB79 1 ; name. Callers may rely on both A and carry.
|
|
00DB79 1
|
|
00DB79 1 ; ----------------------------------------------------------------------------
|
|
00DB79 1 ; Secondary region-test path.
|
|
00DB79 1 ;
|
|
00DB79 1 ; Carry clear returns A = $00 with carry set through $DB75.
|
|
00DB79 1 ; Carry set falls through to the alternate $80 result.
|
|
00DB79 1 ; ----------------------------------------------------------------------------
|
|
00DB79 1
|
|
00DB79 1 ResolveCurrentObject_SecondaryRegion: ; $DB79
|
|
00DB79 1 20 84 DB jsr TestCurrentObjectRegion ; $DB79: 20 84 DB
|
|
00DB7C 1 90 F7 bcc ResolveCurrentObject_ZeroResult
|
|
00DB7E 1 ; $DB7C: 90 F7
|
|
00DB7E 1
|
|
00DB7E 1 ; ----------------------------------------------------------------------------
|
|
00DB7E 1 ; Return carry clear with A = $80.
|
|
00DB7E 1 ; ----------------------------------------------------------------------------
|
|
00DB7E 1
|
|
00DB7E 1 ResolveCurrentObject_AlternateResult: ; $DB7E
|
|
00DB7E 1 18 clc ; $DB7E: 18
|
|
00DB7F 1 A9 80 lda #$80 ; $DB7F: A9 80
|
|
00DB81 1 60 rts ; $DB81: 60
|
|
00DB82 1
|
|
00DB82 1 ; ----------------------------------------------------------------------------
|
|
00DB82 1 ; Neutral return with carry clear. A is preserved from the preceding test.
|
|
00DB82 1 ; ----------------------------------------------------------------------------
|
|
00DB82 1
|
|
00DB82 1 ResolveCurrentObject_Neutral: ; $DB82
|
|
00DB82 1 18 clc ; $DB82: 18
|
|
00DB83 1 60 rts ; $DB83: 60
|
|
00DB84 1
|
|
00DB84 1 ; ============================================================================
|
|
00DB84 1 ; $DB84-$DBAF
|
|
00DB84 1 ; Test whether another active object satisfies a selector and state condition
|
|
00DB84 1 ; relative to CurrentObjectIndex.
|
|
00DB84 1 ;
|
|
00DB84 1 ; Return:
|
|
00DB84 1 ; Carry is the primary Boolean result.
|
|
00DB84 1 ;
|
|
00DB84 1 ; C = 1:
|
|
00DB84 1 ; matching/active condition
|
|
00DB84 1 ;
|
|
00DB84 1 ; C = 0:
|
|
00DB84 1 ; no matching condition
|
|
00DB84 1 ;
|
|
00DB84 1 ; The final LSR converts bit zero of the calculated value into carry.
|
|
00DB84 1 ; ============================================================================
|
|
00DB84 1
|
|
00DB84 1 ; ----------------------------------------------------------------------------
|
|
00DB84 1 ; Contract:
|
|
00DB84 1 ; Description: Implements Test Current Object Region.
|
|
00DB84 1 ; Entry: Registers: A, X, Y; Memory: $0598, currentobjectindex, $056d
|
|
00DB84 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00DB84 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DB84 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00DB84 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DB84 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DB84 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00DB84 1 ; ----------------------------------------------------------------------------
|
|
00DB84 1 TestCurrentObjectRegion: ; $DB84
|
|
00DB84 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DB84: 20 DC E3
|
|
00DB87 1 ; Returns a selector in Y.
|
|
00DB87 1
|
|
00DB87 1 ; ----------------------------------------------------------------------------
|
|
00DB87 1 ; Convert the selector into a comparison value:
|
|
00DB87 1 ;
|
|
00DB87 1 ; A = ((Y >> 1) << 1) + 3
|
|
00DB87 1 ;
|
|
00DB87 1 ; The LSR/ASL pair clears bit zero before adding three.
|
|
00DB87 1 ; Carry from ASL is intentionally retained by ADC.
|
|
00DB87 1 ; ----------------------------------------------------------------------------
|
|
00DB87 1
|
|
00DB87 1 98 tya ; $DB87: 98
|
|
00DB88 1 4A lsr ; $DB88: 4A
|
|
00DB89 1 0A asl ; $DB89: 0A
|
|
00DB8A 1 69 03 adc #$03 ; $DB8A: 69 03
|
|
00DB8C 1
|
|
00DB8C 1 ; ----------------------------------------------------------------------------
|
|
00DB8C 1 ; Search the four state entries $0598-$059B.
|
|
00DB8C 1 ;
|
|
00DB8C 1 ; X starts at four, is decremented before each comparison, and stops when A is
|
|
00DB8C 1 ; greater than or equal to the indexed state value.
|
|
00DB8C 1 ; ----------------------------------------------------------------------------
|
|
00DB8C 1
|
|
00DB8C 1 A2 04 ldx #$04 ; $DB8C: A2 04
|
|
00DB8E 1
|
|
00DB8E 1 TestCurrentObjectRegion_Search: ; $DB8E
|
|
00DB8E 1 CA dex ; $DB8E: CA
|
|
00DB8F 1
|
|
00DB8F 1 DD 98 05 cmp $0598,x ; $DB8F: DD 98 05
|
|
00DB92 1 90 FA bcc TestCurrentObjectRegion_Search
|
|
00DB94 1 ; $DB92: 90 FA
|
|
00DB94 1
|
|
00DB94 1 ; ----------------------------------------------------------------------------
|
|
00DB94 1 ; Load the selected state entry into Y.
|
|
00DB94 1 ;
|
|
00DB94 1 ; Values of eight or greater return immediately. Carry remains set from
|
|
00DB94 1 ; CPY #$08 in that case.
|
|
00DB94 1 ; ----------------------------------------------------------------------------
|
|
00DB94 1
|
|
00DB94 1 BC 98 05 ldy $0598,x ; $DB94: BC 98 05
|
|
00DB97 1
|
|
00DB97 1 C0 08 cpy #$08 ; $DB97: C0 08
|
|
00DB99 1 B0 14 bcs TestCurrentObjectRegion_Return
|
|
00DB9B 1 ; $DB99: B0 14
|
|
00DB9B 1
|
|
00DB9B 1 ; ----------------------------------------------------------------------------
|
|
00DB9B 1 ; Convert the state-table index into an object offset:
|
|
00DB9B 1 ;
|
|
00DB9B 1 ; A = (X * 2) + 6
|
|
00DB9B 1 ;
|
|
00DB9B 1 ; If this offset is the current object, return immediately. Carry is set by
|
|
00DB9B 1 ; CMP on equality.
|
|
00DB9B 1 ; ----------------------------------------------------------------------------
|
|
00DB9B 1
|
|
00DB9B 1 8A txa ; $DB9B: 8A
|
|
00DB9C 1 0A asl ; $DB9C: 0A
|
|
00DB9D 1 69 06 adc #$06 ; $DB9D: 69 06
|
|
00DB9F 1
|
|
00DB9F 1 C5 E1 cmp CurrentObjectIndex ; $DB9F: C5 E1
|
|
00DBA1 1 F0 0C beq TestCurrentObjectRegion_Return
|
|
00DBA3 1 ; $DBA1: F0 0C
|
|
00DBA3 1
|
|
00DBA3 1 ; ----------------------------------------------------------------------------
|
|
00DBA3 1 ; Use the calculated object offset to inspect its state at $056D,X.
|
|
00DBA3 1 ; ----------------------------------------------------------------------------
|
|
00DBA3 1
|
|
00DBA3 1 AA tax ; $DBA3: AA
|
|
00DBA4 1
|
|
00DBA4 1 BD 6D 05 lda $056D,x ; $DBA4: BD 6D 05
|
|
00DBA7 1 F0 05 beq TestCurrentObjectRegion_Shift
|
|
00DBA9 1 ; $DBA7: F0 05
|
|
00DBA9 1
|
|
00DBA9 1 ; ----------------------------------------------------------------------------
|
|
00DBA9 1 ; For an active object, combine the selector comparison with carry.
|
|
00DBA9 1 ;
|
|
00DBA9 1 ; CPY #$06 establishes carry, ROL moves it into A, and ADC #$00 incorporates
|
|
00DBA9 1 ; the resulting carry state.
|
|
00DBA9 1 ; ----------------------------------------------------------------------------
|
|
00DBA9 1
|
|
00DBA9 1 C0 06 cpy #$06 ; $DBA9: C0 06
|
|
00DBAB 1 2A rol ; $DBAB: 2A
|
|
00DBAC 1 69 00 adc #$00 ; $DBAC: 69 00
|
|
00DBAE 1
|
|
00DBAE 1 ; ----------------------------------------------------------------------------
|
|
00DBAE 1 ; Return bit zero of A in carry.
|
|
00DBAE 1 ; ----------------------------------------------------------------------------
|
|
00DBAE 1
|
|
00DBAE 1 TestCurrentObjectRegion_Shift: ; $DBAE
|
|
00DBAE 1 4A lsr ; $DBAE: 4A
|
|
00DBAF 1
|
|
00DBAF 1 TestCurrentObjectRegion_Return: ; $DBAF
|
|
00DBAF 1 60 rts ; $DBAF: 60
|
|
00DBB0 1
|
|
00DBB0 1 ; ============================================================================
|
|
00DBB0 1 ; $DBB0-$DBB7
|
|
00DBB0 1 ; Selector-specific input-mask table.
|
|
00DBB0 1 ;
|
|
00DBB0 1 ; Used by TestCurrentObjectInput:
|
|
00DBB0 1 ;
|
|
00DBB0 1 ; jsr GetCurrentObjectSelectorAndState
|
|
00DBB0 1 ; lda InputState1
|
|
00DBB0 1 ; and InputMaskTable,y
|
|
00DBB0 1 ;
|
|
00DBB0 1 ; Y selects one of eight masks. Entries occur in identical pairs, suggesting
|
|
00DBB0 1 ; that adjacent selector values share the same accepted input bits.
|
|
00DBB0 1 ; ============================================================================
|
|
00DBB0 1
|
|
00DBB0 1 InputMaskTable: ; $DBB0
|
|
00DBB0 1 00 00 .byte $00,$00 ; Selectors $00-$01: no accepted input
|
|
00DBB2 1 05 05 .byte $05,$05 ; Selectors $02-$03: bits $01 and $04
|
|
00DBB4 1 0C 0C .byte $0C,$0C ; Selectors $04-$05: bits $04 and $08
|
|
00DBB6 1 06 06 .byte $06,$06 ; Selectors $06-$07: bits $02 and $04
|
|
00DBB8 1
|
|
00DBB8 1 ; ============================================================================
|
|
00DBB8 1 ; $DBB8-$DBF5
|
|
00DBB8 1 ; Update the current object's animation frame and return a six-tick delay.
|
|
00DBB8 1 ;
|
|
00DBB8 1 ; The routine derives one of eight animation ranges from the object's state at
|
|
00DBB8 1 ; $056D/$056E and an additional condition returned by $E6B7. When permitted,
|
|
00DBB8 1 ; it advances $039A,X and wraps or clamps the frame through two lookup tables.
|
|
00DBB8 1 ;
|
|
00DBB8 1 ; Return:
|
|
00DBB8 1 ; A = $06
|
|
00DBB8 1 ;
|
|
00DBB8 1 ; Carry from $E6B7 can skip the animation update entirely.
|
|
00DBB8 1 ; ============================================================================
|
|
00DBB8 1
|
|
00DBB8 1 ; ----------------------------------------------------------------------------
|
|
00DBB8 1 ; Contract:
|
|
00DBB8 1 ; Description: Implements Select Secondary Object Delay.
|
|
00DBB8 1 ; Entry: Registers: A, X; Memory: pendingaudioflags, currentobjectindex, $056e, $056d, $039a
|
|
00DBB8 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00DBB8 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DBB8 1 ; Memory effects: pendingaudioflags, $039a
|
|
00DBB8 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DBB8 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DBB8 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 7.
|
|
00DBB8 1 ; ----------------------------------------------------------------------------
|
|
00DBB8 1 SelectSecondaryObjectDelay: ; $DBB8
|
|
00DBB8 1 A5 FE lda PendingAudioFlags ; $DBB8: A5 FE
|
|
00DBBA 1 09 04 ora #$04 ; $DBBA: 09 04
|
|
00DBBC 1 85 FE sta PendingAudioFlags ; $DBBC: 85 FE
|
|
00DBBE 1
|
|
00DBBE 1 ; ----------------------------------------------------------------------------
|
|
00DBBE 1 ; Update or test the current object.
|
|
00DBBE 1 ;
|
|
00DBBE 1 ; Carry set skips directly to the fixed delay return.
|
|
00DBBE 1 ; ----------------------------------------------------------------------------
|
|
00DBBE 1
|
|
00DBBE 1 A6 E1 ldx CurrentObjectIndex ; $DBBE: A6 E1
|
|
00DBC0 1 20 B7 E6 jsr ClearMovementTransforms ; $DBC0: 20 B7 E6
|
|
00DBC3 1 B0 2E bcs SecondaryObjectDelay_Return
|
|
00DBC5 1 ; $DBC3: B0 2E
|
|
00DBC5 1
|
|
00DBC5 1 ; ----------------------------------------------------------------------------
|
|
00DBC5 1 ; Derive a compact animation-range selector from $056D,X and $056E,X.
|
|
00DBC5 1 ;
|
|
00DBC5 1 ; Bit flow:
|
|
00DBC5 1 ;
|
|
00DBC5 1 ; 1. ASL $056E,X places its high bit in carry.
|
|
00DBC5 1 ; 2. ROL A shifts that carry into $056D,X.
|
|
00DBC5 1 ; 3. A second ROL expands the selector before it is saved.
|
|
00DBC5 1 ; ----------------------------------------------------------------------------
|
|
00DBC5 1
|
|
00DBC5 1 A6 E1 ldx CurrentObjectIndex ; $DBC5: A6 E1
|
|
00DBC7 1
|
|
00DBC7 1 BD 6E 05 lda $056E,x ; $DBC7: BD 6E 05
|
|
00DBCA 1 0A asl ; $DBCA: 0A
|
|
00DBCB 1
|
|
00DBCB 1 BD 6D 05 lda $056D,x ; $DBCB: BD 6D 05
|
|
00DBCE 1 2A rol ; $DBCE: 2A
|
|
00DBCF 1 2A rol ; $DBCF: 2A
|
|
00DBD0 1
|
|
00DBD0 1 48 pha ; $DBD0: 48
|
|
00DBD1 1 ; Preserve the preliminary selector.
|
|
00DBD1 1
|
|
00DBD1 1 ; ----------------------------------------------------------------------------
|
|
00DBD1 1 ; Run the object helper again.
|
|
00DBD1 1 ;
|
|
00DBD1 1 ; The helper may update X and returns a condition in carry.
|
|
00DBD1 1 ; ----------------------------------------------------------------------------
|
|
00DBD1 1
|
|
00DBD1 1 20 B7 E6 jsr ClearMovementTransforms ; $DBD1: 20 B7 E6
|
|
00DBD4 1
|
|
00DBD4 1 68 pla ; $DBD4: 68
|
|
00DBD5 1 B0 1C bcs SecondaryObjectDelay_Return
|
|
00DBD7 1 ; $DBD5: B0 1C
|
|
00DBD7 1
|
|
00DBD7 1 ; ----------------------------------------------------------------------------
|
|
00DBD7 1 ; Incorporate whether X is at least $15 into the selector.
|
|
00DBD7 1 ;
|
|
00DBD7 1 ; CPX #$15 sets carry, and ROL shifts that condition into A.
|
|
00DBD7 1 ; ----------------------------------------------------------------------------
|
|
00DBD7 1
|
|
00DBD7 1 E0 15 cpx #$15 ; $DBD7: E0 15
|
|
00DBD9 1 2A rol ; $DBD9: 2A
|
|
00DBDA 1
|
|
00DBDA 1 29 07 and #$07 ; $DBDA: 29 07
|
|
00DBDC 1 A8 tay ; $DBDC: A8
|
|
00DBDD 1 ; Y selects one of eight animation ranges.
|
|
00DBDD 1
|
|
00DBDD 1 ; ----------------------------------------------------------------------------
|
|
00DBDD 1 ; Load the current frame and increment it.
|
|
00DBDD 1 ;
|
|
00DBDD 1 ; The original frame remains in A for the threshold comparisons.
|
|
00DBDD 1 ; ----------------------------------------------------------------------------
|
|
00DBDD 1
|
|
00DBDD 1 BD 9A 03 lda $039A,x ; $DBDD: BD 9A 03
|
|
00DBE0 1 FE 9A 03 inc $039A,x ; $DBE0: FE 9A 03
|
|
00DBE3 1
|
|
00DBE3 1 ; ----------------------------------------------------------------------------
|
|
00DBE3 1 ; Compare the original frame against the upper and lower bounds.
|
|
00DBE3 1 ;
|
|
00DBE3 1 ; The table bases intentionally overlap:
|
|
00DBE3 1 ;
|
|
00DBE3 1 ; SecondaryAnimationBaseTable,Y
|
|
00DBE3 1 ; SecondaryAnimationLimitTable,Y
|
|
00DBE3 1 ;
|
|
00DBE3 1 ; If the frame lies outside the permitted range, reset it to the base frame.
|
|
00DBE3 1 ; ----------------------------------------------------------------------------
|
|
00DBE3 1
|
|
00DBE3 1 D9 FE DB cmp SecondaryAnimationLimitTable,y
|
|
00DBE6 1 ; $DBE3: D9 FE DB
|
|
00DBE6 1 B0 05 bcs SecondaryObjectDelay_ResetFrame
|
|
00DBE8 1 ; $DBE6: B0 05
|
|
00DBE8 1
|
|
00DBE8 1 D9 F6 DB cmp SecondaryAnimationBaseTable,y
|
|
00DBEB 1 ; $DBE8: D9 F6 DB
|
|
00DBEB 1 B0 06 bcs SecondaryObjectDelay_Return
|
|
00DBED 1 ; $DBEB: B0 06
|
|
00DBED 1
|
|
00DBED 1 SecondaryObjectDelay_ResetFrame: ; $DBED
|
|
00DBED 1 B9 F6 DB lda SecondaryAnimationBaseTable,y
|
|
00DBF0 1 ; $DBED: B9 F6 DB
|
|
00DBF0 1 9D 9A 03 sta $039A,x ; $DBF0: 9D 9A 03
|
|
00DBF3 1
|
|
00DBF3 1 ; ----------------------------------------------------------------------------
|
|
00DBF3 1 ; Return a fixed six-tick delay.
|
|
00DBF3 1 ; ----------------------------------------------------------------------------
|
|
00DBF3 1
|
|
00DBF3 1 SecondaryObjectDelay_Return: ; $DBF3
|
|
00DBF3 1 A9 06 lda #$06 ; $DBF3: A9 06
|
|
00DBF5 1 60 rts ; $DBF5: 60
|
|
00DBF6 1
|
|
00DBF6 1 ; ============================================================================
|
|
00DBF6 1 ; $DBF6-$DC05
|
|
00DBF6 1 ; Parallel secondary-object animation tables.
|
|
00DBF6 1 ;
|
|
00DBF6 1 ; SelectSecondaryObjectDelay uses the same Y index with both tables:
|
|
00DBF6 1 ;
|
|
00DBF6 1 ; SecondaryAnimationBaseTable,Y
|
|
00DBF6 1 ; Base or reset animation frame.
|
|
00DBF6 1 ;
|
|
00DBF6 1 ; SecondaryAnimationLimitTable,Y
|
|
00DBF6 1 ; Upper animation-frame limit.
|
|
00DBF6 1 ;
|
|
00DBF6 1 ; The animation helper increments the current frame, then resets it to the
|
|
00DBF6 1 ; corresponding base frame whenever it falls below the base or reaches the
|
|
00DBF6 1 ; upper limit.
|
|
00DBF6 1 ; ============================================================================
|
|
00DBF6 1
|
|
00DBF6 1 ; ----------------------------------------------------------------------------
|
|
00DBF6 1 ; Base/reset animation frames.
|
|
00DBF6 1 ; ----------------------------------------------------------------------------
|
|
00DBF6 1
|
|
00DBF6 1 SecondaryAnimationBaseTable: ; $DBF6
|
|
00DBF6 1 4D 1A 50 1E .byte $4D,$1A,$50,$1E
|
|
00DBFA 1 56 27 53 23 .byte $56,$27,$53,$23
|
|
00DBFE 1
|
|
00DBFE 1 ; ----------------------------------------------------------------------------
|
|
00DBFE 1 ; Upper animation-frame limits.
|
|
00DBFE 1 ; ----------------------------------------------------------------------------
|
|
00DBFE 1
|
|
00DBFE 1 SecondaryAnimationLimitTable: ; $DBFE
|
|
00DBFE 1 4F 1C 52 20 .byte $4F,$1C,$52,$20
|
|
00DC02 1 58 29 55 25 .byte $58,$29,$55,$25
|
|
00DC06 1
|
|
00DC06 1
|
|
00DC06 1 ; ============================================================================
|
|
00DC06 1 ; $DC06-$DC28
|
|
00DC06 1 ; Test the current object's adjusted X and Y coordinate regions.
|
|
00DC06 1 ;
|
|
00DC06 1 ; Entry:
|
|
00DC06 1 ; X = ignored. The routine reloads X from CurrentObjectIndex.
|
|
00DC06 1 ; Y = coordinate-adjustment table index.
|
|
00DC06 1 ;
|
|
00DC06 1 ; Return:
|
|
00DC06 1 ; A contains the final comparison value.
|
|
00DC06 1 ;
|
|
00DC06 1 ; Carry set:
|
|
00DC06 1 ; The adjusted X coordinate is at least two, or the adjusted Y
|
|
00DC06 1 ; coordinate is at least two.
|
|
00DC06 1 ;
|
|
00DC06 1 ; Carry clear:
|
|
00DC06 1 ; Both adjusted coordinate values are below two.
|
|
00DC06 1 ;
|
|
00DC06 1 ; The low coordinate bytes are shifted only to place bit 7 into carry. That
|
|
00DC06 1 ; carry is then added to the corresponding high coordinate byte.
|
|
00DC06 1 ; ============================================================================
|
|
00DC06 1
|
|
00DC06 1 TestCurrentObjectCoordinateRegion: ; $DC06
|
|
00DC06 1 A6 E1 ldx CurrentObjectIndex ; $DC06: A6 E1
|
|
00DC08 1
|
|
00DC08 1 ; ----------------------------------------------------------------------------
|
|
00DC08 1 ; Test the adjusted horizontal coordinate.
|
|
00DC08 1 ;
|
|
00DC08 1 ; The horizontal high byte is adjusted using the table based at $DC2A,Y:
|
|
00DC08 1 ;
|
|
00DC08 1 ; adjustedX = $050A,X + Table_DC2A,Y + carry($0509,X << 1) + 1
|
|
00DC08 1 ; ----------------------------------------------------------------------------
|
|
00DC08 1
|
|
00DC08 1 BD 09 05 lda $0509,x ; $DC08: BD 09 05
|
|
00DC0B 1 0A asl ; $DC0B: 0A
|
|
00DC0C 1 ; Carry = bit 7 of the horizontal low byte.
|
|
00DC0C 1
|
|
00DC0C 1 BD 0A 05 lda $050A,x ; $DC0C: BD 0A 05
|
|
00DC0F 1 79 2A DC adc HorizontalAdjustmentTable,y
|
|
00DC12 1 ; $DC0F: 79 2A DC
|
|
00DC12 1
|
|
00DC12 1 18 clc ; $DC12: 18
|
|
00DC13 1 69 01 adc #$01 ; $DC13: 69 01
|
|
00DC15 1
|
|
00DC15 1 C9 02 cmp #$02 ; $DC15: C9 02
|
|
00DC17 1 B0 0F bcs TestCurrentObjectCoordinateRegion_Return
|
|
00DC19 1 ; $DC17: B0 0F
|
|
00DC19 1
|
|
00DC19 1 ; ----------------------------------------------------------------------------
|
|
00DC19 1 ; The adjusted horizontal coordinate is below two.
|
|
00DC19 1 ; Test the adjusted vertical coordinate.
|
|
00DC19 1 ;
|
|
00DC19 1 ; The vertical high byte is adjusted using the table based at $DC29,Y:
|
|
00DC19 1 ;
|
|
00DC19 1 ; adjustedY = $053B,X + Table_DC29,Y + carry($053A,X << 1) + 1
|
|
00DC19 1 ; ----------------------------------------------------------------------------
|
|
00DC19 1
|
|
00DC19 1 BD 3A 05 lda $053A,x ; $DC19: BD 3A 05
|
|
00DC1C 1 0A asl ; $DC1C: 0A
|
|
00DC1D 1 ; Carry = bit 7 of the vertical low byte.
|
|
00DC1D 1
|
|
00DC1D 1 BD 3B 05 lda $053B,x ; $DC1D: BD 3B 05
|
|
00DC20 1 79 29 DC adc VerticalAdjustmentTable,y
|
|
00DC23 1 ; $DC20: 79 29 DC
|
|
00DC23 1
|
|
00DC23 1 18 clc ; $DC23: 18
|
|
00DC24 1 69 01 adc #$01 ; $DC24: 69 01
|
|
00DC26 1
|
|
00DC26 1 C9 02 cmp #$02 ; $DC26: C9 02
|
|
00DC28 1
|
|
00DC28 1 TestCurrentObjectCoordinateRegion_Return: ; $DC28
|
|
00DC28 1 60 rts ; $DC28: 60
|
|
00DC29 1
|
|
00DC29 1 ; ============================================================================
|
|
00DC29 1 ; $DC29-$DC30
|
|
00DC29 1 ; Overlapping signed coordinate-adjustment tables.
|
|
00DC29 1 ;
|
|
00DC29 1 ; The routine accesses:
|
|
00DC29 1 ;
|
|
00DC29 1 ; VerticalAdjustmentTable,Y at $DC29
|
|
00DC29 1 ; HorizontalAdjustmentTable,Y at $DC2A
|
|
00DC29 1 ;
|
|
00DC29 1 ; The table index in Y is supplied by the caller.
|
|
00DC29 1 ; ============================================================================
|
|
00DC29 1
|
|
00DC29 1 VerticalAdjustmentTable: ; $DC29
|
|
00DC29 1 08 .byte $08
|
|
00DC2A 1
|
|
00DC2A 1 HorizontalAdjustmentTable: ; $DC2A
|
|
00DC2A 1 00 F8 00 08 .byte $00,$F8,$00,$08
|
|
00DC2E 1 00 F8 00 .byte $00,$F8,$00
|
|
00DC31 1
|
|
00DC31 1 ; ============================================================================
|
|
00DC31 1 ; $DC31-$DC87
|
|
00DC31 1 ; Initialize object-processing parameters, process a list of event slots,
|
|
00DC31 1 ; dispatch one command for each listed object, and leave through the common
|
|
00DC31 1 ; engine exit.
|
|
00DC31 1 ; ============================================================================
|
|
00DC31 1
|
|
00DC31 1 InitializeObjectEventSequence: ; $DC31
|
|
00DC31 1 A9 20 lda #$20 ; $DC31: A9 20
|
|
00DC33 1 20 41 EB jsr StoreObjectEventBankValue ; $DC33: 20 41 EB
|
|
00DC36 1
|
|
00DC36 1 ; ----------------------------------------------------------------------------
|
|
00DC36 1 ; Clear working object indices.
|
|
00DC36 1 ; ----------------------------------------------------------------------------
|
|
00DC36 1
|
|
00DC36 1 A9 00 lda #$00 ; $DC36: A9 00
|
|
00DC38 1 85 A4 sta $A4 ; $DC38: 85 A4
|
|
00DC3A 1 85 A9 sta $A9 ; $DC3A: 85 A9
|
|
00DC3C 1
|
|
00DC3C 1 ; ----------------------------------------------------------------------------
|
|
00DC3C 1 ; Initialize object-selection bounds.
|
|
00DC3C 1 ; ----------------------------------------------------------------------------
|
|
00DC3C 1
|
|
00DC3C 1 A9 04 lda #$04 ; $DC3C: A9 04
|
|
00DC3E 1 85 A8 sta $A8 ; $DC3E: 85 A8
|
|
00DC40 1
|
|
00DC40 1 A9 16 lda #$16 ; $DC40: A9 16
|
|
00DC42 1 85 A7 sta $A7 ; $DC42: 85 A7
|
|
00DC44 1
|
|
00DC44 1 ; ----------------------------------------------------------------------------
|
|
00DC44 1 ; Select initial values for $A6 and $A5.
|
|
00DC44 1 ;
|
|
00DC44 1 ; Defaults:
|
|
00DC44 1 ; Y = $14
|
|
00DC44 1 ; X = $10
|
|
00DC44 1 ;
|
|
00DC44 1 ; If RandomVerticalMotion is negative:
|
|
00DC44 1 ; Y = $12
|
|
00DC44 1 ;
|
|
00DC44 1 ; Otherwise, when RandomVerticalMotion is at least $1E and ObjectSelectionLowerBound is zero:
|
|
00DC44 1 ; X = $0E
|
|
00DC44 1 ; ----------------------------------------------------------------------------
|
|
00DC44 1
|
|
00DC44 1 A0 14 ldy #$14 ; $DC44: A0 14
|
|
00DC46 1 A2 10 ldx #$10 ; $DC46: A2 10
|
|
00DC48 1
|
|
00DC48 1 A5 90 lda RandomVerticalMotion ; $DC48: A5 90
|
|
00DC4A 1 10 04 bpl InitializeObjectEventSequence_CheckUpper
|
|
00DC4C 1 ; $DC4A: 10 04
|
|
00DC4C 1
|
|
00DC4C 1 A0 12 ldy #$12 ; $DC4C: A0 12
|
|
00DC4E 1 D0 0A bne InitializeObjectEventSequence_SaveBounds
|
|
00DC50 1 ; $DC4E: D0 0A
|
|
00DC50 1 ; Always taken because Y is nonzero.
|
|
00DC50 1
|
|
00DC50 1 InitializeObjectEventSequence_CheckUpper: ; $DC50
|
|
00DC50 1 C9 1E cmp #$1E ; $DC50: C9 1E
|
|
00DC52 1 30 06 bmi InitializeObjectEventSequence_SaveBounds
|
|
00DC54 1 ; $DC52: 30 06
|
|
00DC54 1
|
|
00DC54 1 A5 A5 lda ObjectSelectionLowerBound ; $DC54: A5 A5
|
|
00DC56 1 D0 02 bne InitializeObjectEventSequence_SaveBounds
|
|
00DC58 1 ; $DC56: D0 02
|
|
00DC58 1
|
|
00DC58 1 A2 0E ldx #$0E ; $DC58: A2 0E
|
|
00DC5A 1
|
|
00DC5A 1 InitializeObjectEventSequence_SaveBounds: ; $DC5A
|
|
00DC5A 1 84 A6 sty $A6 ; $DC5A: 84 A6
|
|
00DC5C 1 86 A5 stx ObjectSelectionLowerBound ; $DC5C: 86 A5
|
|
00DC5E 1
|
|
00DC5E 1 ; ----------------------------------------------------------------------------
|
|
00DC5E 1 ; Process event slots selected by the nine-byte table at $DC88.
|
|
00DC5E 1 ;
|
|
00DC5E 1 ; X begins at eight and counts down through zero. The table value is loaded
|
|
00DC5E 1 ; into Y and passed to $EB66.
|
|
00DC5E 1 ; ----------------------------------------------------------------------------
|
|
00DC5E 1
|
|
00DC5E 1 A2 08 ldx #$08 ; $DC5E: A2 08
|
|
00DC60 1
|
|
00DC60 1 InitializeObjectEventSequence_ProcessEvents: ; $DC60
|
|
00DC60 1 86 B8 stx $B8 ; $DC60: 86 B8
|
|
00DC62 1
|
|
00DC62 1 BC 88 DC ldy ObjectEventSlotTable,x ; $DC62: BC 88 DC
|
|
00DC65 1 20 66 EB jsr DispatchNextQueuedEvent ; $DC65: 20 66 EB
|
|
00DC68 1
|
|
00DC68 1 20 48 EB jsr SelectObjectEventBank1 ; $DC68: 20 48 EB
|
|
00DC6B 1
|
|
00DC6B 1 A6 B8 ldx $B8 ; $DC6B: A6 B8
|
|
00DC6D 1 CA dex ; $DC6D: CA
|
|
00DC6E 1 10 F0 bpl InitializeObjectEventSequence_ProcessEvents
|
|
00DC70 1 ; $DC6E: 10 F0
|
|
00DC70 1
|
|
00DC70 1 ; ----------------------------------------------------------------------------
|
|
00DC70 1 ; Dispatch a command for each object/event-table entry in reverse order.
|
|
00DC70 1 ; ----------------------------------------------------------------------------
|
|
00DC70 1
|
|
00DC70 1 A0 08 ldy #$08 ; $DC70: A0 08
|
|
00DC72 1
|
|
00DC72 1 InitializeObjectEventSequence_DispatchLoop: ; $DC72
|
|
00DC72 1 84 B8 sty $B8 ; $DC72: 84 B8
|
|
00DC74 1
|
|
00DC74 1 BE 88 DC ldx ObjectEventSlotTable,y ; $DC74: BE 88 DC
|
|
00DC77 1 20 9B E2 jsr DispatchInlineObjectCommand ; $DC77: 20 9B E2
|
|
00DC7A 1
|
|
00DC7A 1 ; Inline record consumed by $E29B.
|
|
00DC7A 1 ;
|
|
00DC7A 1 ; The stored address is $DD47, apparently the continuation/handler used
|
|
00DC7A 1 ; for each selected object. Its exact dispatch convention will be confirmed
|
|
00DC7A 1 ; when $E29B is decoded.
|
|
00DC7A 1 00 47 DD .byte $00,$47,$DD ; $DC7A-$DC7C
|
|
00DC7D 1
|
|
00DC7D 1 20 48 EB jsr SelectObjectEventBank1 ; $DC7D: 20 48 EB
|
|
00DC80 1
|
|
00DC80 1 A4 B8 ldy $B8 ; $DC80: A4 B8
|
|
00DC82 1 88 dey ; $DC82: 88
|
|
00DC83 1 10 ED bpl InitializeObjectEventSequence_DispatchLoop
|
|
00DC85 1 ; $DC83: 10 ED
|
|
00DC85 1
|
|
00DC85 1 ; ----------------------------------------------------------------------------
|
|
00DC85 1 ; Leave through the common engine exit.
|
|
00DC85 1 ; ----------------------------------------------------------------------------
|
|
00DC85 1
|
|
00DC85 1 4C 6A EB jmp CommonEngineExit ; $DC85: 4C 6A EB
|
|
00DC88 1
|
|
00DC88 1 ; ============================================================================
|
|
00DC88 1 ; $DC88-$DC90
|
|
00DC88 1 ; Object/event-slot lookup table.
|
|
00DC88 1 ;
|
|
00DC88 1 ; InitializeObjectEventSequence uses this table twice:
|
|
00DC88 1 ;
|
|
00DC88 1 ; 1. Each value is passed to $EB66 as an event-slot index.
|
|
00DC88 1 ; 2. Each value is loaded into X before dispatching the inline record
|
|
00DC88 1 ; through $E29B.
|
|
00DC88 1 ;
|
|
00DC88 1 ; The values are also valid even-numbered object-array offsets. Dividing each
|
|
00DC88 1 ; value by two gives the associated compact object-state index.
|
|
00DC88 1 ; ============================================================================
|
|
00DC88 1
|
|
00DC88 1 ObjectEventSlotTable: ; $DC88
|
|
00DC88 1 04 .byte $04 ; Object/event offset $04, compact index $02
|
|
00DC89 1 0E .byte $0E ; Object/event offset $0E, compact index $07
|
|
00DC8A 1 10 .byte $10 ; Object/event offset $10, compact index $08
|
|
00DC8B 1 12 .byte $12 ; Object/event offset $12, compact index $09
|
|
00DC8C 1 14 .byte $14 ; Object/event offset $14, compact index $0A
|
|
00DC8D 1 16 .byte $16 ; Object/event offset $16, compact index $0B
|
|
00DC8E 1 1E .byte $1E ; Object/event offset $1E, compact index $0F
|
|
00DC8F 1 20 .byte $20 ; Object/event offset $20, compact index $10
|
|
00DC90 1 22 .byte $22 ; Object/event offset $22, compact index $11
|
|
00DC91 1
|
|
00DC91 1 ; ============================================================================
|
|
00DC91 1 ; $DC91-$DCA0
|
|
00DC91 1 ; Wait until the current object's geometry or region test clears.
|
|
00DC91 1 ;
|
|
00DC91 1 ; The routine repeatedly:
|
|
00DC91 1 ;
|
|
00DC91 1 ; 1. Calls the setup helper at $E2DE.
|
|
00DC91 1 ; 2. Waits using the delay returned in A.
|
|
00DC91 1 ; 3. Prepares geometry arguments through $E4B8.
|
|
00DC91 1 ; 4. Tests the resulting region through $E55F.
|
|
00DC91 1 ;
|
|
00DC91 1 ; A carry-set result restarts the routine. Carry clear leaves through the
|
|
00DC91 1 ; common engine exit.
|
|
00DC91 1 ; ============================================================================
|
|
00DC91 1
|
|
00DC91 1 WaitForObjectRegionClear: ; $DC91
|
|
00DC91 1 20 DE E2 jsr UpdateCurrentObjectAnimationDelay ; $DC91: 20 DE E2
|
|
00DC94 1 ; Returns a delay value in A.
|
|
00DC94 1
|
|
00DC94 1 20 41 EB jsr StoreObjectEventBankValue ; $DC94: 20 41 EB
|
|
00DC97 1 ; Wait for the delay supplied in A.
|
|
00DC97 1
|
|
00DC97 1 WaitForObjectRegionClear_Test:
|
|
00DC97 1 20 B8 E4 jsr SelectGeometryRecordFromObject ; $DC97: 20 B8 E4
|
|
00DC9A 1 ; Prepare the geometry/region arguments.
|
|
00DC9A 1
|
|
00DC9A 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $DC9A: 20 5F E5
|
|
00DC9D 1 ; Test the prepared region.
|
|
00DC9D 1
|
|
00DC9D 1 B0 F2 bcs WaitForObjectRegionClear
|
|
00DC9F 1 ; $DC9D: B0 F2
|
|
00DC9F 1
|
|
00DC9F 1 4C 6A EB jmp CommonEngineExit ; $DC9F: 4C 6A EB
|
|
00DCA2 1
|
|
00DCA2 1 ; ============================================================================
|
|
00DCA2 1 ; $DCA2-$DCB9
|
|
00DCA2 1 ; Dispatch an inline command for six entries from ObjectEventSlotTable.
|
|
00DCA2 1 ;
|
|
00DCA2 1 ; The routine processes table indices five through zero:
|
|
00DCA2 1 ;
|
|
00DCA2 1 ; Y=$05 -> object/event offset $16
|
|
00DCA2 1 ; Y=$04 -> object/event offset $14
|
|
00DCA2 1 ; Y=$03 -> object/event offset $12
|
|
00DCA2 1 ; Y=$02 -> object/event offset $10
|
|
00DCA2 1 ; Y=$01 -> object/event offset $0E
|
|
00DCA2 1 ; Y=$00 -> object/event offset $04
|
|
00DCA2 1 ;
|
|
00DCA2 1 ; For each entry:
|
|
00DCA2 1 ; 1. Save the table index in $B8.
|
|
00DCA2 1 ; 2. Load the object/event offset into X.
|
|
00DCA2 1 ; 3. Dispatch the inline record through $E29B.
|
|
00DCA2 1 ; 4. Wait for the next frame.
|
|
00DCA2 1 ; ============================================================================
|
|
00DCA2 1
|
|
00DCA2 1 DispatchSixObjectEvents: ; $DCA2
|
|
00DCA2 1 A0 05 ldy #$05 ; $DCA2: A0 05
|
|
00DCA4 1
|
|
00DCA4 1 DispatchSixObjectEvents_Loop: ; $DCA4
|
|
00DCA4 1 84 B8 sty $B8 ; $DCA4: 84 B8
|
|
00DCA6 1
|
|
00DCA6 1 BE 88 DC ldx ObjectEventSlotTable,y ; $DCA6: BE 88 DC
|
|
00DCA9 1
|
|
00DCA9 1 20 9B E2 jsr DispatchInlineObjectCommand ; $DCA9: 20 9B E2
|
|
00DCAC 1
|
|
00DCAC 1 ; Inline record consumed by $E29B.
|
|
00DCAC 1 ;
|
|
00DCAC 1 ; The record contains a leading zero byte followed by address $DC96.
|
|
00DCAC 1 ; The address points inside WaitForObjectRegionClear:
|
|
00DCAC 1 ;
|
|
00DCAC 1 ; $DC94: JSR $EB41
|
|
00DCAC 1 ; $DC97: JSR $E4B8
|
|
00DCAC 1 ;
|
|
00DCAC 1 ; A stored address of $DC96 is one byte before the entry at $DC97,
|
|
00DCAC 1 ; suggesting an RTS-style dispatch to $DC97.
|
|
00DCAC 1 00 .byte $00 ; $DCAC
|
|
00DCAD 1 96 DC .word WaitForObjectRegionClear_Test - 1
|
|
00DCAF 1 ; $DCAD-$DCAE: $DC96
|
|
00DCAF 1
|
|
00DCAF 1 20 48 EB jsr SelectObjectEventBank1 ; $DCAF: 20 48 EB
|
|
00DCB2 1
|
|
00DCB2 1 A4 B8 ldy $B8 ; $DCB2: A4 B8
|
|
00DCB4 1 88 dey ; $DCB4: 88
|
|
00DCB5 1
|
|
00DCB5 1 D0 ED bne DispatchSixObjectEvents_Loop
|
|
00DCB7 1 ; $DCB5: D0 ED
|
|
00DCB7 1
|
|
00DCB7 1 ; ----------------------------------------------------------------------------
|
|
00DCB7 1 ; Leave through the common engine exit.
|
|
00DCB7 1 ;
|
|
00DCB7 1 ; Because the loop uses BNE rather than BPL, processing stops after Y is
|
|
00DCB7 1 ; decremented from one to zero. The table entry at index zero is therefore not
|
|
00DCB7 1 ; dispatched by this loop. The actual processed indices are five through one.
|
|
00DCB7 1 ; ----------------------------------------------------------------------------
|
|
00DCB7 1
|
|
00DCB7 1 4C 6A EB jmp CommonEngineExit ; $DCB7: 4C 6A EB
|
|
00DCBA 1
|
|
00DCBA 1 ; ============================================================================
|
|
00DCBA 1 ; $DCBA-$DCDF
|
|
00DCBA 1 ; Select and initialize an active object or event slot.
|
|
00DCBA 1 ;
|
|
00DCBA 1 ; The routine does nothing if $A4 already contains a nonzero object offset.
|
|
00DCBA 1 ; Otherwise, it checks the base object state and searches for a usable
|
|
00DCBA 1 ; selector. On success, it stores the selected offset in $A4 and clears the
|
|
00DCBA 1 ; corresponding zero-page state byte at $A4,X.
|
|
00DCBA 1 ; ============================================================================
|
|
00DCBA 1
|
|
00DCBA 1 ; ----------------------------------------------------------------------------
|
|
00DCBA 1 ; Contract:
|
|
00DCBA 1 ; Description: Implements Select Active Object.
|
|
00DCBA 1 ; Entry: Registers: A, X; Memory: $a4, $056c
|
|
00DCBA 1 ; Returns/products: Registers/clobbers: A, X
|
|
00DCBA 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DCBA 1 ; Memory effects: $a4
|
|
00DCBA 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DCBA 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DCBA 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00DCBA 1 ; ----------------------------------------------------------------------------
|
|
00DCBA 1 SelectActiveObject: ; $DCBA
|
|
00DCBA 1 A5 A4 lda $A4 ; $DCBA: A5 A4
|
|
00DCBC 1 D0 21 bne SelectActiveObject_Return
|
|
00DCBE 1 ; $DCBC: D0 21
|
|
00DCBE 1
|
|
00DCBE 1 ; ----------------------------------------------------------------------------
|
|
00DCBE 1 ; When the base object's high state at $056C is negative after comparison with
|
|
00DCBE 1 ; three, use the alternate selector helper at $DF45.
|
|
00DCBE 1 ; ----------------------------------------------------------------------------
|
|
00DCBE 1
|
|
00DCBE 1 AD 6C 05 lda $056C ; $DCBE: AD 6C 05
|
|
00DCC1 1 C9 03 cmp #$03 ; $DCC1: C9 03
|
|
00DCC3 1 30 13 bmi SelectActiveObject_Alternate
|
|
00DCC5 1 ; $DCC3: 30 13
|
|
00DCC5 1
|
|
00DCC5 1 ; ----------------------------------------------------------------------------
|
|
00DCC5 1 ; Obtain a candidate selector through $DF08.
|
|
00DCC5 1 ;
|
|
00DCC5 1 ; Values seven or greater are rejected.
|
|
00DCC5 1 ; ----------------------------------------------------------------------------
|
|
00DCC5 1
|
|
00DCC5 1 20 08 DF jsr TestCurrentObjectGeometry ; $DCC5: 20 08 DF
|
|
00DCC8 1
|
|
00DCC8 1 C9 07 cmp #$07 ; $DCC8: C9 07
|
|
00DCCA 1 B0 13 bcs SelectActiveObject_Return
|
|
00DCCC 1 ; $DCCA: B0 13
|
|
00DCCC 1
|
|
00DCCC 1 ; ----------------------------------------------------------------------------
|
|
00DCCC 1 ; Convert the candidate selector into an object offset.
|
|
00DCCC 1 ;
|
|
00DCCC 1 ; GetCurrentObjectSelectorAndState returns:
|
|
00DCCC 1 ; X = selected object offset
|
|
00DCCC 1 ; Y = related selector value
|
|
00DCCC 1 ; ----------------------------------------------------------------------------
|
|
00DCCC 1
|
|
00DCCC 1 SelectActiveObject_Save: ; $DCCC
|
|
00DCCC 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DCCC: 20 DC E3
|
|
00DCCF 1
|
|
00DCCF 1 86 A4 stx $A4 ; $DCCF: 86 A4
|
|
00DCD1 1
|
|
00DCD1 1 ; ----------------------------------------------------------------------------
|
|
00DCD1 1 ; Clear the selected zero-page object-state entry.
|
|
00DCD1 1 ;
|
|
00DCD1 1 ; X is explicitly changed to zero, so STX $A4,X stores zero at address $A4.
|
|
00DCD1 1 ; This is distinct from clearing the variable at zero-page address $A4.
|
|
00DCD1 1 ; ----------------------------------------------------------------------------
|
|
00DCD1 1
|
|
00DCD1 1 A2 00 ldx #$00 ; $DCD1: A2 00
|
|
00DCD3 1 96 A4 stx $A4,y ; $DCD3: 96 A4
|
|
00DCD5 1
|
|
00DCD5 1 4C 48 DD jmp ContinueObjectProcessing; $DCD5: 4C 48 DD
|
|
00DCD8 1
|
|
00DCD8 1 ; ----------------------------------------------------------------------------
|
|
00DCD8 1 ; Alternate selection path.
|
|
00DCD8 1 ;
|
|
00DCD8 1 ; Continue requesting a selector until the returned value is at least eight.
|
|
00DCD8 1 ; The successful value remains in A while GetCurrentObjectSelectorAndState derives the selected object.
|
|
00DCD8 1 ; ----------------------------------------------------------------------------
|
|
00DCD8 1
|
|
00DCD8 1 SelectActiveObject_Alternate: ; $DCD8
|
|
00DCD8 1 20 45 DF jsr CalculateCurrentObjectGeometry ; $DCD8: 20 45 DF
|
|
00DCDB 1
|
|
00DCDB 1 C9 08 cmp #$08 ; $DCDB: C9 08
|
|
00DCDD 1 90 ED bcc SelectActiveObject_Save ; $DCDD: 90 ED
|
|
00DCDF 1
|
|
00DCDF 1 SelectActiveObject_Return: ; $DCDF
|
|
00DCDF 1 60 rts ; $DCDF: 60
|
|
00DCE0 1
|
|
00DCE0 1 ; ============================================================================
|
|
00DCE0 1 ; $DCE0-$DD20
|
|
00DCE0 1 ; Initialize the selected object's state, run geometry tests, and select one
|
|
00DCE0 1 ; of two shared continuation paths.
|
|
00DCE0 1 ;
|
|
00DCE0 1 ; Entry:
|
|
00DCE0 1 ; X = selected object offset
|
|
00DCE0 1 ;
|
|
00DCE0 1 ; The routine saves the incoming object offset, derives its compact state
|
|
00DCE0 1 ; index, stores the original offset into $0595,X, then executes a sequence of
|
|
00DCE0 1 ; object and geometry helpers.
|
|
00DCE0 1 ; ============================================================================
|
|
00DCE0 1
|
|
00DCE0 1 ProcessSelectedObject: ; $DCE0
|
|
00DCE0 1 8A txa ; $DCE0: 8A
|
|
00DCE1 1 A8 tay ; $DCE1: A8
|
|
00DCE2 1 ; Preserve the incoming object offset in Y.
|
|
00DCE2 1
|
|
00DCE2 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DCE5 1 ; $DCE2: 20 68 DA
|
|
00DCE5 1 ; X = CurrentObjectIndex >> 1.
|
|
00DCE5 1
|
|
00DCE5 1 98 tya ; $DCE5: 98
|
|
00DCE6 1 9D 95 05 sta $0595,x ; $DCE6: 9D 95 05
|
|
00DCE9 1 ; Save the selected object offset.
|
|
00DCE9 1
|
|
00DCE9 1 ; ----------------------------------------------------------------------------
|
|
00DCE9 1 ; Re-enter the object-selector routine.
|
|
00DCE9 1 ;
|
|
00DCE9 1 ; Because $A4 is now nonzero, SelectActiveObject returns immediately.
|
|
00DCE9 1 ; ----------------------------------------------------------------------------
|
|
00DCE9 1
|
|
00DCE9 1 20 BA DC jsr SelectActiveObject ; $DCE9: 20 BA DC
|
|
00DCEC 1
|
|
00DCEC 1 ; ----------------------------------------------------------------------------
|
|
00DCEC 1 ; Prepare and evaluate the selected object's geometry.
|
|
00DCEC 1 ; ----------------------------------------------------------------------------
|
|
00DCEC 1 ProcessSelectedObject_Geometry:
|
|
00DCEC 1 20 74 E4 jsr SelectGeometryRecord_Default ; $DCEC: 20 74 E4
|
|
00DCEF 1 20 C2 E4 jsr LoadGeometryRecord ; $DCEF: 20 C2 E4
|
|
00DCF2 1 20 DB E4 jsr CalculateCurrentGeometryDifference ; $DCF2: 20 DB E4
|
|
00DCF5 1 20 02 E5 jsr EvaluateGeometryDifference ; $DCF5: 20 02 E5
|
|
00DCF8 1
|
|
00DCF8 1 C9 08 cmp #$08 ; $DCF8: C9 08
|
|
00DCFA 1 B0 0B bcs ProcessSelectedObject_LargeResult
|
|
00DCFC 1 ; $DCFA: B0 0B
|
|
00DCFC 1
|
|
00DCFC 1 ; ----------------------------------------------------------------------------
|
|
00DCFC 1 ; For values below eight, preserve A while obtaining the current selector.
|
|
00DCFC 1 ;
|
|
00DCFC 1 ; GetCurrentObjectSelectorAndState returns X and Y. STX $A4,Y stores X into a selector-dependent
|
|
00DCFC 1 ; zero-page state slot.
|
|
00DCFC 1 ; ----------------------------------------------------------------------------
|
|
00DCFC 1
|
|
00DCFC 1 48 pha ; $DCFC: 48
|
|
00DCFD 1
|
|
00DCFD 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DCFD: 20 DC E3
|
|
00DD00 1
|
|
00DD00 1 96 A4 stx $A4,y ; $DD00: 96 A4
|
|
00DD02 1
|
|
00DD02 1 68 pla ; $DD02: 68
|
|
00DD03 1
|
|
00DD03 1 C9 03 cmp #$03 ; $DD03: C9 03
|
|
00DD05 1 90 0E bcc ProcessSelectedObject_SmallResult
|
|
00DD07 1 ; $DD05: 90 0E
|
|
00DD07 1
|
|
00DD07 1 ; ----------------------------------------------------------------------------
|
|
00DD07 1 ; Handle values three or greater, or any original result at least eight.
|
|
00DD07 1 ; ----------------------------------------------------------------------------
|
|
00DD07 1
|
|
00DD07 1 ProcessSelectedObject_LargeResult: ; $DD07
|
|
00DD07 1 A5 C6 lda $C6 ; $DD07: A5 C6
|
|
00DD09 1
|
|
00DD09 1 20 13 E5 jsr BuildGeometryVector ; $DD09: 20 13 E5
|
|
00DD0C 1 20 28 E5 jsr StoreCurrentObjectMovement ; $DD0C: 20 28 E5
|
|
00DD0F 1 20 DE E2 jsr UpdateCurrentObjectAnimationDelay ; $DD0F: 20 DE E2
|
|
00DD12 1
|
|
00DD12 1 4C 4A DD jmp ContinueObjectProcessingWithDelay
|
|
00DD15 1 ; $DD12: 4C 4A DD
|
|
00DD15 1
|
|
00DD15 1 ; ----------------------------------------------------------------------------
|
|
00DD15 1 ; Handle result values zero through two.
|
|
00DD15 1 ; ----------------------------------------------------------------------------
|
|
00DD15 1
|
|
00DD15 1 ProcessSelectedObject_SmallResult: ; $DD15
|
|
00DD15 1 20 48 E5 jsr StoreGeometryInCurrentObject ; $DD15: 20 48 E5
|
|
00DD18 1 20 D3 E2 jsr ClearCurrentObjectMovement ; $DD18: 20 D3 E2
|
|
00DD1B 1 20 D4 DF jsr UpdateCurrentObjectDisplayState ; $DD1B: 20 D4 DF
|
|
00DD1E 1
|
|
00DD1E 1 4C 48 DD jmp ContinueObjectProcessing
|
|
00DD21 1 ; $DD1E: 4C 48 DD
|
|
00DD21 1
|
|
00DD21 1 ; ============================================================================
|
|
00DD21 1 ; $DD21-$DD4C
|
|
00DD21 1 ; Find an available object-state slot or continue processing the current
|
|
00DD21 1 ; selected object.
|
|
00DD21 1 ;
|
|
00DD21 1 ; The routine searches zero-page state entries $A4-$A7 when the current object
|
|
00DD21 1 ; offset is below $18. If an empty entry is found, the current object is moved
|
|
00DD21 1 ; into that slot and processing restarts at the geometry setup path at $DCEC.
|
|
00DD21 1 ;
|
|
00DD21 1 ; Otherwise, the routine performs a short delay and continues with the shared
|
|
00DD21 1 ; object-processing path beginning at $DD4D.
|
|
00DD21 1 ; ============================================================================
|
|
00DD21 1
|
|
00DD21 1 FindAvailableObjectSlot: ; $DD21
|
|
00DD21 1 A6 E1 ldx CurrentObjectIndex ; $DD21: A6 E1
|
|
00DD23 1
|
|
00DD23 1 E0 18 cpx #$18 ; $DD23: E0 18
|
|
00DD25 1 B0 09 bcs CheckSavedObjectOffset ; $DD25: B0 09
|
|
00DD27 1
|
|
00DD27 1 ; ----------------------------------------------------------------------------
|
|
00DD27 1 ; Search zero-page entries $A4-$A7 for an empty slot.
|
|
00DD27 1 ;
|
|
00DD27 1 ; X begins at four and is decremented before looping, so the tested addresses
|
|
00DD27 1 ; are:
|
|
00DD27 1 ;
|
|
00DD27 1 ; $A8 initially through indexed addressing at X=$04
|
|
00DD27 1 ; then $A7, $A6, and $A5 as X counts down
|
|
00DD27 1 ;
|
|
00DD27 1 ; The loop intentionally stops before repeating with X=$00.
|
|
00DD27 1 ; ----------------------------------------------------------------------------
|
|
00DD27 1
|
|
00DD27 1 A2 04 ldx #$04 ; $DD27: A2 04
|
|
00DD29 1
|
|
00DD29 1 FindAvailableObjectSlot_Search: ; $DD29
|
|
00DD29 1 B5 A4 lda $A4,x ; $DD29: B5 A4
|
|
00DD2B 1 F0 0F beq AssignObjectToSlot ; $DD2B: F0 0F
|
|
00DD2D 1
|
|
00DD2D 1 CA dex ; $DD2D: CA
|
|
00DD2E 1 D0 F9 bne FindAvailableObjectSlot_Search
|
|
00DD30 1 ; $DD2E: D0 F9
|
|
00DD30 1
|
|
00DD30 1 ; ----------------------------------------------------------------------------
|
|
00DD30 1 ; No empty slot was found, or the current object offset is at least $18.
|
|
00DD30 1 ;
|
|
00DD30 1 ; If the saved object offset at $A9 equals CurrentObjectIndex, branch forward
|
|
00DD30 1 ; to the special path at HandleSavedObject
|
|
00DD30 1 ; ----------------------------------------------------------------------------
|
|
00DD30 1
|
|
00DD30 1 CheckSavedObjectOffset: ; $DD30
|
|
00DD30 1 A5 A9 lda $A9 ; $DD30: A5 A9
|
|
00DD32 1 C5 E1 cmp CurrentObjectIndex ; $DD32: C5 E1
|
|
00DD34 1 F0 4C beq ObjectSelection_CheckActive ; $DD34: F0 4C
|
|
00DD36 1
|
|
00DD36 1 ; ----------------------------------------------------------------------------
|
|
00DD36 1 ; Run the object helper and continue at the common delay path.
|
|
00DD36 1 ; ----------------------------------------------------------------------------
|
|
00DD36 1
|
|
00DD36 1 20 D3 E2 jsr ClearCurrentObjectMovement ; $DD36: 20 D3 E2
|
|
00DD39 1
|
|
00DD39 1 4C 48 DD jmp ContinueObjectProcessing
|
|
00DD3C 1 ; $DD39: 4C 48 DD
|
|
00DD3C 1
|
|
00DD3C 1 ; ----------------------------------------------------------------------------
|
|
00DD3C 1 ; An empty zero-page object slot was found.
|
|
00DD3C 1 ;
|
|
00DD3C 1 ; Preserve the slot index in Y, derive the compact current-object state index,
|
|
00DD3C 1 ; and store the slot index into $0595,X.
|
|
00DD3C 1 ; ----------------------------------------------------------------------------
|
|
00DD3C 1
|
|
00DD3C 1 AssignObjectToSlot: ; $DD3C
|
|
00DD3C 1 8A txa ; $DD3C: 8A
|
|
00DD3D 1 A8 tay ; $DD3D: A8
|
|
00DD3E 1 ; Y = available zero-page slot index.
|
|
00DD3E 1
|
|
00DD3E 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DD41 1 ; $DD3E: 20 68 DA
|
|
00DD41 1
|
|
00DD41 1 98 tya ; $DD41: 98
|
|
00DD42 1 9D 95 05 sta $0595,x ; $DD42: 9D 95 05
|
|
00DD45 1
|
|
00DD45 1 ; ----------------------------------------------------------------------------
|
|
00DD45 1 ; Restart selected-object processing at the geometry setup entry.
|
|
00DD45 1 ; ----------------------------------------------------------------------------
|
|
00DD45 1
|
|
00DD45 1 4C EC DC jmp ProcessSelectedObject_Geometry
|
|
00DD48 1 ; $DD45: 4C EC DC
|
|
00DD48 1
|
|
00DD48 1 ; ============================================================================
|
|
00DD48 1 ; $DD48-$DD4C
|
|
00DD48 1 ; Shared continuation used by several earlier object-processing paths.
|
|
00DD48 1 ;
|
|
00DD48 1 ; Entry at $DD48 loads a six-tick delay.
|
|
00DD48 1 ; Entry at ContinueObjectProcessingWithDelay uses the delay already present in A.
|
|
00DD48 1 ; ============================================================================
|
|
00DD48 1
|
|
00DD48 1 ContinueObjectProcessing: ; $DD48
|
|
00DD48 1 A9 06 lda #$06 ; $DD48: A9 06
|
|
00DD4A 1
|
|
00DD4A 1 ContinueObjectProcessingWithDelay: ; $DD4A
|
|
00DD4A 1 20 41 EB jsr StoreObjectEventBankValue ; $DD4A: 20 41 EB
|
|
00DD4D 1
|
|
00DD4D 1 ; ============================================================================
|
|
00DD4D 1 ; $DD4D-$DD77
|
|
00DD4D 1 ; Shared object-selection and routing path.
|
|
00DD4D 1 ;
|
|
00DD4D 1 ; This path checks whether CurrentObjectIndex is already assigned to one of
|
|
00DD4D 1 ; the zero-page object slots at $A4-$A8. It then evaluates global state and
|
|
00DD4D 1 ; routes to the appropriate object-processing branch.
|
|
00DD4D 1 ; ============================================================================
|
|
00DD4D 1
|
|
00DD4D 1 ObjectSelectionSharedPath: ; $DD4D
|
|
00DD4D 1 A5 E1 lda CurrentObjectIndex ; $DD4D: A5 E1
|
|
00DD4F 1
|
|
00DD4F 1 ; ----------------------------------------------------------------------------
|
|
00DD4F 1 ; Search the five zero-page object slots $A8 through $A4.
|
|
00DD4F 1 ;
|
|
00DD4F 1 ; X begins at four:
|
|
00DD4F 1 ;
|
|
00DD4F 1 ; X=$04 -> $A8
|
|
00DD4F 1 ; X=$03 -> $A7
|
|
00DD4F 1 ; X=$02 -> $A6
|
|
00DD4F 1 ; X=$01 -> $A5
|
|
00DD4F 1 ; X=$00 -> $A4
|
|
00DD4F 1 ;
|
|
00DD4F 1 ; If a slot matches CurrentObjectIndex, restart selected-object processing at
|
|
00DD4F 1 ; $DCE0 with the matching slot index still in X.
|
|
00DD4F 1 ; ----------------------------------------------------------------------------
|
|
00DD4F 1
|
|
00DD4F 1 A2 04 ldx #$04 ; $DD4F: A2 04
|
|
00DD51 1
|
|
00DD51 1 ObjectSelection_SearchSlots: ; $DD51
|
|
00DD51 1 D5 A4 cmp $A4,x ; $DD51: D5 A4
|
|
00DD53 1 F0 8B beq ProcessSelectedObject ; $DD53: F0 8B
|
|
00DD55 1
|
|
00DD55 1 CA dex ; $DD55: CA
|
|
00DD56 1 D0 F9 bne ObjectSelection_SearchSlots
|
|
00DD58 1 ; $DD56: D0 F9
|
|
00DD58 1
|
|
00DD58 1 ; ----------------------------------------------------------------------------
|
|
00DD58 1 ; If BaseMotionEventCount or SpecialSequenceState is nonzero, continue at the shared state path
|
|
00DD58 1 ; beginning at $DD78.
|
|
00DD58 1 ; ----------------------------------------------------------------------------
|
|
00DD58 1
|
|
00DD58 1 A6 5E ldx BaseMotionEventCount ; $DD58: A6 5E
|
|
00DD5A 1 D0 1C bne ObjectSelection_NoSavedObject
|
|
00DD5C 1 ; $DD5A: D0 1C
|
|
00DD5C 1
|
|
00DD5C 1 A6 6D ldx SpecialSequenceState ; $DD5C: A6 6D
|
|
00DD5E 1 D0 18 bne ObjectSelection_NoSavedObject
|
|
00DD60 1 ; $DD5E: D0 18
|
|
00DD60 1
|
|
00DD60 1 ; ----------------------------------------------------------------------------
|
|
00DD60 1 ; Run the geometry/collision test at $CBEA.
|
|
00DD60 1 ;
|
|
00DD60 1 ; Carry clear continues locally. Carry set transfers to the alternate path at
|
|
00DD60 1 ; $DED8.
|
|
00DD60 1 ; ----------------------------------------------------------------------------
|
|
00DD60 1
|
|
00DD60 1 20 EA CB jsr TestCurrentObjectCollision ; $DD60: 20 EA CB
|
|
00DD63 1 90 03 bcc ObjectSelection_CheckCurrent
|
|
00DD65 1 ; $DD63: 90 03
|
|
00DD65 1
|
|
00DD65 1 4C D8 DE jmp ObjectRouting_ReverseMovement ; $DD65: 4C D8 DE
|
|
00DD68 1
|
|
00DD68 1 ; ----------------------------------------------------------------------------
|
|
00DD68 1 ; Compare CurrentObjectIndex against the primary and saved object offsets.
|
|
00DD68 1 ; ----------------------------------------------------------------------------
|
|
00DD68 1
|
|
00DD68 1 ObjectSelection_CheckCurrent: ; $DD68
|
|
00DD68 1 A6 E1 ldx CurrentObjectIndex ; $DD68: A6 E1
|
|
00DD6A 1
|
|
00DD6A 1 E4 A4 cpx $A4 ; $DD6A: E4 A4
|
|
00DD6C 1 F0 71 beq ObjectRouting_CheckBaseState ; $DD6C: F0 71
|
|
00DD6E 1
|
|
00DD6E 1 E4 A9 cpx $A9 ; $DD6E: E4 A9
|
|
00DD70 1 F0 10 beq ObjectSelection_CheckActive
|
|
00DD72 1 ; $DD70: F0 10
|
|
00DD72 1
|
|
00DD72 1 ; ----------------------------------------------------------------------------
|
|
00DD72 1 ; If no saved object exists, branch forward to $DDC8.
|
|
00DD72 1 ;
|
|
00DD72 1 ; Otherwise, restart the available-slot search at $DD21.
|
|
00DD72 1 ; ----------------------------------------------------------------------------
|
|
00DD72 1
|
|
00DD72 1 A5 A9 lda $A9 ; $DD72: A5 A9
|
|
00DD74 1 F0 52 beq ObjectRoutingPath ; $DD74: F0 52
|
|
00DD76 1
|
|
00DD76 1 D0 A9 bne FindAvailableObjectSlot ; $DD76: D0 A9
|
|
00DD78 1 ; Always taken when A is nonzero.
|
|
00DD78 1
|
|
00DD78 1 ; ============================================================================
|
|
00DD78 1 ; $DD78-$DD8E
|
|
00DD78 1 ; Exit path followed by the shared object-selection continuation.
|
|
00DD78 1 ; ============================================================================
|
|
00DD78 1
|
|
00DD78 1 ObjectSelection_NoSavedObject: ; $DD78
|
|
00DD78 1 20 D3 E2 jsr ClearCurrentObjectMovement ; $DD78: 20 D3 E2
|
|
00DD7B 1 4C 6A EB jmp CommonEngineExit ; $DD7B: 4C 6A EB
|
|
00DD7E 1
|
|
00DD7E 1 ; ----------------------------------------------------------------------------
|
|
00DD7E 1 ; Continue according to the flags returned by the preceding shared helper.
|
|
00DD7E 1 ;
|
|
00DD7E 1 ; These branches go backward into previously decoded code:
|
|
00DD7E 1 ;
|
|
00DD7E 1 ; Z set -> assign the current object to an available slot at $DD3C
|
|
00DD7E 1 ; C clear -> restart the slot-selection routine at $DD21
|
|
00DD7E 1 ; ----------------------------------------------------------------------------
|
|
00DD7E 1
|
|
00DD7E 1 ObjectSelection_StatePath: ; $DD7E
|
|
00DD7E 1 F0 BC beq AssignObjectToSlot ; $DD7E: F0 BC
|
|
00DD80 1 ObjectSelection_RestartSlots:
|
|
00DD80 1 90 9F bcc FindAvailableObjectSlot ; $DD80: 90 9F
|
|
00DD82 1
|
|
00DD82 1 ; ----------------------------------------------------------------------------
|
|
00DD82 1 ; Check whether an object is already active in $A4.
|
|
00DD82 1 ;
|
|
00DD82 1 ; This is also the target of the BEQ at $DD34:
|
|
00DD82 1 ;
|
|
00DD82 1 ; $DD34: F0 4C -> $DD82
|
|
00DD82 1 ; ----------------------------------------------------------------------------
|
|
00DD82 1
|
|
00DD82 1 ObjectSelection_CheckActive: ; $DD82
|
|
00DD82 1 A6 A4 ldx $A4 ; $DD82: A6 A4
|
|
00DD84 1 D0 09 bne ProcessSavedObjectGeometry
|
|
00DD86 1 ; $DD84: D0 09
|
|
00DD86 1
|
|
00DD86 1 ; ----------------------------------------------------------------------------
|
|
00DD86 1 ; No active object is stored in $A4.
|
|
00DD86 1 ;
|
|
00DD86 1 ; X is zero here, so clear $A9, then assign CurrentObjectIndex to $A4.
|
|
00DD86 1 ; ----------------------------------------------------------------------------
|
|
00DD86 1
|
|
00DD86 1 86 A9 stx $A9 ; $DD86: 86 A9
|
|
00DD88 1
|
|
00DD88 1 HandleSavedObject: ; $DD88
|
|
00DD88 1 A6 E1 ldx CurrentObjectIndex ; $DD88: A6 E1
|
|
00DD8A 1 86 A4 stx $A4 ; $DD8A: 86 A4
|
|
00DD8C 1
|
|
00DD8C 1 4C 48 DD jmp ContinueObjectProcessing
|
|
00DD8F 1 ; $DD8C: 4C 48 DD
|
|
00DD8F 1
|
|
00DD8F 1 ; ============================================================================
|
|
00DD8F 1 ; $DD8F-$DDC7
|
|
00DD8F 1 ; Build and test a geometry region around the active object.
|
|
00DD8F 1 ;
|
|
00DD8F 1 ; Entry:
|
|
00DD8F 1 ; X = active object offset loaded from $A4
|
|
00DD8F 1 ;
|
|
00DD8F 1 ; The object's coordinate is copied into the geometry arguments at $B2-$B5.
|
|
00DD8F 1 ; The vertical high byte is increased by five before the geometry test.
|
|
00DD8F 1 ; ============================================================================
|
|
00DD8F 1
|
|
00DD8F 1 ProcessSavedObjectGeometry: ; $DD8F
|
|
00DD8F 1 BD 09 05 lda $0509,x ; $DD8F: BD 09 05
|
|
00DD92 1 85 B2 sta $B2 ; $DD92: 85 B2
|
|
00DD94 1
|
|
00DD94 1 BD 0A 05 lda $050A,x ; $DD94: BD 0A 05
|
|
00DD97 1 85 B3 sta $B3 ; $DD97: 85 B3
|
|
00DD99 1
|
|
00DD99 1 BD 3A 05 lda $053A,x ; $DD99: BD 3A 05
|
|
00DD9C 1 85 B4 sta $B4 ; $DD9C: 85 B4
|
|
00DD9E 1
|
|
00DD9E 1 BD 3B 05 lda $053B,x ; $DD9E: BD 3B 05
|
|
00DDA1 1 18 clc ; $DDA1: 18
|
|
00DDA2 1 69 05 adc #$05 ; $DDA2: 69 05
|
|
00DDA4 1 85 B5 sta $B5 ; $DDA4: 85 B5
|
|
00DDA6 1
|
|
00DDA6 1 ; ----------------------------------------------------------------------------
|
|
00DDA6 1 ; Adjust the geometry arguments and perform the region test.
|
|
00DDA6 1 ; ----------------------------------------------------------------------------
|
|
00DDA6 1
|
|
00DDA6 1 20 FB DE jsr SelectObjectGeometrySize ; $DDA6: 20 FB DE
|
|
00DDA9 1 20 62 E5 jsr EvaluateLoadedCurrentObjectGeometry ; $DDA9: 20 62 E5
|
|
00DDAC 1
|
|
00DDAC 1 90 06 bcc ProcessSavedObjectAnimation
|
|
00DDAE 1 ; $DDAC: 90 06
|
|
00DDAE 1
|
|
00DDAE 1 ; ----------------------------------------------------------------------------
|
|
00DDAE 1 ; Region test remains active.
|
|
00DDAE 1 ;
|
|
00DDAE 1 ; Run the setup helper and continue using the delay returned in A.
|
|
00DDAE 1 ; ----------------------------------------------------------------------------
|
|
00DDAE 1
|
|
00DDAE 1 20 DE E2 jsr UpdateCurrentObjectAnimationDelay ; $DDAE: 20 DE E2
|
|
00DDB1 1
|
|
00DDB1 1 4C 4A DD jmp ContinueObjectProcessingWithDelay
|
|
00DDB4 1 ; $DDB1: 4C 4A DD
|
|
00DDB4 1
|
|
00DDB4 1 ; ----------------------------------------------------------------------------
|
|
00DDB4 1 ; Region test cleared.
|
|
00DDB4 1 ;
|
|
00DDB4 1 ; Set the current object's animation frame to $67. Compact object indices
|
|
00DDB4 1 ; below $0C also receive attribute/state value $43.
|
|
00DDB4 1 ; ----------------------------------------------------------------------------
|
|
00DDB4 1
|
|
00DDB4 1 ProcessSavedObjectAnimation: ; $DDB4
|
|
00DDB4 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DDB7 1 ; $DDB4: 20 68 DA
|
|
00DDB7 1
|
|
00DDB7 1 A9 67 lda #$67 ; $DDB7: A9 67
|
|
00DDB9 1 9D 9B 03 sta $039B,x ; $DDB9: 9D 9B 03
|
|
00DDBC 1
|
|
00DDBC 1 E0 0C cpx #$0C ; $DDBC: E0 0C
|
|
00DDBE 1 B0 05 bcs ProcessSavedObjectAnimation_Done
|
|
00DDC0 1 ; $DDBE: B0 05
|
|
00DDC0 1
|
|
00DDC0 1 A9 43 lda #$43 ; $DDC0: A9 43
|
|
00DDC2 1 9D B0 03 sta $03B0,x ; $DDC2: 9D B0 03
|
|
00DDC5 1
|
|
00DDC5 1 ProcessSavedObjectAnimation_Done: ; $DDC5
|
|
00DDC5 1 4C 48 DD jmp ContinueObjectProcessing
|
|
00DDC8 1 ; $DDC5: 4C 48 DD
|
|
00DDC8 1
|
|
00DDC8 1 ; ============================================================================
|
|
00DDC8 1 ; $DDC8-$DE54
|
|
00DDC8 1 ; Route the current object through slot selection, state checks, animation
|
|
00DDC8 1 ; setup, collision tests, and common continuation paths.
|
|
00DDC8 1 ; ============================================================================
|
|
00DDC8 1
|
|
00DDC8 1 ObjectRoutingPath: ; $DDC8
|
|
00DDC8 1 A0 16 ldy #$16 ; $DDC8: A0 16
|
|
00DDCA 1
|
|
00DDCA 1 ; ----------------------------------------------------------------------------
|
|
00DDCA 1 ; Object offsets above $16 skip directly to the main state check at $DDDF.
|
|
00DDCA 1 ; ----------------------------------------------------------------------------
|
|
00DDCA 1
|
|
00DDCA 1 C4 E1 cpy CurrentObjectIndex ; $DDCA: C4 E1
|
|
00DDCC 1 90 11 bcc ObjectRouting_CheckBaseState
|
|
00DDCE 1 ; $DDCC: 90 11
|
|
00DDCE 1
|
|
00DDCE 1 ; ----------------------------------------------------------------------------
|
|
00DDCE 1 ; Search zero-page object slots $A8 through $A5.
|
|
00DDCE 1 ;
|
|
00DDCE 1 ; An empty slot branches backward to ObjectSelection_StatePath at $DD7E.
|
|
00DDCE 1 ; ----------------------------------------------------------------------------
|
|
00DDCE 1
|
|
00DDCE 1 A2 04 ldx #$04 ; $DDCE: A2 04
|
|
00DDD0 1
|
|
00DDD0 1 ObjectRouting_SearchSlots: ; $DDD0
|
|
00DDD0 1 B5 A4 lda $A4,x ; $DDD0: B5 A4
|
|
00DDD2 1 F0 AA beq ObjectSelection_StatePath
|
|
00DDD4 1 ; $DDD2: F0 AA
|
|
00DDD4 1
|
|
00DDD4 1 CA dex ; $DDD4: CA
|
|
00DDD5 1 D0 F9 bne ObjectRouting_SearchSlots
|
|
00DDD7 1 ; $DDD5: D0 F9
|
|
00DDD7 1
|
|
00DDD7 1 ; ----------------------------------------------------------------------------
|
|
00DDD7 1 ; Compare the limit value $16 against the active and saved object offsets.
|
|
00DDD7 1 ;
|
|
00DDD7 1 ; If Y is below either offset, branch backward to the BCC at $DD80, which
|
|
00DDD7 1 ; restarts the available-slot routine at $DD21.
|
|
00DDD7 1 ; ----------------------------------------------------------------------------
|
|
00DDD7 1
|
|
00DDD7 1 C4 A4 cpy $A4 ; $DDD7: C4 A4
|
|
00DDD9 1 90 A5 bcc ObjectSelection_RestartSlots
|
|
00DDDB 1 ; $DDD9: 90 A5
|
|
00DDDB 1
|
|
00DDDB 1 C4 A9 cpy $A9 ; $DDDB: C4 A9
|
|
00DDDD 1 90 A1 bcc ObjectSelection_RestartSlots
|
|
00DDDF 1 ; $DDDD: 90 A1
|
|
00DDDF 1
|
|
00DDDF 1 ; ============================================================================
|
|
00DDDF 1 ; $DDDF
|
|
00DDDF 1 ; Main state and candidate-selection path.
|
|
00DDDF 1 ; ============================================================================
|
|
00DDDF 1
|
|
00DDDF 1 ObjectRouting_CheckBaseState: ; $DDDF
|
|
00DDDF 1 AD 6C 05 lda $056C ; $DDDF: AD 6C 05
|
|
00DDE2 1 C9 03 cmp #$03 ; $DDE2: C9 03
|
|
00DDE4 1 10 6F bpl ObjectRouting_BaseStateAtLeast3
|
|
00DDE6 1 ; $DDE4: 10 6F
|
|
00DDE6 1 ; Target $DE55.
|
|
00DDE6 1
|
|
00DDE6 1 ; ----------------------------------------------------------------------------
|
|
00DDE6 1 ; Obtain a candidate through $DF45.
|
|
00DDE6 1 ; ----------------------------------------------------------------------------
|
|
00DDE6 1
|
|
00DDE6 1 20 45 DF jsr CalculateCurrentObjectGeometry ; $DDE6: 20 45 DF
|
|
00DDE9 1
|
|
00DDE9 1 C9 18 cmp #$18 ; $DDE9: C9 18
|
|
00DDEB 1 B0 08 bcs ObjectRouting_CheckCandidate8
|
|
00DDED 1 ; $DDEB: B0 08
|
|
00DDED 1
|
|
00DDED 1 ; ----------------------------------------------------------------------------
|
|
00DDED 1 ; For candidates below $18, distinguish current object offsets below or above
|
|
00DDED 1 ; $18 before applying the candidate-$08 threshold.
|
|
00DDED 1 ; ----------------------------------------------------------------------------
|
|
00DDED 1
|
|
00DDED 1 A6 E1 ldx CurrentObjectIndex ; $DDED: A6 E1
|
|
00DDEF 1 E0 18 cpx #$18 ; $DDEF: E0 18
|
|
00DDF1 1 B0 04 bcs ObjectRouting_CompareCurrent
|
|
00DDF3 1 ; $DDF1: B0 04
|
|
00DDF3 1
|
|
00DDF3 1 C9 08 cmp #$08 ; $DDF3: C9 08
|
|
00DDF5 1
|
|
00DDF5 1 ObjectRouting_CheckCandidate8: ; $DDF5
|
|
00DDF5 1 B0 78 bcs ObjectRouting_LargeCandidate
|
|
00DDF7 1 ; $DDF5: B0 78
|
|
00DDF7 1 ; Target $DE6F.
|
|
00DDF7 1
|
|
00DDF7 1 ; ----------------------------------------------------------------------------
|
|
00DDF7 1 ; Candidate is below the active threshold.
|
|
00DDF7 1 ;
|
|
00DDF7 1 ; If CurrentObjectIndex differs from $A4, run the alternate path at $DE4D.
|
|
00DDF7 1 ; ----------------------------------------------------------------------------
|
|
00DDF7 1
|
|
00DDF7 1 ObjectRouting_CompareCurrent: ; $DDF7
|
|
00DDF7 1 A6 E1 ldx CurrentObjectIndex ; $DDF7: A6 E1
|
|
00DDF9 1 E4 A4 cpx $A4 ; $DDF9: E4 A4
|
|
00DDFB 1 D0 50 bne ObjectRouting_Alternate ; $DDFB: D0 50
|
|
00DDFD 1
|
|
00DDFD 1 C9 02 cmp #$02 ; $DDFD: C9 02
|
|
00DDFF 1 B0 77 bcs ObjectRouting_ApplyCoordinateSetup
|
|
00DE01 1 ; $DDFF: B0 77
|
|
00DE01 1 ; Target $DE78.
|
|
00DE01 1
|
|
00DE01 1 ; ----------------------------------------------------------------------------
|
|
00DE01 1 ; Configure animation values for candidate values zero or one.
|
|
00DE01 1 ; ----------------------------------------------------------------------------
|
|
00DE01 1
|
|
00DE01 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DE04 1 ; $DE01: 20 68 DA
|
|
00DE04 1
|
|
00DE04 1 A9 3E lda #$3E ; $DE04: A9 3E
|
|
00DE06 1 AC 6C 05 ldy $056C ; $DE06: AC 6C 05
|
|
00DE09 1 F0 0B beq ObjectRouting_UseFrame60
|
|
00DE0B 1 ; $DE09: F0 0B
|
|
00DE0B 1
|
|
00DE0B 1 A9 43 lda #$43 ; $DE0B: A9 43
|
|
00DE0D 1
|
|
00DE0D 1 88 dey ; $DE0D: 88
|
|
00DE0E 1 D0 06 bne ObjectRouting_UseFrame60
|
|
00DE10 1 ; $DE0E: D0 06
|
|
00DE10 1
|
|
00DE10 1 A9 41 lda #$41 ; $DE10: A9 41
|
|
00DE12 1 A0 5E ldy #$5E ; $DE12: A0 5E
|
|
00DE14 1 D0 02 bne ObjectRouting_SaveFrames
|
|
00DE16 1 ; $DE14: D0 02
|
|
00DE16 1
|
|
00DE16 1 ObjectRouting_UseFrame60: ; $DE16
|
|
00DE16 1 A0 60 ldy #$60 ; $DE16: A0 60
|
|
00DE18 1
|
|
00DE18 1 ObjectRouting_SaveFrames: ; $DE18
|
|
00DE18 1 E0 0C cpx #$0C ; $DE18: E0 0C
|
|
00DE1A 1 B0 03 bcs ObjectRouting_SaveMainFrame
|
|
00DE1C 1 ; $DE1A: B0 03
|
|
00DE1C 1
|
|
00DE1C 1 9D B0 03 sta $03B0,x ; $DE1C: 9D B0 03
|
|
00DE1F 1
|
|
00DE1F 1 ObjectRouting_SaveMainFrame: ; $DE1F
|
|
00DE1F 1 98 tya ; $DE1F: 98
|
|
00DE20 1 9D 9B 03 sta $039B,x ; $DE20: 9D 9B 03
|
|
00DE23 1
|
|
00DE23 1 ; ----------------------------------------------------------------------------
|
|
00DE23 1 ; Run the base-object merge/comparison helper.
|
|
00DE23 1 ;
|
|
00DE23 1 ; Failure returns a one-tick delay through the shared path at $DD4A.
|
|
00DE23 1 ; ----------------------------------------------------------------------------
|
|
00DE23 1
|
|
00DE23 1 A6 E1 ldx CurrentObjectIndex ; $DE23: A6 E1
|
|
00DE25 1 20 C0 C9 jsr TryMergeObjectIntoBase ; $DE25: 20 C0 C9
|
|
00DE28 1
|
|
00DE28 1 F0 05 beq ObjectRouting_MergeSucceeded
|
|
00DE2A 1 ; $DE28: F0 05
|
|
00DE2A 1
|
|
00DE2A 1 A9 01 lda #$01 ; $DE2A: A9 01
|
|
00DE2C 1 4C 4A DD jmp ContinueObjectProcessingWithDelay
|
|
00DE2F 1 ; $DE2C: 4C 4A DD
|
|
00DE2F 1
|
|
00DE2F 1 ; ----------------------------------------------------------------------------
|
|
00DE2F 1 ; Merge succeeded. Advance engine and motion state.
|
|
00DE2F 1 ; ----------------------------------------------------------------------------
|
|
00DE2F 1
|
|
00DE2F 1 ObjectRouting_MergeSucceeded: ; $DE2F
|
|
00DE2F 1 20 D3 E2 jsr ClearCurrentObjectMovement ; $DE2F: 20 D3 E2
|
|
00DE32 1 20 E6 E3 jsr InitializeBaseObjectFromCurrent ; $DE32: 20 E6 E3
|
|
00DE35 1
|
|
00DE35 1 E6 5E inc BaseMotionEventCount ; $DE35: E6 5E
|
|
00DE37 1
|
|
00DE37 1 A9 20 lda #$20 ; $DE37: A9 20
|
|
00DE39 1 85 FE sta PendingAudioFlags ; $DE39: 85 FE
|
|
00DE3B 1
|
|
00DE3B 1 A5 5D lda BaseMotionPhase ; $DE3B: A5 5D
|
|
00DE3D 1 D0 03 bne ObjectRouting_TestRegion
|
|
00DE3F 1 ; $DE3D: D0 03
|
|
00DE3F 1
|
|
00DE3F 1 20 5A E3 jsr ProcessCompactObjectState_FindAlternate ; $DE3F: 20 5A E3
|
|
00DE42 1
|
|
00DE42 1 ; ----------------------------------------------------------------------------
|
|
00DE42 1 ; Test the current object's region.
|
|
00DE42 1 ;
|
|
00DE42 1 ; Carry set routes to $DED8. Carry clear enters the engine path at $E037.
|
|
00DE42 1 ; ----------------------------------------------------------------------------
|
|
00DE42 1
|
|
00DE42 1 ObjectRouting_TestRegion: ; $DE42
|
|
00DE42 1 20 EA CB jsr TestCurrentObjectCollision ; $DE42: 20 EA CB
|
|
00DE45 1 90 03 bcc ObjectRouting_EnterEngine
|
|
00DE47 1 ; $DE45: 90 03
|
|
00DE47 1
|
|
00DE47 1 4C D8 DE jmp ObjectRouting_ReverseMovement ; $DE47: 4C D8 DE
|
|
00DE4A 1
|
|
00DE4A 1 ObjectRouting_EnterEngine: ; $DE4A
|
|
00DE4A 1 4C 37 E0 jmp ObjectStateDispatch ; $DE4A: 4C 37 E0
|
|
00DE4D 1
|
|
00DE4D 1 ; ----------------------------------------------------------------------------
|
|
00DE4D 1 ; CurrentObjectIndex differs from $A4.
|
|
00DE4D 1 ;
|
|
00DE4D 1 ; Run the helper at $DEEF and return a one-tick delay through the shared path.
|
|
00DE4D 1 ; ----------------------------------------------------------------------------
|
|
00DE4D 1
|
|
00DE4D 1 ObjectRouting_Alternate: ; $DE4D
|
|
00DE4D 1 20 EF DE jsr AssignCurrentObjectSlot ; $DE4D: 20 EF DE
|
|
00DE50 1
|
|
00DE50 1 A9 01 lda #$01 ; $DE50: A9 01
|
|
00DE52 1 4C 4A DD jmp ContinueObjectProcessingWithDelay
|
|
00DE55 1 ; $DE52: 4C 4A DD
|
|
00DE55 1
|
|
00DE55 1 ; ============================================================================
|
|
00DE55 1 ; $DE55-$DE83
|
|
00DE55 1 ; Handle base state $056C >= 3.
|
|
00DE55 1 ;
|
|
00DE55 1 ; The routine obtains a candidate value from $DF08 and chooses between a
|
|
00DE55 1 ; coordinate-based setup path and the candidate-state path at $DE84.
|
|
00DE55 1 ; ============================================================================
|
|
00DE55 1
|
|
00DE55 1 ObjectRouting_BaseStateAtLeast3: ; $DE55
|
|
00DE55 1 20 08 DF jsr TestCurrentObjectGeometry ; $DE55: 20 08 DF
|
|
00DE58 1
|
|
00DE58 1 C9 07 cmp #$07 ; $DE58: C9 07
|
|
00DE5A 1 90 28 bcc ObjectRouting_CandidateBelow7
|
|
00DE5C 1 ; $DE5A: 90 28
|
|
00DE5C 1 ; Target $DE84.
|
|
00DE5C 1
|
|
00DE5C 1 ; ----------------------------------------------------------------------------
|
|
00DE5C 1 ; Candidate is at least seven.
|
|
00DE5C 1 ;
|
|
00DE5C 1 ; For object offsets below $18, use the coordinate setup path directly.
|
|
00DE5C 1 ; For offsets at least $18, candidate values below $18 return to $DE84.
|
|
00DE5C 1 ; ----------------------------------------------------------------------------
|
|
00DE5C 1
|
|
00DE5C 1 A6 E1 ldx CurrentObjectIndex ; $DE5C: A6 E1
|
|
00DE5E 1 E0 18 cpx #$18 ; $DE5E: E0 18
|
|
00DE60 1 90 04 bcc ObjectRouting_SetupCoordinates
|
|
00DE62 1 ; $DE60: 90 04
|
|
00DE62 1
|
|
00DE62 1 C9 18 cmp #$18 ; $DE62: C9 18
|
|
00DE64 1 90 1E bcc ObjectRouting_CandidateBelow7
|
|
00DE66 1 ; $DE64: 90 1E
|
|
00DE66 1
|
|
00DE66 1 ; ----------------------------------------------------------------------------
|
|
00DE66 1 ; Build geometry/coordinate arguments.
|
|
00DE66 1 ;
|
|
00DE66 1 ; $B5 begins at zero. $DEFB adjusts or derives the geometry values and returns
|
|
00DE66 1 ; a value in A, which is saved in $B3.
|
|
00DE66 1 ; ----------------------------------------------------------------------------
|
|
00DE66 1
|
|
00DE66 1 ObjectRouting_SetupCoordinates: ; $DE66
|
|
00DE66 1 A9 00 lda #$00 ; $DE66: A9 00
|
|
00DE68 1 85 B5 sta $B5 ; $DE68: 85 B5
|
|
00DE6A 1
|
|
00DE6A 1 20 FB DE jsr SelectObjectGeometrySize ; $DE6A: 20 FB DE
|
|
00DE6D 1 85 B3 sta $B3 ; $DE6D: 85 B3
|
|
00DE6F 1
|
|
00DE6F 1 ; ----------------------------------------------------------------------------
|
|
00DE6F 1 ; If $A4 equals CurrentObjectIndex, clear $A4.
|
|
00DE6F 1 ; ----------------------------------------------------------------------------
|
|
00DE6F 1 ObjectRouting_LargeCandidate:
|
|
00DE6F 1 38 sec ; $DE6F: 38
|
|
00DE70 1
|
|
00DE70 1 A5 A4 lda $A4 ; $DE70: A5 A4
|
|
00DE72 1 E5 E1 sbc CurrentObjectIndex ; $DE72: E5 E1
|
|
00DE74 1 D0 02 bne ObjectRouting_ApplyCoordinateSetup
|
|
00DE76 1 ; $DE74: D0 02
|
|
00DE76 1
|
|
00DE76 1 85 A4 sta $A4 ; $DE76: 85 A4
|
|
00DE78 1 ; A is zero on equality.
|
|
00DE78 1
|
|
00DE78 1 ; ----------------------------------------------------------------------------
|
|
00DE78 1 ; Apply the geometry setup, select a delay, and continue through $DD4A.
|
|
00DE78 1 ; ----------------------------------------------------------------------------
|
|
00DE78 1
|
|
00DE78 1 ObjectRouting_ApplyCoordinateSetup: ; $DE78
|
|
00DE78 1 20 19 E5 jsr BuildGeometryVectorFromArguments ; $DE78: 20 19 E5
|
|
00DE7B 1 20 28 E5 jsr StoreCurrentObjectMovement ; $DE7B: 20 28 E5
|
|
00DE7E 1 20 DE E2 jsr UpdateCurrentObjectAnimationDelay ; $DE7E: 20 DE E2
|
|
00DE81 1
|
|
00DE81 1 4C 4A DD jmp ContinueObjectProcessingWithDelay
|
|
00DE84 1 ; $DE81: 4C 4A DD
|
|
00DE84 1
|
|
00DE84 1 ; ============================================================================
|
|
00DE84 1 ; $DE84-$DEC7
|
|
00DE84 1 ; Handle candidate values below the high-state routing threshold.
|
|
00DE84 1 ; ============================================================================
|
|
00DE84 1
|
|
00DE84 1 ObjectRouting_CandidateBelow7: ; $DE84
|
|
00DE84 1 C9 02 cmp #$02 ; $DE84: C9 02
|
|
00DE86 1 90 40 bcc ObjectRouting_CandidateBelow2
|
|
00DE88 1 ; $DE86: 90 40
|
|
00DE88 1 ; Target $DEC8.
|
|
00DE88 1
|
|
00DE88 1 ; ----------------------------------------------------------------------------
|
|
00DE88 1 ; Candidate is at least two.
|
|
00DE88 1 ;
|
|
00DE88 1 ; CurrentObjectIndex must match either $A4 or $A9. Otherwise, return to the
|
|
00DE88 1 ; alternate path at $DE4D.
|
|
00DE88 1 ; ----------------------------------------------------------------------------
|
|
00DE88 1
|
|
00DE88 1 A6 E1 ldx CurrentObjectIndex ; $DE88: A6 E1
|
|
00DE8A 1
|
|
00DE8A 1 E4 A4 cpx $A4 ; $DE8A: E4 A4
|
|
00DE8C 1 F0 04 beq ObjectRouting_SetCandidateAnimation
|
|
00DE8E 1 ; $DE8C: F0 04
|
|
00DE8E 1
|
|
00DE8E 1 E4 A9 cpx $A9 ; $DE8E: E4 A9
|
|
00DE90 1 D0 BB bne ObjectRouting_Alternate ; $DE90: D0 BB
|
|
00DE92 1
|
|
00DE92 1 ; ----------------------------------------------------------------------------
|
|
00DE92 1 ; Assign animation frame $5E and an attribute/state value of $41 or $42.
|
|
00DE92 1 ; ----------------------------------------------------------------------------
|
|
00DE92 1
|
|
00DE92 1 ObjectRouting_SetCandidateAnimation: ; $DE92
|
|
00DE92 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00DE95 1 ; $DE92: 20 68 DA
|
|
00DE95 1
|
|
00DE95 1 A9 5E lda #$5E ; $DE95: A9 5E
|
|
00DE97 1 9D 9B 03 sta $039B,x ; $DE97: 9D 9B 03
|
|
00DE9A 1
|
|
00DE9A 1 E0 0C cpx #$0C ; $DE9A: E0 0C
|
|
00DE9C 1 B0 0C bcs ObjectRouting_UpdateCandidate
|
|
00DE9E 1 ; $DE9C: B0 0C
|
|
00DE9E 1
|
|
00DE9E 1 A9 41 lda #$41 ; $DE9E: A9 41
|
|
00DEA0 1
|
|
00DEA0 1 DD B0 03 cmp $03B0,x ; $DEA0: DD B0 03
|
|
00DEA3 1 D0 02 bne ObjectRouting_SaveCandidateAttribute
|
|
00DEA5 1 ; $DEA3: D0 02
|
|
00DEA5 1
|
|
00DEA5 1 A9 42 lda #$42 ; $DEA5: A9 42
|
|
00DEA7 1
|
|
00DEA7 1 ObjectRouting_SaveCandidateAttribute: ; $DEA7
|
|
00DEA7 1 9D B0 03 sta $03B0,x ; $DEA7: 9D B0 03
|
|
00DEAA 1
|
|
00DEAA 1 ; ----------------------------------------------------------------------------
|
|
00DEAA 1 ; Update the current object and attempt the base-object merge.
|
|
00DEAA 1 ; ----------------------------------------------------------------------------
|
|
00DEAA 1
|
|
00DEAA 1 ObjectRouting_UpdateCandidate: ; $DEAA
|
|
00DEAA 1 A6 E1 ldx CurrentObjectIndex ; $DEAA: A6 E1
|
|
00DEAC 1 20 B7 E6 jsr ClearMovementTransforms ; $DEAC: 20 B7 E6
|
|
00DEAF 1
|
|
00DEAF 1 A6 E1 ldx CurrentObjectIndex ; $DEAF: A6 E1
|
|
00DEB1 1 20 C0 C9 jsr TryMergeObjectIntoBase ; $DEB1: 20 C0 C9
|
|
00DEB4 1
|
|
00DEB4 1 F0 1F beq ObjectRouting_MergeComplete
|
|
00DEB6 1 ; $DEB4: F0 1F
|
|
00DEB6 1 ; Target $DED5.
|
|
00DEB6 1
|
|
00DEB6 1 ; ----------------------------------------------------------------------------
|
|
00DEB6 1 ; Merge did not complete.
|
|
00DEB6 1 ;
|
|
00DEB6 1 ; Rebuild geometry arguments and return through the shared continuation.
|
|
00DEB6 1 ; ----------------------------------------------------------------------------
|
|
00DEB6 1
|
|
00DEB6 1 A9 00 lda #$00 ; $DEB6: A9 00
|
|
00DEB8 1 85 B5 sta $B5 ; $DEB8: 85 B5
|
|
00DEBA 1
|
|
00DEBA 1 20 FB DE jsr SelectObjectGeometrySize ; $DEBA: 20 FB DE
|
|
00DEBD 1 85 B3 sta $B3 ; $DEBD: 85 B3
|
|
00DEBF 1
|
|
00DEBF 1 20 19 E5 jsr BuildGeometryVectorFromArguments ; $DEBF: 20 19 E5
|
|
00DEC2 1 20 28 E5 jsr StoreCurrentObjectMovement ; $DEC2: 20 28 E5
|
|
00DEC5 1
|
|
00DEC5 1 4C 48 DD jmp ContinueObjectProcessing
|
|
00DEC8 1 ; $DEC5: 4C 48 DD
|
|
00DEC8 1
|
|
00DEC8 1 ; ============================================================================
|
|
00DEC8 1 ; $DEC8-$DED7
|
|
00DEC8 1 ; Candidate values zero or one.
|
|
00DEC8 1 ; ============================================================================
|
|
00DEC8 1
|
|
00DEC8 1 ObjectRouting_CandidateBelow2: ; $DEC8
|
|
00DEC8 1 20 D3 E2 jsr ClearCurrentObjectMovement ; $DEC8: 20 D3 E2
|
|
00DECB 1
|
|
00DECB 1 20 C0 C9 jsr TryMergeObjectIntoBase ; $DECB: 20 C0 C9
|
|
00DECE 1 F0 05 beq ObjectRouting_MergeComplete
|
|
00DED0 1 ; $DECE: F0 05
|
|
00DED0 1
|
|
00DED0 1 A9 01 lda #$01 ; $DED0: A9 01
|
|
00DED2 1 4C 4A DD jmp ContinueObjectProcessingWithDelay
|
|
00DED5 1 ; $DED2: 4C 4A DD
|
|
00DED5 1
|
|
00DED5 1 ; ----------------------------------------------------------------------------
|
|
00DED5 1 ; Merge completed. Re-enter the success path at $DE2F.
|
|
00DED5 1 ; ----------------------------------------------------------------------------
|
|
00DED5 1
|
|
00DED5 1 ObjectRouting_MergeComplete: ; $DED5
|
|
00DED5 1 4C 2F DE jmp ObjectRouting_MergeSucceeded
|
|
00DED8 1 ; $DED5: 4C 2F DE
|
|
00DED8 1
|
|
00DED8 1 ; ============================================================================
|
|
00DED8 1 ; $DED8-$DEEE
|
|
00DED8 1 ; Region/collision response path.
|
|
00DED8 1 ;
|
|
00DED8 1 ; Negate the current object's horizontal and vertical high movement values and
|
|
00DED8 1 ; store the results in $056D,X/$056E,X.
|
|
00DED8 1 ; ============================================================================
|
|
00DED8 1
|
|
00DED8 1 ObjectRouting_ReverseMovement: ; $DED8
|
|
00DED8 1 A6 E1 ldx CurrentObjectIndex ; $DED8: A6 E1
|
|
00DEDA 1
|
|
00DEDA 1 A9 00 lda #$00 ; $DEDA: A9 00
|
|
00DEDC 1 38 sec ; $DEDC: 38
|
|
00DEDD 1 FD 0A 05 sbc $050A,x ; $DEDD: FD 0A 05
|
|
00DEE0 1 9D 6D 05 sta $056D,x ; $DEE0: 9D 6D 05
|
|
00DEE3 1
|
|
00DEE3 1 A9 00 lda #$00 ; $DEE3: A9 00
|
|
00DEE5 1 38 sec ; $DEE5: 38
|
|
00DEE6 1 FD 3B 05 sbc $053B,x ; $DEE6: FD 3B 05
|
|
00DEE9 1 9D 6E 05 sta $056E,x ; $DEE9: 9D 6E 05
|
|
00DEEC 1
|
|
00DEEC 1 4C 48 DD jmp ContinueObjectProcessing
|
|
00DEEF 1 ; $DEEC: 4C 48 DD
|
|
00DEEF 1
|
|
00DEEF 1 ; ============================================================================
|
|
00DEEF 1 ; $DEEF-$DEFA
|
|
00DEEF 1 ; Assign CurrentObjectIndex to the active or saved object slot.
|
|
00DEEF 1 ;
|
|
00DEEF 1 ; If $A4 is zero:
|
|
00DEEF 1 ; Store CurrentObjectIndex in $A4.
|
|
00DEEF 1 ;
|
|
00DEEF 1 ; If $A4 is nonzero:
|
|
00DEEF 1 ; Store CurrentObjectIndex in $A9.
|
|
00DEEF 1 ;
|
|
00DEEF 1 ; Return:
|
|
00DEEF 1 ; X = CurrentObjectIndex
|
|
00DEEF 1 ; ============================================================================
|
|
00DEEF 1
|
|
00DEEF 1 ; ----------------------------------------------------------------------------
|
|
00DEEF 1 ; Contract:
|
|
00DEEF 1 ; Description: Implements Assign Current Object Slot.
|
|
00DEEF 1 ; Entry: Registers: X; Memory: currentobjectindex, $a4
|
|
00DEEF 1 ; Returns/products: Registers/clobbers: A, X
|
|
00DEEF 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DEEF 1 ; Memory effects: $a4
|
|
00DEEF 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DEEF 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DEEF 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00DEEF 1 ; ----------------------------------------------------------------------------
|
|
00DEEF 1 AssignCurrentObjectSlot: ; $DEEF
|
|
00DEEF 1 A6 E1 ldx CurrentObjectIndex ; $DEEF: A6 E1
|
|
00DEF1 1
|
|
00DEF1 1 A5 A4 lda $A4 ; $DEF1: A5 A4
|
|
00DEF3 1 D0 03 bne AssignCurrentObjectToSavedSlot
|
|
00DEF5 1 ; $DEF3: D0 03
|
|
00DEF5 1
|
|
00DEF5 1 ; ----------------------------------------------------------------------------
|
|
00DEF5 1 ; No active object is assigned. Store the current object in the primary slot.
|
|
00DEF5 1 ; ----------------------------------------------------------------------------
|
|
00DEF5 1
|
|
00DEF5 1 86 A4 stx $A4 ; $DEF5: 86 A4
|
|
00DEF7 1 60 rts ; $DEF7: 60
|
|
00DEF8 1
|
|
00DEF8 1 ; ----------------------------------------------------------------------------
|
|
00DEF8 1 ; The primary slot is occupied. Store the current object in the saved slot.
|
|
00DEF8 1 ; ----------------------------------------------------------------------------
|
|
00DEF8 1
|
|
00DEF8 1 AssignCurrentObjectToSavedSlot: ; $DEF8
|
|
00DEF8 1 86 A9 stx $A9 ; $DEF8: 86 A9
|
|
00DEFA 1 60 rts ; $DEFA: 60
|
|
00DEFB 1
|
|
00DEFB 1 ; ============================================================================
|
|
00DEFB 1 ; $DEFB-$DF07
|
|
00DEFB 1 ; Select a geometry or object-size parameter from CurrentObjectIndex.
|
|
00DEFB 1 ;
|
|
00DEFB 1 ; Return:
|
|
00DEFB 1 ; A = selected parameter
|
|
00DEFB 1 ; $C6 = selected parameter
|
|
00DEFB 1 ;
|
|
00DEFB 1 ; CurrentObjectIndex below $18:
|
|
00DEFB 1 ; parameter = $08
|
|
00DEFB 1 ;
|
|
00DEFB 1 ; CurrentObjectIndex at least $18:
|
|
00DEFB 1 ; parameter = $03
|
|
00DEFB 1 ; ============================================================================
|
|
00DEFB 1
|
|
00DEFB 1 ; ----------------------------------------------------------------------------
|
|
00DEFB 1 ; Contract:
|
|
00DEFB 1 ; Description: Implements Select Object Geometry Size.
|
|
00DEFB 1 ; Entry: Registers: A, X; Memory: currentobjectindex
|
|
00DEFB 1 ; Returns/products: Registers/clobbers: A, X
|
|
00DEFB 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DEFB 1 ; Memory effects: $c6
|
|
00DEFB 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DEFB 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DEFB 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00DEFB 1 ; ----------------------------------------------------------------------------
|
|
00DEFB 1 SelectObjectGeometrySize: ; $DEFB
|
|
00DEFB 1 A6 E1 ldx CurrentObjectIndex ; $DEFB: A6 E1
|
|
00DEFD 1
|
|
00DEFD 1 A9 03 lda #$03 ; $DEFD: A9 03
|
|
00DEFF 1
|
|
00DEFF 1 E0 18 cpx #$18 ; $DEFF: E0 18
|
|
00DF01 1 B0 02 bcs SelectObjectGeometrySize_Save
|
|
00DF03 1 ; $DF01: B0 02
|
|
00DF03 1
|
|
00DF03 1 A9 08 lda #$08 ; $DF03: A9 08
|
|
00DF05 1
|
|
00DF05 1 SelectObjectGeometrySize_Save: ; $DF05
|
|
00DF05 1 85 C6 sta $C6 ; $DF05: 85 C6
|
|
00DF07 1 60 rts ; $DF07: 60
|
|
00DF08 1
|
|
00DF08 1 ; ============================================================================
|
|
00DF08 1 ; $DF08-$DF11
|
|
00DF08 1 ; Configure geometry arguments for the current object and run the region test.
|
|
00DF08 1 ;
|
|
00DF08 1 ; Return:
|
|
00DF08 1 ; A and processor flags are returned directly from $E502.
|
|
00DF08 1 ;
|
|
00DF08 1 ; Call sequence:
|
|
00DF08 1 ; $DF12 Select and copy the relevant object coordinates into $B2-$B5.
|
|
00DF08 1 ; $E4DB Process or normalize the geometry arguments.
|
|
00DF08 1 ; $E502 Perform the final geometry/region test.
|
|
00DF08 1 ; ============================================================================
|
|
00DF08 1
|
|
00DF08 1 ; ----------------------------------------------------------------------------
|
|
00DF08 1 ; Contract:
|
|
00DF08 1 ; Description: Implements Test Current Object Geometry.
|
|
00DF08 1 ; Entry: No register input inferred
|
|
00DF08 1 ; Returns/products: No direct product inferred
|
|
00DF08 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DF08 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00DF08 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DF08 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DF08 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00DF08 1 ; ----------------------------------------------------------------------------
|
|
00DF08 1 TestCurrentObjectGeometry: ; $DF08
|
|
00DF08 1 20 12 DF jsr SetupCurrentObjectGeometry
|
|
00DF0B 1 ; $DF08: 20 12 DF
|
|
00DF0B 1
|
|
00DF0B 1 20 DB E4 jsr CalculateCurrentGeometryDifference ; $DF0B: 20 DB E4
|
|
00DF0E 1 20 02 E5 jsr EvaluateGeometryDifference ; $DF0E: 20 02 E5
|
|
00DF11 1
|
|
00DF11 1 60 rts ; $DF11: 60
|
|
00DF12 1
|
|
00DF12 1 ; ============================================================================
|
|
00DF12 1 ; $DF12-$DF26
|
|
00DF12 1 ; Copy saved base coordinates into the geometry argument structure.
|
|
00DF12 1 ;
|
|
00DF12 1 ; The original ROM deliberately uses absolute addressing for zero-page
|
|
00DF12 1 ; locations $53-$56. Raw bytes are used here to prevent CA65 from shortening
|
|
00DF12 1 ; these instructions to zero-page addressing.
|
|
00DF12 1 ; ============================================================================
|
|
00DF12 1
|
|
00DF12 1 SetupCurrentObjectGeometry: ; $DF12
|
|
00DF12 1 AD 53 00 .byte $AD,$53,$00 ; $DF12: LDA $0053
|
|
00DF15 1 85 B2 sta $B2 ; $DF15: 85 B2
|
|
00DF17 1
|
|
00DF17 1 AD 54 00 .byte $AD,$54,$00 ; $DF17: LDA $0054
|
|
00DF1A 1 85 B3 sta $B3 ; $DF1A: 85 B3
|
|
00DF1C 1
|
|
00DF1C 1 AD 55 00 .byte $AD,$55,$00 ; $DF1C: LDA $0055
|
|
00DF1F 1 85 B4 sta $B4 ; $DF1F: 85 B4
|
|
00DF21 1
|
|
00DF21 1 AD 56 00 .byte $AD,$56,$00 ; $DF21: LDA $0056
|
|
00DF24 1 85 B5 sta $B5 ; $DF24: 85 B5
|
|
00DF26 1
|
|
00DF26 1 60 rts ; $DF26: 60
|
|
00DF27 1
|
|
00DF27 1 ; ============================================================================
|
|
00DF27 1 ; $DF27-$DF3B
|
|
00DF27 1 ; Copy the base object's live coordinates into the geometry arguments.
|
|
00DF27 1 ;
|
|
00DF27 1 ; Source:
|
|
00DF27 1 ; $0509/$050A = base horizontal coordinate
|
|
00DF27 1 ; $053A/$053B = base vertical coordinate
|
|
00DF27 1 ;
|
|
00DF27 1 ; Destination:
|
|
00DF27 1 ; $B2/$B3 = geometry horizontal coordinate
|
|
00DF27 1 ; $B4/$B5 = geometry vertical coordinate
|
|
00DF27 1 ; ============================================================================
|
|
00DF27 1
|
|
00DF27 1 ; ----------------------------------------------------------------------------
|
|
00DF27 1 ; Contract:
|
|
00DF27 1 ; Description: Implements Setup Base Object Geometry.
|
|
00DF27 1 ; Entry: Registers: A; Memory: $0509, $050a, $053a, $053b
|
|
00DF27 1 ; Returns/products: Registers/clobbers: A
|
|
00DF27 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DF27 1 ; Memory effects: $b2, $b3, $b4, $b5
|
|
00DF27 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DF27 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DF27 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00DF27 1 ; ----------------------------------------------------------------------------
|
|
00DF27 1 SetupBaseObjectGeometry: ; $DF27
|
|
00DF27 1 AD 09 05 lda $0509 ; $DF27: AD 09 05
|
|
00DF2A 1 85 B2 sta $B2 ; $DF2A: 85 B2
|
|
00DF2C 1
|
|
00DF2C 1 AD 0A 05 lda $050A ; $DF2C: AD 0A 05
|
|
00DF2F 1 85 B3 sta $B3 ; $DF2F: 85 B3
|
|
00DF31 1
|
|
00DF31 1 AD 3A 05 lda $053A ; $DF31: AD 3A 05
|
|
00DF34 1 85 B4 sta $B4 ; $DF34: 85 B4
|
|
00DF36 1
|
|
00DF36 1 AD 3B 05 lda $053B ; $DF36: AD 3B 05
|
|
00DF39 1 85 B5 sta $B5 ; $DF39: 85 B5
|
|
00DF3B 1
|
|
00DF3B 1 60 rts ; $DF3B: 60
|
|
00DF3C 1
|
|
00DF3C 1 ; ============================================================================
|
|
00DF3C 1 ; $DF3C-$DF44
|
|
00DF3C 1 ; Prepare geometry using the base object's live coordinates, process the
|
|
00DF3C 1 ; geometry arguments, and return the resulting high coordinate in X.
|
|
00DF3C 1 ;
|
|
00DF3C 1 ; Return:
|
|
00DF3C 1 ; X = $AF
|
|
00DF3C 1 ;
|
|
00DF3C 1 ; A and Y retain whatever values were left by $E4DB.
|
|
00DF3C 1 ; Processor flags reflect LDX $AF.
|
|
00DF3C 1 ; ============================================================================
|
|
00DF3C 1
|
|
00DF3C 1 PrepareBaseObjectGeometry: ; $DF3C
|
|
00DF3C 1 20 27 DF jsr SetupBaseObjectGeometry ; $DF3C: 20 27 DF
|
|
00DF3F 1 20 DB E4 jsr CalculateCurrentGeometryDifference ; $DF3F: 20 DB E4
|
|
00DF42 1
|
|
00DF42 1 A6 AF ldx CalculatedCoordinateHigh ; $DF42: A6 AF
|
|
00DF44 1 60 rts ; $DF44: 60
|
|
00DF45 1
|
|
00DF45 1 ; ============================================================================
|
|
00DF45 1 ; $DF45-$DF91
|
|
00DF45 1 ; Calculate geometry and movement arguments for the current object.
|
|
00DF45 1 ;
|
|
00DF45 1 ; This routine:
|
|
00DF45 1 ; 1. Selects an object-size parameter in $C6.
|
|
00DF45 1 ; 2. Prepares the base object's geometry.
|
|
00DF45 1 ; 3. Saves a geometry result in $D4/$D5.
|
|
00DF45 1 ; 4. Copies base movement values into $D6/$D7.
|
|
00DF45 1 ; 5. Calls the signed-vector helper at $E877.
|
|
00DF45 1 ; 6. Selects and installs final geometry arguments.
|
|
00DF45 1 ; 7. Tail-calls the geometry-processing helper at $E502.
|
|
00DF45 1 ; ============================================================================
|
|
00DF45 1
|
|
00DF45 1 ; ----------------------------------------------------------------------------
|
|
00DF45 1 ; Contract:
|
|
00DF45 1 ; Description: Calculates Current Object Geometry.
|
|
00DF45 1 ; Entry: Registers: A, X, Y; Memory: $0508, $0539, $c6, $d4
|
|
00DF45 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00DF45 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DF45 1 ; Memory effects: $d4, $d5, $d6, $d7, $b5, $b3
|
|
00DF45 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DF45 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DF45 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00DF45 1 ; ----------------------------------------------------------------------------
|
|
00DF45 1 CalculateCurrentObjectGeometry: ; $DF45
|
|
00DF45 1 20 FB DE jsr SelectObjectGeometrySize
|
|
00DF48 1 ; $DF45: 20 FB DE
|
|
00DF48 1
|
|
00DF48 1 20 3C DF jsr PrepareBaseObjectGeometry
|
|
00DF4B 1 ; $DF48: 20 3C DF
|
|
00DF4B 1
|
|
00DF4B 1 ; ----------------------------------------------------------------------------
|
|
00DF4B 1 ; Save the geometry result.
|
|
00DF4B 1 ;
|
|
00DF4B 1 ; PrepareBaseObjectGeometry returns:
|
|
00DF4B 1 ; X = geometry high/result byte from $AF
|
|
00DF4B 1 ; A = result left by $E4DB
|
|
00DF4B 1 ; ----------------------------------------------------------------------------
|
|
00DF4B 1
|
|
00DF4B 1 86 D4 stx $D4 ; $DF4B: 86 D4
|
|
00DF4D 1 85 D5 sta $D5 ; $DF4D: 85 D5
|
|
00DF4F 1
|
|
00DF4F 1 ; ----------------------------------------------------------------------------
|
|
00DF4F 1 ; Save the base movement values.
|
|
00DF4F 1 ; ----------------------------------------------------------------------------
|
|
00DF4F 1
|
|
00DF4F 1 AE 08 05 ldx $0508 ; $DF4F: AE 08 05
|
|
00DF52 1 86 D6 stx $D6 ; $DF52: 86 D6
|
|
00DF54 1
|
|
00DF54 1 AC 39 05 ldy $0539 ; $DF54: AC 39 05
|
|
00DF57 1 84 D7 sty $D7 ; $DF57: 84 D7
|
|
00DF59 1
|
|
00DF59 1 ; ----------------------------------------------------------------------------
|
|
00DF59 1 ; Run the signed-vector helper.
|
|
00DF59 1 ;
|
|
00DF59 1 ; The helper returns a signed result in A/Y. A is copied to X so its sign can
|
|
00DF59 1 ; select the next path.
|
|
00DF59 1 ; ----------------------------------------------------------------------------
|
|
00DF59 1
|
|
00DF59 1 20 77 E8 jsr NormalizeSignedVector ; $DF59: 20 77 E8
|
|
00DF5C 1
|
|
00DF5C 1 AA tax ; $DF5C: AA
|
|
00DF5D 1 10 1B bpl CalculateCurrentObjectGeometry_Nonnegative
|
|
00DF5F 1 ; $DF5D: 10 1B
|
|
00DF5F 1
|
|
00DF5F 1 ; ----------------------------------------------------------------------------
|
|
00DF5F 1 ; Negative-result path.
|
|
00DF5F 1 ;
|
|
00DF5F 1 ; Convert Y to its magnitude when negative, then compare it with the selected
|
|
00DF5F 1 ; object-size parameter at $C6.
|
|
00DF5F 1 ; ----------------------------------------------------------------------------
|
|
00DF5F 1
|
|
00DF5F 1 98 tya ; $DF5F: 98
|
|
00DF60 1 10 05 bpl CalculateCurrentObjectGeometry_CompareMagnitude
|
|
00DF62 1 ; $DF60: 10 05
|
|
00DF62 1
|
|
00DF62 1 49 FF eor #$FF ; $DF62: 49 FF
|
|
00DF64 1 38 sec ; $DF64: 38
|
|
00DF65 1 69 00 adc #$00 ; $DF65: 69 00
|
|
00DF67 1 ; With carry set, forms two's-complement
|
|
00DF67 1 ; magnitude: (~A) + 1.
|
|
00DF67 1
|
|
00DF67 1 CalculateCurrentObjectGeometry_CompareMagnitude: ; $DF67
|
|
00DF67 1 C5 C6 cmp $C6 ; $DF67: C5 C6
|
|
00DF69 1 B0 15 bcs CalculateCurrentObjectGeometry_Clamp
|
|
00DF6B 1 ; $DF69: B0 15
|
|
00DF6B 1
|
|
00DF6B 1 ; ----------------------------------------------------------------------------
|
|
00DF6B 1 ; Magnitude is below the selected object size.
|
|
00DF6B 1 ;
|
|
00DF6B 1 ; Use:
|
|
00DF6B 1 ; X = $C6
|
|
00DF6B 1 ; $B5 = Y
|
|
00DF6B 1 ; $B3 = $D4
|
|
00DF6B 1 ;
|
|
00DF6B 1 ; Then enter the geometry helper at $E502.
|
|
00DF6B 1 ; ----------------------------------------------------------------------------
|
|
00DF6B 1
|
|
00DF6B 1 A6 C6 ldx $C6 ; $DF6B: A6 C6
|
|
00DF6D 1
|
|
00DF6D 1 98 tya ; $DF6D: 98
|
|
00DF6E 1 85 B5 sta $B5 ; $DF6E: 85 B5
|
|
00DF70 1
|
|
00DF70 1 20 A5 E8 jsr RunEightRoundTransform ; $DF70: 20 A5 E8
|
|
00DF73 1
|
|
00DF73 1 A5 D4 lda $D4 ; $DF73: A5 D4
|
|
00DF75 1 85 B3 sta $B3 ; $DF75: 85 B3
|
|
00DF77 1
|
|
00DF77 1 CalculateCurrentObjectGeometry_RunTest: ; $DF77
|
|
00DF77 1 4C 02 E5 jmp EvaluateGeometryDifference ; $DF77: 4C 02 E5
|
|
00DF7A 1
|
|
00DF7A 1 ; ----------------------------------------------------------------------------
|
|
00DF7A 1 ; Nonnegative-result path.
|
|
00DF7A 1 ;
|
|
00DF7A 1 ; Initialize X from the selected object-size parameter and A to zero.
|
|
00DF7A 1 ; The unconditional BEQ continues at the shared argument-store path.
|
|
00DF7A 1 ; ----------------------------------------------------------------------------
|
|
00DF7A 1
|
|
00DF7A 1 CalculateCurrentObjectGeometry_Nonnegative: ; $DF7A
|
|
00DF7A 1 A6 C6 ldx $C6 ; $DF7A: A6 C6
|
|
00DF7C 1
|
|
00DF7C 1 A9 00 lda #$00 ; $DF7C: A9 00
|
|
00DF7E 1 F0 0C beq CalculateCurrentObjectGeometry_SaveArguments
|
|
00DF80 1 ; $DF7E: F0 0C
|
|
00DF80 1
|
|
00DF80 1 ; ----------------------------------------------------------------------------
|
|
00DF80 1 ; Clamp or normalize the selected object-size value.
|
|
00DF80 1 ;
|
|
00DF80 1 ; If Y is at least $80, invert $C6 and add the incoming carry.
|
|
00DF80 1 ; X is cleared before storing the resulting arguments.
|
|
00DF80 1 ; ----------------------------------------------------------------------------
|
|
00DF80 1
|
|
00DF80 1 CalculateCurrentObjectGeometry_Clamp: ; $DF80
|
|
00DF80 1 A5 C6 lda $C6 ; $DF80: A5 C6
|
|
00DF82 1
|
|
00DF82 1 C0 80 cpy #$80 ; $DF82: C0 80
|
|
00DF84 1 90 04 bcc CalculateCurrentObjectGeometry_ClearX
|
|
00DF86 1 ; $DF84: 90 04
|
|
00DF86 1
|
|
00DF86 1 49 FF eor #$FF ; $DF86: 49 FF
|
|
00DF88 1 69 00 adc #$00 ; $DF88: 69 00
|
|
00DF8A 1
|
|
00DF8A 1 CalculateCurrentObjectGeometry_ClearX: ; $DF8A
|
|
00DF8A 1 A2 00 ldx #$00 ; $DF8A: A2 00
|
|
00DF8C 1
|
|
00DF8C 1 CalculateCurrentObjectGeometry_SaveArguments: ; $DF8C
|
|
00DF8C 1 85 B5 sta $B5 ; $DF8C: 85 B5
|
|
00DF8E 1 86 B3 stx $B3 ; $DF8E: 86 B3
|
|
00DF90 1
|
|
00DF90 1 F0 E5 beq CalculateCurrentObjectGeometry_RunTest
|
|
00DF92 1 ; $DF90: F0 E5
|
|
00DF92 1 ; Branches to $DF77 when the stored A value
|
|
00DF92 1 ; is zero.
|
|
00DF92 1
|
|
00DF92 1 ; ============================================================================
|
|
00DF92 1 ; $DF92-$DFA6
|
|
00DF92 1 ; Transform X and Y independently, then add their two-byte results.
|
|
00DF92 1 ;
|
|
00DF92 1 ; Entry:
|
|
00DF92 1 ; X = first signed input
|
|
00DF92 1 ; Y = second signed input
|
|
00DF92 1 ;
|
|
00DF92 1 ; Exit:
|
|
00DF92 1 ; A/Y = combined two-byte result
|
|
00DF92 1 ;
|
|
00DF92 1 ; The helper at $DFA7 returns:
|
|
00DF92 1 ; A = low/result byte
|
|
00DF92 1 ; X = high/result byte
|
|
00DF92 1 ; ============================================================================
|
|
00DF92 1
|
|
00DF92 1 AddTransformedSignedValues: ; $DF92
|
|
00DF92 1 8A txa ; $DF92: 8A
|
|
00DF93 1 20 A7 DF jsr TransformSignedValue ; $DF93: 20 A7 DF
|
|
00DF96 1
|
|
00DF96 1 86 06 stx $06 ; $DF96: 86 06
|
|
00DF98 1 85 05 sta MathTemp05 ; $DF98: 85 05
|
|
00DF9A 1
|
|
00DF9A 1 98 tya ; $DF9A: 98
|
|
00DF9B 1 20 A7 DF jsr TransformSignedValue ; $DF9B: 20 A7 DF
|
|
00DF9E 1
|
|
00DF9E 1 ; ----------------------------------------------------------------------------
|
|
00DF9E 1 ; Add the two transformed results:
|
|
00DF9E 1 ;
|
|
00DF9E 1 ; second high + first high -> Y
|
|
00DF9E 1 ; second low + first low -> A
|
|
00DF9E 1 ; ----------------------------------------------------------------------------
|
|
00DF9E 1
|
|
00DF9E 1 48 pha ; $DF9E: 48
|
|
00DF9F 1
|
|
00DF9F 1 8A txa ; $DF9F: 8A
|
|
00DFA0 1 65 06 adc $06 ; $DFA0: 65 06
|
|
00DFA2 1 A8 tay ; $DFA2: A8
|
|
00DFA3 1
|
|
00DFA3 1 68 pla ; $DFA3: 68
|
|
00DFA4 1 65 05 adc MathTemp05 ; $DFA4: 65 05
|
|
00DFA6 1
|
|
00DFA6 1 60 rts ; $DFA6: 60
|
|
00DFA7 1
|
|
00DFA7 1 ; ============================================================================
|
|
00DFA7 1 ; $DFA7-$DFC3
|
|
00DFA7 1 ; Convert a signed byte to its magnitude, then perform an eight-step
|
|
00DFA7 1 ; shift-and-add transformation.
|
|
00DFA7 1 ;
|
|
00DFA7 1 ; Entry:
|
|
00DFA7 1 ; A = signed input byte
|
|
00DFA7 1 ;
|
|
00DFA7 1 ; Exit:
|
|
00DFA7 1 ; A = transformed low byte
|
|
00DFA7 1 ; X = transformed high/working byte from $28
|
|
00DFA7 1 ;
|
|
00DFA7 1 ; Working values:
|
|
00DFA7 1 ; $28 = shifting multiplier/result byte
|
|
00DFA7 1 ; $2B = absolute input value
|
|
00DFA7 1 ; ============================================================================
|
|
00DFA7 1
|
|
00DFA7 1 ; ----------------------------------------------------------------------------
|
|
00DFA7 1 ; Contract:
|
|
00DFA7 1 ; Description: Implements Transform Signed Value.
|
|
00DFA7 1 ; Entry: Registers: A, X; Memory: $2b, $28
|
|
00DFA7 1 ; Returns/products: Registers/clobbers: A, X
|
|
00DFA7 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DFA7 1 ; Memory effects: $28, $2b
|
|
00DFA7 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DFA7 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DFA7 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00DFA7 1 ; ----------------------------------------------------------------------------
|
|
00DFA7 1 TransformSignedValue: ; $DFA7
|
|
00DFA7 1 10 05 bpl TransformSignedValue_HaveMagnitude
|
|
00DFA9 1 ; $DFA7: 10 05
|
|
00DFA9 1
|
|
00DFA9 1 49 FF eor #$FF ; $DFA9: 49 FF
|
|
00DFAB 1 18 clc ; $DFAB: 18
|
|
00DFAC 1 69 01 adc #$01 ; $DFAC: 69 01
|
|
00DFAE 1
|
|
00DFAE 1 TransformSignedValue_HaveMagnitude: ; $DFAE
|
|
00DFAE 1 85 28 sta $28 ; $DFAE: 85 28
|
|
00DFB0 1 85 2B sta $2B ; $DFB0: 85 2B
|
|
00DFB2 1
|
|
00DFB2 1 A9 00 lda #$00 ; $DFB2: A9 00
|
|
00DFB4 1 A2 07 ldx #$07 ; $DFB4: A2 07
|
|
00DFB6 1
|
|
00DFB6 1 ; ----------------------------------------------------------------------------
|
|
00DFB6 1 ; Repeatedly shift $28 right through A.
|
|
00DFB6 1 ;
|
|
00DFB6 1 ; Whenever carry is set, add the original magnitude from $2B.
|
|
00DFB6 1 ; ----------------------------------------------------------------------------
|
|
00DFB6 1
|
|
00DFB6 1 TransformSignedValue_Loop: ; $DFB6
|
|
00DFB6 1 4A lsr ; $DFB6: 4A
|
|
00DFB7 1 66 28 ror $28 ; $DFB7: 66 28
|
|
00DFB9 1
|
|
00DFB9 1 90 03 bcc TransformSignedValue_Next
|
|
00DFBB 1 ; $DFB9: 90 03
|
|
00DFBB 1
|
|
00DFBB 1 18 clc ; $DFBB: 18
|
|
00DFBC 1 65 2B adc $2B ; $DFBC: 65 2B
|
|
00DFBE 1
|
|
00DFBE 1 TransformSignedValue_Next: ; $DFBE
|
|
00DFBE 1 CA dex ; $DFBE: CA
|
|
00DFBF 1 D0 F5 bne TransformSignedValue_Loop
|
|
00DFC1 1 ; $DFBF: D0 F5
|
|
00DFC1 1
|
|
00DFC1 1 A6 28 ldx $28 ; $DFC1: A6 28
|
|
00DFC3 1 60 rts ; $DFC3: 60
|
|
00DFC4 1
|
|
00DFC4 1 ; ============================================================================
|
|
00DFC4 1 ; $DFC4-$DFD3
|
|
00DFC4 1 ; Signed coordinate-offset table.
|
|
00DFC4 1 ;
|
|
00DFC4 1 ; Eight two-byte entries are present. Interpreted as little-endian signed
|
|
00DFC4 1 ; 16-bit values:
|
|
00DFC4 1 ;
|
|
00DFC4 1 ; $F800, $0800, $F800, $0000,
|
|
00DFC4 1 ; $00F9, $0007, $00F9, $FE00
|
|
00DFC4 1 ;
|
|
00DFC4 1 ; Several later routines index this region through nearby or overlapping base
|
|
00DFC4 1 ; addresses, so preserving the raw byte layout is safest.
|
|
00DFC4 1 ; ============================================================================
|
|
00DFC4 1
|
|
00DFC4 1 SignedCoordinateOffsetTable: ; $DFC4
|
|
00DFC4 1 00 F8 .byte $00,$F8 ; $F800
|
|
00DFC6 1 00 08 .byte $00,$08 ; $0800
|
|
00DFC8 1 00 F8 .byte $00,$F8 ; $F800
|
|
00DFCA 1 00 00 .byte $00,$00 ; $0000
|
|
00DFCC 1 F9 00 .byte $F9,$00 ; $00F9
|
|
00DFCE 1 07 00 .byte $07,$00 ; $0007
|
|
00DFD0 1 F9 00 .byte $F9,$00 ; $00F9
|
|
00DFD2 1 00 FE .byte $00,$FE ; $FE00
|
|
00DFD4 1
|
|
00DFD4 1 ; ============================================================================
|
|
00DFD4 1 ; $DFD4-$DFEA
|
|
00DFD4 1 ; Update the current object's animation values from the selector returned by
|
|
00DFD4 1 ; GetCurrentObjectSelectorAndState.
|
|
00DFD4 1 ;
|
|
00DFD4 1 ; The selector returned in X chooses an attribute from the four-byte table
|
|
00DFD4 1 ; immediately following the routine.
|
|
00DFD4 1 ; ============================================================================
|
|
00DFD4 1
|
|
00DFD4 1 ; ----------------------------------------------------------------------------
|
|
00DFD4 1 ; Contract:
|
|
00DFD4 1 ; Description: Updates Current Object Display State.
|
|
00DFD4 1 ; Entry: Registers: A, X; Memory: $dfea, currentobjectindex
|
|
00DFD4 1 ; Returns/products: Registers/clobbers: A, X
|
|
00DFD4 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00DFD4 1 ; Memory effects: $03b0, $039b
|
|
00DFD4 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00DFD4 1 ; comparison, load, or store path and are not a stable API product.
|
|
00DFD4 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00DFD4 1 ; ----------------------------------------------------------------------------
|
|
00DFD4 1 UpdateCurrentObjectDisplayState: ; $DFD4
|
|
00DFD4 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $DFD4: 20 DC E3
|
|
00DFD7 1
|
|
00DFD7 1 ; ----------------------------------------------------------------------------
|
|
00DFD7 1 ; Convert the returned object/event offset into a compact sprite-array index.
|
|
00DFD7 1 ; ----------------------------------------------------------------------------
|
|
00DFD7 1
|
|
00DFD7 1 8A txa ; $DFD7: 8A
|
|
00DFD8 1 4A lsr ; $DFD8: 4A
|
|
00DFD9 1 AA tax ; $DFD9: AA
|
|
00DFDA 1
|
|
00DFDA 1 ; ----------------------------------------------------------------------------
|
|
00DFDA 1 ; Load the selector-dependent animation attribute.
|
|
00DFDA 1 ;
|
|
00DFDA 1 ; Y is returned by GetCurrentObjectSelectorAndState and selects one of the table entries at $DFEB.
|
|
00DFDA 1 ; ----------------------------------------------------------------------------
|
|
00DFDA 1
|
|
00DFDA 1 B9 EA DF lda $DFEA,y ; $DFDA: B9 EA DF
|
|
00DFDD 1 ; Original indexed base is $DFEA, one byte
|
|
00DFDD 1 ; before the visible table.
|
|
00DFDD 1
|
|
00DFDD 1 9D B0 03 sta $03B0,x ; $DFDD: 9D B0 03
|
|
00DFE0 1
|
|
00DFE0 1 A9 5A lda #$5A ; $DFE0: A9 5A
|
|
00DFE2 1 9D 9B 03 sta $039B,x ; $DFE2: 9D 9B 03
|
|
00DFE5 1
|
|
00DFE5 1 ; ----------------------------------------------------------------------------
|
|
00DFE5 1 ; Update the current object and return.
|
|
00DFE5 1 ; ----------------------------------------------------------------------------
|
|
00DFE5 1
|
|
00DFE5 1 A6 E1 ldx CurrentObjectIndex ; $DFE5: A6 E1
|
|
00DFE7 1 20 B7 E6 jsr ClearMovementTransforms ; $DFE7: 20 B7 E6
|
|
00DFEA 1
|
|
00DFEA 1 60 rts ; $DFEA: 60
|
|
00DFEB 1
|
|
00DFEB 1 ; ============================================================================
|
|
00DFEB 1 ; $DFEB-$DFEE
|
|
00DFEB 1 ; Object-display attribute table.
|
|
00DFEB 1 ;
|
|
00DFEB 1 ; The load at $DFDA intentionally uses base $DFEA. Expected Y values are
|
|
00DFEB 1 ; therefore $01-$04:
|
|
00DFEB 1 ;
|
|
00DFEB 1 ; Y=$01 -> $DFEB
|
|
00DFEB 1 ; Y=$02 -> $DFEC
|
|
00DFEB 1 ; Y=$03 -> $DFED
|
|
00DFEB 1 ; Y=$04 -> $DFEE
|
|
00DFEB 1 ; ============================================================================
|
|
00DFEB 1
|
|
00DFEB 1 ObjectDisplayAttributeTable: ; $DFEB
|
|
00DFEB 1 2A 3D 3D 13 .byte $2A,$3D,$3D,$13
|
|
00DFEF 1
|
|
00DFEF 1 ; ============================================================================
|
|
00DFEF 1 ; $DFEF-$E01C
|
|
00DFEF 1 ; Assign a state value to the current object, perform a geometry test, and
|
|
00DFEF 1 ; either restart the test or finish the object transition.
|
|
00DFEF 1 ;
|
|
00DFEF 1 ; Multiple entry points select state values one through five in Y.
|
|
00DFEF 1 ; ============================================================================
|
|
00DFEF 1
|
|
00DFEF 1 SetCurrentObjectState1: ; $DFEF
|
|
00DFEF 1 A0 01 ldy #$01 ; $DFEF: A0 01
|
|
00DFF1 1 D0 0E bne SetCurrentObjectState ; $DFF1: D0 0E
|
|
00DFF3 1
|
|
00DFF3 1 SetCurrentObjectState2: ; $DFF3
|
|
00DFF3 1 A0 02 ldy #$02 ; $DFF3: A0 02
|
|
00DFF5 1 D0 0A bne SetCurrentObjectState ; $DFF5: D0 0A
|
|
00DFF7 1
|
|
00DFF7 1 SetCurrentObjectState3: ; $DFF7
|
|
00DFF7 1 A0 03 ldy #$03 ; $DFF7: A0 03
|
|
00DFF9 1 D0 06 bne SetCurrentObjectState ; $DFF9: D0 06
|
|
00DFFB 1
|
|
00DFFB 1 SetCurrentObjectState4: ; $DFFB
|
|
00DFFB 1 A0 04 ldy #$04 ; $DFFB: A0 04
|
|
00DFFD 1 D0 02 bne SetCurrentObjectState ; $DFFD: D0 02
|
|
00DFFF 1
|
|
00DFFF 1 SetCurrentObjectState5: ; $DFFF
|
|
00DFFF 1 A0 05 ldy #$05 ; $DFFF: A0 05
|
|
00E001 1
|
|
00E001 1 ; ----------------------------------------------------------------------------
|
|
00E001 1 ; Store the selected state in $0595 using the compact current-object index.
|
|
00E001 1 ; ----------------------------------------------------------------------------
|
|
00E001 1
|
|
00E001 1 SetCurrentObjectState: ; $E001
|
|
00E001 1 A5 E1 lda CurrentObjectIndex ; $E001: A5 E1
|
|
00E003 1 4A lsr ; $E003: 4A
|
|
00E004 1 AA tax ; $E004: AA
|
|
00E005 1
|
|
00E005 1 98 tya ; $E005: 98
|
|
00E006 1 9D 95 05 sta $0595,x ; $E006: 9D 95 05
|
|
00E009 1
|
|
00E009 1 ; ----------------------------------------------------------------------------
|
|
00E009 1 ; Prepare and test the current object's geometry.
|
|
00E009 1 ; ----------------------------------------------------------------------------
|
|
00E009 1
|
|
00E009 1 SetCurrentObjectState_Retry: ; $E009
|
|
00E009 1 20 74 E4 jsr SelectGeometryRecord_Default ; $E009: 20 74 E4
|
|
00E00C 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $E00C: 20 5F E5
|
|
00E00F 1
|
|
00E00F 1 90 06 bcc SetCurrentObjectState_Finish
|
|
00E011 1 ; $E00F: 90 06
|
|
00E011 1
|
|
00E011 1 ; ----------------------------------------------------------------------------
|
|
00E011 1 ; Geometry remains active. Run the helper at $E313 and retry.
|
|
00E011 1 ; ----------------------------------------------------------------------------
|
|
00E011 1
|
|
00E011 1 20 13 E3 jsr UpdateCurrentObjectAnimationAndWait ; $E011: 20 13 E3
|
|
00E014 1
|
|
00E014 1 4C 09 E0 jmp SetCurrentObjectState_Retry
|
|
00E017 1 ; $E014: 4C 09 E0
|
|
00E017 1
|
|
00E017 1 ; ----------------------------------------------------------------------------
|
|
00E017 1 ; Geometry cleared. Update display state and leave through the common exit.
|
|
00E017 1 ; ----------------------------------------------------------------------------
|
|
00E017 1
|
|
00E017 1 SetCurrentObjectState_Finish: ; $E017
|
|
00E017 1 20 D4 DF jsr UpdateCurrentObjectDisplayState
|
|
00E01A 1 ; $E017: 20 D4 DF
|
|
00E01A 1
|
|
00E01A 1 4C 6A EB jmp CommonEngineExit ; $E01A: 4C 6A EB
|
|
00E01D 1
|
|
00E01D 1 ; ============================================================================
|
|
00E01D 1 ; $E01D-$E036
|
|
00E01D 1 ; Lookup data used by the following object-state routines.
|
|
00E01D 1 ;
|
|
00E01D 1 ; Several later routines reference addresses inside this region, including
|
|
00E01D 1 ; $E021 and $E027. Preserve the exact raw layout until all references have
|
|
00E01D 1 ; been fully characterized.
|
|
00E01D 1 ; ============================================================================
|
|
00E01D 1
|
|
00E01D 1 ObjectStateLookupData: ; $E01D
|
|
00E01D 1 02 06 08 04 .byte $02,$06,$08,$04
|
|
00E021 1 ObjectStateThresholdTable:
|
|
00E021 1 02 05 FD FB .byte $02,$05,$FD,$FB
|
|
00E025 1 05 FD .byte $05,$FD
|
|
00E027 1 ObjectStateResultTable:
|
|
00E027 1 F9 00 .byte $F9,$00
|
|
00E029 1 00 FF 04 04 .byte $00,$FF,$04,$04
|
|
00E02D 1 02 04 06 06 .byte $02,$04,$06,$06
|
|
00E031 1 04 06 08 06 .byte $04,$06,$08,$06
|
|
00E035 1 08 08 .byte $08,$08
|
|
00E037 1
|
|
00E037 1 ; ============================================================================
|
|
00E037 1 ; $E037-$E08A
|
|
00E037 1 ; Evaluate global object state, select an active object, initialize its timer,
|
|
00E037 1 ; and wait for either input or timer expiration.
|
|
00E037 1 ;
|
|
00E037 1 ; Several conditions transfer directly to the next major path at $E08B.
|
|
00E037 1 ; ============================================================================
|
|
00E037 1
|
|
00E037 1 ObjectStateDispatch: ; $E037
|
|
00E037 1 A5 60 lda PendingStateTransition ; $E037: A5 60
|
|
00E039 1 D0 50 bne ObjectStateDispatch_NextPath
|
|
00E03B 1 ; $E039: D0 50
|
|
00E03B 1
|
|
00E03B 1 ; ----------------------------------------------------------------------------
|
|
00E03B 1 ; Search or validate the current object state.
|
|
00E03B 1 ;
|
|
00E03B 1 ; Carry set from $E1CE skips the three setup helpers and continues at $E049.
|
|
00E03B 1 ; ----------------------------------------------------------------------------
|
|
00E03B 1
|
|
00E03B 1 20 CE E1 jsr TestObjectGeometryFourTimes ; $E03B: 20 CE E1
|
|
00E03E 1 B0 09 bcs ObjectStateDispatch_CheckCandidate
|
|
00E040 1 ; $E03E: B0 09
|
|
00E040 1
|
|
00E040 1 ; ----------------------------------------------------------------------------
|
|
00E040 1 ; Contract:
|
|
00E040 1 ; Description: Internal dispatcher entry for the current object-state selection.
|
|
00E040 1 ; Entry: Current object and selector state initialized.
|
|
00E040 1 ; Returns/products: Dispatches selected state; products follow selected path.
|
|
00E040 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E040 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E040 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E040 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E040 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00E040 1 ; ----------------------------------------------------------------------------
|
|
00E040 1 ProcessObjectStateSelection:
|
|
00E040 1 20 47 E3 jsr ProcessCompactObjectState ; $E040: 20 47 E3
|
|
00E043 1 20 6A E3 jsr ProcessCompactObjectState_TestSelector ; $E043: 20 6A E3
|
|
00E046 1 20 31 E3 jsr FindAndQueueSelectedState ; $E046: 20 31 E3
|
|
00E049 1
|
|
00E049 1 ; ----------------------------------------------------------------------------
|
|
00E049 1 ; Run the next selection test.
|
|
00E049 1 ;
|
|
00E049 1 ; Carry set transfers to the next major state path at $E08B.
|
|
00E049 1 ; ----------------------------------------------------------------------------
|
|
00E049 1
|
|
00E049 1 ObjectStateDispatch_CheckCandidate: ; $E049
|
|
00E049 1 20 E7 E1 jsr FindEligibleObjectState ; $E049: 20 E7 E1
|
|
00E04C 1 B0 3D bcs ObjectStateDispatch_NextPath
|
|
00E04E 1 ; $E04C: B0 3D
|
|
00E04E 1
|
|
00E04E 1 ; ----------------------------------------------------------------------------
|
|
00E04E 1 ; When ObjectTransitionState is nonzero, validate the object-state selector.
|
|
00E04E 1 ; ----------------------------------------------------------------------------
|
|
00E04E 1
|
|
00E04E 1 A5 6E lda ObjectTransitionState ; $E04E: A5 6E
|
|
00E050 1 F0 0D beq ObjectStateDispatch_InitializeObject
|
|
00E052 1 ; $E050: F0 0D
|
|
00E052 1
|
|
00E052 1 A6 C3 ldx $C3 ; $E052: A6 C3
|
|
00E054 1
|
|
00E054 1 BD 98 05 lda $0598,x ; $E054: BD 98 05
|
|
00E057 1 4A lsr ; $E057: 4A
|
|
00E058 1 A8 tay ; $E058: A8
|
|
00E059 1 C8 iny ; $E059: C8
|
|
00E05A 1
|
|
00E05A 1 20 46 E2 jsr FindObjectStateForSelector ; $E05A: 20 46 E2
|
|
00E05D 1 30 2C bmi ObjectStateDispatch_NextPath
|
|
00E05F 1 ; $E05D: 30 2C
|
|
00E05F 1
|
|
00E05F 1 ; ----------------------------------------------------------------------------
|
|
00E05F 1 ; Initialize the selected object's compact state.
|
|
00E05F 1 ;
|
|
00E05F 1 ; GetCurrentObjectStateIndex derives X from CurrentObjectIndex. The entry indexed by $C3 is
|
|
00E05F 1 ; complemented and stored in $0595,X.
|
|
00E05F 1 ; ----------------------------------------------------------------------------
|
|
00E05F 1
|
|
00E05F 1 ObjectStateDispatch_InitializeObject: ; $E05F
|
|
00E05F 1 20 68 DA jsr GetCurrentObjectStateIndex
|
|
00E062 1 ; $E05F: 20 68 DA
|
|
00E062 1
|
|
00E062 1 A5 C3 lda $C3 ; $E062: A5 C3
|
|
00E064 1 49 FF eor #$FF ; $E064: 49 FF
|
|
00E066 1 9D 95 05 sta $0595,x ; $E066: 9D 95 05
|
|
00E069 1
|
|
00E069 1 A9 00 lda #$00 ; $E069: A9 00
|
|
00E06B 1 85 9E sta $9E ; $E06B: 85 9E
|
|
00E06D 1
|
|
00E06D 1 ; ----------------------------------------------------------------------------
|
|
00E06D 1 ; Initialize the current object's timer to one.
|
|
00E06D 1 ;
|
|
00E06D 1 ; This is also the restart point after $E222 returns a nonzero result.
|
|
00E06D 1 ; ----------------------------------------------------------------------------
|
|
00E06D 1
|
|
00E06D 1 ObjectStateDispatch_SetTimer: ; $E06D
|
|
00E06D 1 A9 01 lda #$01 ; $E06D: A9 01
|
|
00E06F 1
|
|
00E06F 1 ObjectStateDispatch_StoreTimer: ; $E06F
|
|
00E06F 1 A6 E1 ldx CurrentObjectIndex ; $E06F: A6 E1
|
|
00E071 1 9D B1 05 sta $05B1,x ; $E071: 9D B1 05
|
|
00E074 1
|
|
00E074 1 ; ----------------------------------------------------------------------------
|
|
00E074 1 ; Wait for a frame and monitor the high two bits of InputAux2.
|
|
00E074 1 ; ----------------------------------------------------------------------------
|
|
00E074 1
|
|
00E074 1 ObjectStateDispatch_TimerLoop: ; $E074
|
|
00E074 1 20 48 EB jsr SelectObjectEventBank1 ; $E074: 20 48 EB
|
|
00E077 1
|
|
00E077 1 A5 18 lda InputAux2 ; $E077: A5 18
|
|
00E079 1 29 C0 and #$C0 ; $E079: 29 C0
|
|
00E07B 1 D0 0C bne ObjectStateDispatch_InputActive
|
|
00E07D 1 ; $E07B: D0 0C
|
|
00E07D 1
|
|
00E07D 1 ; ----------------------------------------------------------------------------
|
|
00E07D 1 ; No relevant input. Count the current object's timer down.
|
|
00E07D 1 ; ----------------------------------------------------------------------------
|
|
00E07D 1
|
|
00E07D 1 A6 E1 ldx CurrentObjectIndex ; $E07D: A6 E1
|
|
00E07F 1
|
|
00E07F 1 DE B1 05 dec $05B1,x ; $E07F: DE B1 05
|
|
00E082 1 D0 F0 bne ObjectStateDispatch_TimerLoop
|
|
00E084 1 ; $E082: D0 F0
|
|
00E084 1
|
|
00E084 1 ; ----------------------------------------------------------------------------
|
|
00E084 1 ; The timer expired. Run $E222.
|
|
00E084 1 ;
|
|
00E084 1 ; A nonzero result restarts the timer using the value currently in A.
|
|
00E084 1 ; A zero result falls through to $E089, but BNE is not taken there either,
|
|
00E084 1 ; allowing execution to continue at the next path at $E08B.
|
|
00E084 1 ; ----------------------------------------------------------------------------
|
|
00E084 1
|
|
00E084 1 20 22 E2 jsr ProcessSelectedObjectState ; $E084: 20 22 E2
|
|
00E087 1 D0 E6 bne ObjectStateDispatch_StoreTimer
|
|
00E089 1 ; $E087: D0 E6
|
|
00E089 1
|
|
00E089 1 ObjectStateDispatch_InputActive: ; $E089
|
|
00E089 1 D0 7C bne ObjectStateDispatch_ForwardPath
|
|
00E08B 1 ; $E089: D0 7C
|
|
00E08B 1 ; When reached from $E07B, branches to $E107.
|
|
00E08B 1 ; When reached after zero from $E222, falls
|
|
00E08B 1 ; through to $E08B.
|
|
00E08B 1
|
|
00E08B 1 ; ============================================================================
|
|
00E08B 1 ; $E08B-$E106
|
|
00E08B 1 ; Scan active object-state entries, evaluate their position and state tables,
|
|
00E08B 1 ; then wait for the next eligible input or state transition.
|
|
00E08B 1 ; ============================================================================
|
|
00E08B 1
|
|
00E08B 1 ObjectStateDispatch_NextPath: ; $E08B
|
|
00E08B 1 A6 E1 ldx CurrentObjectIndex ; $E08B: A6 E1
|
|
00E08D 1
|
|
00E08D 1 E0 04 cpx #$04 ; $E08D: E0 04
|
|
00E08F 1 D0 65 bne ObjectStateDispatch_WaitLoop
|
|
00E091 1 ; $E08F: D0 65
|
|
00E091 1
|
|
00E091 1 ; ----------------------------------------------------------------------------
|
|
00E091 1 ; Special setup for object offset $04.
|
|
00E091 1 ; ----------------------------------------------------------------------------
|
|
00E091 1
|
|
00E091 1 A9 12 lda #$12 ; $E091: A9 12
|
|
00E093 1 8D B2 03 sta $03B2 ; $E093: 8D B2 03
|
|
00E096 1
|
|
00E096 1 D0 5E bne ObjectStateDispatch_WaitLoop
|
|
00E098 1 ; $E096: D0 5E
|
|
00E098 1 ; Always taken because A is nonzero.
|
|
00E098 1
|
|
00E098 1 ; ============================================================================
|
|
00E098 1 ; $E098
|
|
00E098 1 ; Select the initial object-state table index.
|
|
00E098 1 ; ============================================================================
|
|
00E098 1
|
|
00E098 1 ObjectStateDispatch_SelectStart: ; $E098
|
|
00E098 1 A2 02 ldx #$02 ; $E098: A2 02
|
|
00E09A 1
|
|
00E09A 1 E4 64 cpx SecondarySequenceState ; $E09A: E4 64
|
|
00E09C 1 D0 07 bne ObjectStateDispatch_AdvanceIndex
|
|
00E09E 1 ; $E09C: D0 07
|
|
00E09E 1
|
|
00E09E 1 A5 BC lda $BC ; $E09E: A5 BC
|
|
00E0A0 1 D0 03 bne ObjectStateDispatch_AdvanceIndex
|
|
00E0A2 1 ; $E0A0: D0 03
|
|
00E0A2 1
|
|
00E0A2 1 ; ----------------------------------------------------------------------------
|
|
00E0A2 1 ; When SecondarySequenceState equals two and $BC is zero, use $BC as the initial index and
|
|
00E0A2 1 ; increment it for the next pass.
|
|
00E0A2 1 ; ----------------------------------------------------------------------------
|
|
00E0A2 1
|
|
00E0A2 1 AA tax ; $E0A2: AA
|
|
00E0A3 1 ; A is zero, so X becomes zero.
|
|
00E0A3 1
|
|
00E0A3 1 E6 BC inc $BC ; $E0A3: E6 BC
|
|
00E0A5 1
|
|
00E0A5 1 ObjectStateDispatch_AdvanceIndex: ; $E0A5
|
|
00E0A5 1 E8 inx ; $E0A5: E8
|
|
00E0A6 1 86 C3 stx $C3 ; $E0A6: 86 C3
|
|
00E0A8 1
|
|
00E0A8 1 ; ============================================================================
|
|
00E0A8 1 ; $E0A8
|
|
00E0A8 1 ; Search object-state entries beginning at index $C3.
|
|
00E0A8 1 ; ============================================================================
|
|
00E0A8 1
|
|
00E0A8 1 ObjectStateDispatch_Search: ; $E0A8
|
|
00E0A8 1 A6 C3 ldx $C3 ; $E0A8: A6 C3
|
|
00E0AA 1
|
|
00E0AA 1 BD 98 05 lda $0598,x ; $E0AA: BD 98 05
|
|
00E0AD 1 30 43 bmi ObjectStateDispatch_NextEntry
|
|
00E0AF 1 ; $E0AD: 30 43
|
|
00E0AF 1
|
|
00E0AF 1 ; ----------------------------------------------------------------------------
|
|
00E0AF 1 ; Load the corresponding compact state from zero-page $95-$98.
|
|
00E0AF 1 ; ----------------------------------------------------------------------------
|
|
00E0AF 1
|
|
00E0AF 1 B4 95 ldy $95,x ; $E0AF: B4 95
|
|
00E0B1 1 D0 04 bne ObjectStateDispatch_TestState
|
|
00E0B3 1 ; $E0B1: D0 04
|
|
00E0B3 1
|
|
00E0B3 1 ; ----------------------------------------------------------------------------
|
|
00E0B3 1 ; A zero compact state derives a value from the table index.
|
|
00E0B3 1 ;
|
|
00E0B3 1 ; A nonzero doubled X branches to the forward transition at
|
|
00E0B3 1 ; ObjectStateDispatch_ForwardTransition
|
|
00E0B3 1 ; ----------------------------------------------------------------------------
|
|
00E0B3 1
|
|
00E0B3 1 8A txa ; $E0B3: 8A
|
|
00E0B4 1 0A asl ; $E0B4: 0A
|
|
00E0B5 1 D0 5D bne ObjectStateDispatch_ForwardTransition
|
|
00E0B7 1 ; $E0B5: D0 5D
|
|
00E0B7 1
|
|
00E0B7 1 ; ----------------------------------------------------------------------------
|
|
00E0B7 1 ; Shift the compact state and reject entries whose low bit was clear.
|
|
00E0B7 1 ; ----------------------------------------------------------------------------
|
|
00E0B7 1
|
|
00E0B7 1 ObjectStateDispatch_TestState: ; $E0B7
|
|
00E0B7 1 4A lsr ; $E0B7: 4A
|
|
00E0B8 1 90 38 bcc ObjectStateDispatch_NextEntry
|
|
00E0BA 1 ; $E0B8: 90 38
|
|
00E0BA 1
|
|
00E0BA 1 85 C2 sta $C2 ; $E0BA: 85 C2
|
|
00E0BC 1 A8 tay ; $E0BC: A8
|
|
00E0BD 1 C8 iny ; $E0BD: C8
|
|
00E0BE 1
|
|
00E0BE 1 ; ----------------------------------------------------------------------------
|
|
00E0BE 1 ; Test the selected state using the helper at $E246.
|
|
00E0BE 1 ; ----------------------------------------------------------------------------
|
|
00E0BE 1
|
|
00E0BE 1 20 46 E2 jsr FindObjectStateForSelector ; $E0BE: 20 46 E2
|
|
00E0C1 1 10 09 bpl ObjectStateDispatch_CompareTables
|
|
00E0C3 1 ; $E0C1: 10 09
|
|
00E0C3 1
|
|
00E0C3 1 ; ----------------------------------------------------------------------------
|
|
00E0C3 1 ; A negative result is ignored while ObjectTransitionState is nonzero.
|
|
00E0C3 1 ;
|
|
00E0C3 1 ; Otherwise, increment A and transfer to the forward transition at
|
|
00E0C3 1 ; ObjectStateDispatch_ForwardTransition
|
|
00E0C3 1 ; ----------------------------------------------------------------------------
|
|
00E0C3 1
|
|
00E0C3 1 A4 6E ldy ObjectTransitionState ; $E0C3: A4 6E
|
|
00E0C5 1 D0 2B bne ObjectStateDispatch_NextEntry
|
|
00E0C7 1 ; $E0C5: D0 2B
|
|
00E0C7 1
|
|
00E0C7 1 18 clc ; $E0C7: 18
|
|
00E0C8 1 69 01 adc #$01 ; $E0C8: 69 01
|
|
00E0CA 1 D0 48 bne ObjectStateDispatch_ForwardTransition
|
|
00E0CC 1 ; $E0CA: D0 48
|
|
00E0CC 1
|
|
00E0CC 1 ; ============================================================================
|
|
00E0CC 1 ; $E0CC
|
|
00E0CC 1 ; Compare the selected object's high coordinate against overlapping lookup
|
|
00E0CC 1 ; tables at $E021, $E024, and $E027.
|
|
00E0CC 1 ; ============================================================================
|
|
00E0CC 1
|
|
00E0CC 1 ObjectStateDispatch_CompareTables: ; $E0CC
|
|
00E0CC 1 A4 C2 ldy $C2 ; $E0CC: A4 C2
|
|
00E0CE 1
|
|
00E0CE 1 A5 C3 lda $C3 ; $E0CE: A5 C3
|
|
00E0D0 1 0A asl ; $E0D0: 0A
|
|
00E0D1 1 AA tax ; $E0D1: AA
|
|
00E0D2 1
|
|
00E0D2 1 ; ----------------------------------------------------------------------------
|
|
00E0D2 1 ; Signed/bitwise first comparison.
|
|
00E0D2 1 ; ----------------------------------------------------------------------------
|
|
00E0D2 1
|
|
00E0D2 1 BD 10 05 lda $0510,x ; $E0D2: BD 10 05
|
|
00E0D5 1
|
|
00E0D5 1 F9 24 E0 sbc $E024,y ; $E0D5: F9 24 E0
|
|
00E0D8 1 59 27 E0 eor $E027,y ; $E0D8: 59 27 E0
|
|
00E0DB 1
|
|
00E0DB 1 10 15 bpl ObjectStateDispatch_NextEntry
|
|
00E0DD 1 ; $E0DB: 10 15
|
|
00E0DD 1
|
|
00E0DD 1 ; ----------------------------------------------------------------------------
|
|
00E0DD 1 ; Second comparison against the table beginning at $E021.
|
|
00E0DD 1 ;
|
|
00E0DD 1 ; ROL incorporates the comparison carry into Y.
|
|
00E0DD 1 ; ----------------------------------------------------------------------------
|
|
00E0DD 1
|
|
00E0DD 1 BD 10 05 lda $0510,x ; $E0DD: BD 10 05
|
|
00E0E0 1 D9 21 E0 cmp $E021,y ; $E0E0: D9 21 E0
|
|
00E0E3 1
|
|
00E0E3 1 98 tya ; $E0E3: 98
|
|
00E0E4 1 2A rol ; $E0E4: 2A
|
|
00E0E5 1 A8 tay ; $E0E5: A8
|
|
00E0E6 1
|
|
00E0E6 1 ; ----------------------------------------------------------------------------
|
|
00E0E6 1 ; Combine the indexed activity byte at $0573,X with the comparison result.
|
|
00E0E6 1 ; ----------------------------------------------------------------------------
|
|
00E0E6 1
|
|
00E0E6 1 BD 73 05 lda $0573,x ; $E0E6: BD 73 05
|
|
00E0E9 1 0A asl ; $E0E9: 0A
|
|
00E0EA 1
|
|
00E0EA 1 98 tya ; $E0EA: 98
|
|
00E0EB 1 2A rol ; $E0EB: 2A
|
|
00E0EC 1 A8 tay ; $E0EC: A8
|
|
00E0ED 1
|
|
00E0ED 1 B9 27 E0 lda $E027,y ; $E0ED: B9 27 E0
|
|
00E0F0 1 D0 22 bne ObjectStateDispatch_ForwardTransition
|
|
00E0F2 1 ; $E0F0: D0 22
|
|
00E0F2 1
|
|
00E0F2 1 ; ----------------------------------------------------------------------------
|
|
00E0F2 1 ; Reject this entry and continue searching backward.
|
|
00E0F2 1 ; ----------------------------------------------------------------------------
|
|
00E0F2 1
|
|
00E0F2 1 ObjectStateDispatch_NextEntry: ; $E0F2
|
|
00E0F2 1 C6 C3 dec $C3 ; $E0F2: C6 C3
|
|
00E0F4 1 10 B2 bpl ObjectStateDispatch_Search
|
|
00E0F6 1 ; $E0F4: 10 B2
|
|
00E0F6 1
|
|
00E0F6 1 ; ============================================================================
|
|
00E0F6 1 ; $E0F6
|
|
00E0F6 1 ; Wait until the global state and input conditions permit another scan.
|
|
00E0F6 1 ; ============================================================================
|
|
00E0F6 1
|
|
00E0F6 1 ObjectStateDispatch_WaitLoop: ; $E0F6
|
|
00E0F6 1 20 48 EB jsr SelectObjectEventBank1 ; $E0F6: 20 48 EB
|
|
00E0F9 1
|
|
00E0F9 1 A5 60 lda PendingStateTransition ; $E0F9: A5 60
|
|
00E0FB 1 D0 F9 bne ObjectStateDispatch_WaitLoop
|
|
00E0FD 1 ; $E0FB: D0 F9
|
|
00E0FD 1
|
|
00E0FD 1 ; ----------------------------------------------------------------------------
|
|
00E0FD 1 ; If $10 is zero, restart object-state selection at $E098.
|
|
00E0FD 1 ; ----------------------------------------------------------------------------
|
|
00E0FD 1
|
|
00E0FD 1 A5 10 lda $10 ; $E0FD: A5 10
|
|
00E0FF 1 F0 97 beq ObjectStateDispatch_SelectStart
|
|
00E101 1 ; $E0FF: F0 97
|
|
00E101 1
|
|
00E101 1 ; ----------------------------------------------------------------------------
|
|
00E101 1 ; Otherwise, wait until either of the high two bits in InputAux2 becomes set.
|
|
00E101 1 ; ----------------------------------------------------------------------------
|
|
00E101 1
|
|
00E101 1 A5 18 lda InputAux2 ; $E101: A5 18
|
|
00E103 1 29 C0 and #$C0 ; $E103: 29 C0
|
|
00E105 1 F0 EF beq ObjectStateDispatch_WaitLoop
|
|
00E107 1 ; $E105: F0 EF
|
|
00E107 1
|
|
00E107 1
|
|
00E107 1 ; ============================================================================
|
|
00E107 1 ; $E107-$E16B
|
|
00E107 1 ; Convert input state into an object-state selection, process event slot $1D,
|
|
00E107 1 ; assign the selected state to an object, and either retry geometry processing
|
|
00E107 1 ; or return to the main object-state dispatch loop.
|
|
00E107 1 ; ============================================================================
|
|
00E107 1
|
|
00E107 1 ObjectStateDispatch_ForwardPath: ; $E107
|
|
00E107 1 A2 FF ldx #$FF ; $E107: A2 FF
|
|
00E109 1
|
|
00E109 1 ; ----------------------------------------------------------------------------
|
|
00E109 1 ; Derive a compact index from InputState2.
|
|
00E109 1 ;
|
|
00E109 1 ; InputState2 is ORed with $F0, then shifted right until a zero bit reaches
|
|
00E109 1 ; carry. X begins at $FF and is incremented before each shift.
|
|
00E109 1 ; ----------------------------------------------------------------------------
|
|
00E109 1
|
|
00E109 1 A5 14 lda InputState2 ; $E109: A5 14
|
|
00E10B 1 09 F0 ora #$F0 ; $E10B: 09 F0
|
|
00E10D 1
|
|
00E10D 1 ObjectStateDispatch_FindInputIndex: ; $E10D
|
|
00E10D 1 E8 inx ; $E10D: E8
|
|
00E10E 1 4A lsr ; $E10E: 4A
|
|
00E10F 1 90 FC bcc ObjectStateDispatch_FindInputIndex
|
|
00E111 1 ; $E10F: 90 FC
|
|
00E111 1
|
|
00E111 1 ; ----------------------------------------------------------------------------
|
|
00E111 1 ; Use the resulting X index to select a byte from the lookup data beginning at
|
|
00E111 1 ; $E01D.
|
|
00E111 1 ; ----------------------------------------------------------------------------
|
|
00E111 1
|
|
00E111 1 BD 1D E0 lda $E01D,x ; $E111: BD 1D E0
|
|
00E114 1 ObjectStateDispatch_ForwardTransition:
|
|
00E114 1 48 pha ; $E114: 48
|
|
00E115 1
|
|
00E115 1 ; ----------------------------------------------------------------------------
|
|
00E115 1 ; Process event slot $1D and run two engine helpers.
|
|
00E115 1 ; ----------------------------------------------------------------------------
|
|
00E115 1
|
|
00E115 1 A0 1D ldy #$1D ; $E115: A0 1D
|
|
00E117 1 20 66 EB jsr DispatchNextQueuedEvent ; $E117: 20 66 EB
|
|
00E11A 1
|
|
00E11A 1 20 D3 E2 jsr ClearCurrentObjectMovement ; $E11A: 20 D3 E2
|
|
00E11D 1 20 E6 E3 jsr InitializeBaseObjectFromCurrent ; $E11D: 20 E6 E3
|
|
00E120 1
|
|
00E120 1 ; ----------------------------------------------------------------------------
|
|
00E120 1 ; Restore the selected lookup value and divide it by two.
|
|
00E120 1 ; Store the resulting compact state in $C2.
|
|
00E120 1 ; ----------------------------------------------------------------------------
|
|
00E120 1
|
|
00E120 1 68 pla ; $E120: 68
|
|
00E121 1 4A lsr ; $E121: 4A
|
|
00E122 1 85 C2 sta $C2 ; $E122: 85 C2
|
|
00E124 1
|
|
00E124 1 ; ----------------------------------------------------------------------------
|
|
00E124 1 ; Obtain the current object/event selector.
|
|
00E124 1 ; ----------------------------------------------------------------------------
|
|
00E124 1
|
|
00E124 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $E124: 20 DC E3
|
|
00E127 1
|
|
00E127 1 A5 C2 lda $C2 ; $E127: A5 C2
|
|
00E129 1
|
|
00E129 1 ; ----------------------------------------------------------------------------
|
|
00E129 1 ; Adjust $BB for two special selector/state combinations:
|
|
00E129 1 ;
|
|
00E129 1 ; Y = $02 and A = $04 -> $BB = $01
|
|
00E129 1 ; Y = $04 and A = $02 -> $BB = $03
|
|
00E129 1 ; ----------------------------------------------------------------------------
|
|
00E129 1
|
|
00E129 1 C0 02 cpy #$02 ; $E129: C0 02
|
|
00E12B 1 D0 08 bne ObjectStateDispatch_CheckSelector4
|
|
00E12D 1 ; $E12B: D0 08
|
|
00E12D 1
|
|
00E12D 1 C9 04 cmp #$04 ; $E12D: C9 04
|
|
00E12F 1 D0 04 bne ObjectStateDispatch_CheckSelector4
|
|
00E131 1 ; $E12F: D0 04
|
|
00E131 1
|
|
00E131 1 A2 01 ldx #$01 ; $E131: A2 01
|
|
00E133 1 86 BB stx $BB ; $E133: 86 BB
|
|
00E135 1
|
|
00E135 1 ObjectStateDispatch_CheckSelector4: ; $E135
|
|
00E135 1 C0 04 cpy #$04 ; $E135: C0 04
|
|
00E137 1 D0 08 bne ObjectStateDispatch_AssignState
|
|
00E139 1 ; $E137: D0 08
|
|
00E139 1
|
|
00E139 1 C9 02 cmp #$02 ; $E139: C9 02
|
|
00E13B 1 D0 04 bne ObjectStateDispatch_AssignState
|
|
00E13D 1 ; $E13B: D0 04
|
|
00E13D 1
|
|
00E13D 1 A2 03 ldx #$03 ; $E13D: A2 03
|
|
00E13F 1 86 BB stx $BB ; $E13F: 86 BB
|
|
00E141 1
|
|
00E141 1 ; ----------------------------------------------------------------------------
|
|
00E141 1 ; Select the target object through $E25E.
|
|
00E141 1 ;
|
|
00E141 1 ; The helper returns an object offset in Y.
|
|
00E141 1 ; ----------------------------------------------------------------------------
|
|
00E141 1
|
|
00E141 1 ObjectStateDispatch_AssignState: ; $E141
|
|
00E141 1 20 5E E2 jsr FindNearestCandidateObject ; $E141: 20 5E E2
|
|
00E144 1
|
|
00E144 1 ; ----------------------------------------------------------------------------
|
|
00E144 1 ; Convert the object offset in Y into a compact object-state index and store
|
|
00E144 1 ; the selected state from $C2 into $0595,X.
|
|
00E144 1 ; ----------------------------------------------------------------------------
|
|
00E144 1
|
|
00E144 1 98 tya ; $E144: 98
|
|
00E145 1 4A lsr ; $E145: 4A
|
|
00E146 1 AA tax ; $E146: AA
|
|
00E147 1
|
|
00E147 1 A5 C2 lda $C2 ; $E147: A5 C2
|
|
00E149 1 9D 95 05 sta $0595,x ; $E149: 9D 95 05
|
|
00E14C 1
|
|
00E14C 1 ; ----------------------------------------------------------------------------
|
|
00E14C 1 ; Compare the selected object offset in Y against CurrentObjectIndex.
|
|
00E14C 1 ;
|
|
00E14C 1 ; If they differ, continue at the next path at $E16C.
|
|
00E14C 1 ; ----------------------------------------------------------------------------
|
|
00E14C 1
|
|
00E14C 1 C4 E1 cpy CurrentObjectIndex ; $E14C: C4 E1
|
|
00E14E 1 D0 1C bne ObjectStateDispatch_DifferentObject
|
|
00E150 1 ; $E14E: D0 1C
|
|
00E150 1
|
|
00E150 1 ; ----------------------------------------------------------------------------
|
|
00E150 1 ; The selected object is the current object.
|
|
00E150 1 ;
|
|
00E150 1 ; Prepare and test its geometry. Carry set runs $E313 and retries the test.
|
|
00E150 1 ; ----------------------------------------------------------------------------
|
|
00E150 1
|
|
00E150 1 ObjectStateDispatch_TestSelectedObject: ; $E150
|
|
00E150 1 20 74 E4 jsr SelectGeometryRecord_Default ; $E150: 20 74 E4
|
|
00E153 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $E153: 20 5F E5
|
|
00E156 1
|
|
00E156 1 90 06 bcc ObjectStateDispatch_SelectedObjectClear
|
|
00E158 1 ; $E156: 90 06
|
|
00E158 1
|
|
00E158 1 20 13 E3 jsr UpdateCurrentObjectAnimationAndWait ; $E158: 20 13 E3
|
|
00E15B 1 4C 50 E1 jmp ObjectStateDispatch_TestSelectedObject
|
|
00E15E 1 ; $E15B: 4C 50 E1
|
|
00E15E 1
|
|
00E15E 1 ; ----------------------------------------------------------------------------
|
|
00E15E 1 ; Geometry cleared.
|
|
00E15E 1 ;
|
|
00E15E 1 ; Update the current object's display state, derive its selector, save that
|
|
00E15E 1 ; selector in $9E, run the engine helper, and return to the setup path at
|
|
00E15E 1 ; $E040.
|
|
00E15E 1 ; ----------------------------------------------------------------------------
|
|
00E15E 1
|
|
00E15E 1 ObjectStateDispatch_SelectedObjectClear: ; $E15E
|
|
00E15E 1 20 D4 DF jsr UpdateCurrentObjectDisplayState
|
|
00E161 1 ; $E15E: 20 D4 DF
|
|
00E161 1
|
|
00E161 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $E161: 20 DC E3
|
|
00E164 1 84 9E sty $9E ; $E164: 84 9E
|
|
00E166 1
|
|
00E166 1 20 E6 E3 jsr InitializeBaseObjectFromCurrent ; $E166: 20 E6 E3
|
|
00E169 1
|
|
00E169 1 4C 40 E0 jmp ProcessObjectStateSelection ; $E169: 4C 40 E0
|
|
00E16C 1
|
|
00E16C 1 ; ============================================================================
|
|
00E16C 1 ; $E16C-$E1CD
|
|
00E16C 1 ; Process the selected object's event, update its animation, wait, and leave
|
|
00E16C 1 ; through the common engine exit.
|
|
00E16C 1 ;
|
|
00E16C 1 ; Entry:
|
|
00E16C 1 ; Y = selected object/event offset returned by $E25E
|
|
00E16C 1 ; $C2 = selected compact state
|
|
00E16C 1 ; ============================================================================
|
|
00E16C 1
|
|
00E16C 1 ObjectStateDispatch_DifferentObject: ; $E16C
|
|
00E16C 1 84 C4 sty $C4 ; $E16C: 84 C4
|
|
00E16E 1
|
|
00E16E 1 ; ----------------------------------------------------------------------------
|
|
00E16E 1 ; Process the selected object's event slot and wait ten ticks.
|
|
00E16E 1 ; ----------------------------------------------------------------------------
|
|
00E16E 1
|
|
00E16E 1 20 66 EB jsr DispatchNextQueuedEvent ; $E16E: 20 66 EB
|
|
00E171 1
|
|
00E171 1 A9 0A lda #$0A ; $E171: A9 0A
|
|
00E173 1 20 41 EB jsr StoreObjectEventBankValue ; $E173: 20 41 EB
|
|
00E176 1
|
|
00E176 1 ; ----------------------------------------------------------------------------
|
|
00E176 1 ; Dispatch the selected object through $E29B.
|
|
00E176 1 ;
|
|
00E176 1 ; X is restored from $C4. The inline record contains a leading zero byte and
|
|
00E176 1 ; stored address $E3AB. The exact dispatch convention will be confirmed when
|
|
00E176 1 ; $E29B and $E3AB are decoded.
|
|
00E176 1 ; ----------------------------------------------------------------------------
|
|
00E176 1
|
|
00E176 1 A6 C4 ldx $C4 ; $E176: A6 C4
|
|
00E178 1 20 9B E2 jsr DispatchInlineObjectCommand ; $E178: 20 9B E2
|
|
00E17B 1
|
|
00E17B 1 00 AB E3 .byte $00,$AB,$E3 ; $E17B-$E17D
|
|
00E17E 1
|
|
00E17E 1 ; ----------------------------------------------------------------------------
|
|
00E17E 1 ; Run the shared engine update, then clear $9E.
|
|
00E17E 1 ; ----------------------------------------------------------------------------
|
|
00E17E 1
|
|
00E17E 1 20 E6 E3 jsr InitializeBaseObjectFromCurrent ; $E17E: 20 E6 E3
|
|
00E181 1
|
|
00E181 1 A9 00 lda #$00 ; $E181: A9 00
|
|
00E183 1 85 9E sta $9E ; $E183: 85 9E
|
|
00E185 1
|
|
00E185 1 ; ----------------------------------------------------------------------------
|
|
00E185 1 ; Object offset $04 uses a short alternate exit at $E1C6.
|
|
00E185 1 ; ----------------------------------------------------------------------------
|
|
00E185 1
|
|
00E185 1 A6 E1 ldx CurrentObjectIndex ; $E185: A6 E1
|
|
00E187 1 E0 04 cpx #$04 ; $E187: E0 04
|
|
00E189 1 F0 3B beq ObjectStateDispatch_Object04
|
|
00E18B 1 ; $E189: F0 3B
|
|
00E18B 1
|
|
00E18B 1 ; ----------------------------------------------------------------------------
|
|
00E18B 1 ; Select an animation attribute according to $C2 and the sign of the current
|
|
00E18B 1 ; object's high horizontal coordinate.
|
|
00E18B 1 ;
|
|
00E18B 1 ; The table access intentionally uses base $DFCD.
|
|
00E18B 1 ; ----------------------------------------------------------------------------
|
|
00E18B 1
|
|
00E18B 1 A6 E1 ldx CurrentObjectIndex ; $E18B: A6 E1
|
|
00E18D 1
|
|
00E18D 1 A4 C2 ldy $C2 ; $E18D: A4 C2
|
|
00E18F 1 B9 CD DF lda $DFCD,y ; $E18F: B9 CD DF
|
|
00E192 1
|
|
00E192 1 A0 3F ldy #$3F ; $E192: A0 3F
|
|
00E194 1
|
|
00E194 1 DD 0A 05 cmp $050A,x ; $E194: DD 0A 05
|
|
00E197 1 10 02 bpl ObjectStateDispatch_SaveFirstFrame
|
|
00E199 1 ; $E197: 10 02
|
|
00E199 1
|
|
00E199 1 A0 40 ldy #$40 ; $E199: A0 40
|
|
00E19B 1
|
|
00E19B 1 ; ----------------------------------------------------------------------------
|
|
00E19B 1 ; Convert CurrentObjectIndex to the compact sprite-array index.
|
|
00E19B 1 ; ----------------------------------------------------------------------------
|
|
00E19B 1
|
|
00E19B 1 ObjectStateDispatch_SaveFirstFrame: ; $E19B
|
|
00E19B 1 A5 E1 lda CurrentObjectIndex ; $E19B: A5 E1
|
|
00E19D 1 4A lsr ; $E19D: 4A
|
|
00E19E 1 AA tax ; $E19E: AA
|
|
00E19F 1
|
|
00E19F 1 ; ----------------------------------------------------------------------------
|
|
00E19F 1 ; Compact indices below $0C receive the selected attribute $3F/$40.
|
|
00E19F 1 ; ----------------------------------------------------------------------------
|
|
00E19F 1
|
|
00E19F 1 E0 0C cpx #$0C ; $E19F: E0 0C
|
|
00E1A1 1 B0 04 bcs ObjectStateDispatch_SaveFrame5F
|
|
00E1A3 1 ; $E1A1: B0 04
|
|
00E1A3 1
|
|
00E1A3 1 98 tya ; $E1A3: 98
|
|
00E1A4 1 9D B0 03 sta $03B0,x ; $E1A4: 9D B0 03
|
|
00E1A7 1
|
|
00E1A7 1 ObjectStateDispatch_SaveFrame5F: ; $E1A7
|
|
00E1A7 1 A9 5F lda #$5F ; $E1A7: A9 5F
|
|
00E1A9 1 9D 9B 03 sta $039B,x ; $E1A9: 9D 9B 03
|
|
00E1AC 1
|
|
00E1AC 1 ; ----------------------------------------------------------------------------
|
|
00E1AC 1 ; Hold this animation for $3C ticks.
|
|
00E1AC 1 ; ----------------------------------------------------------------------------
|
|
00E1AC 1
|
|
00E1AC 1 A9 3C lda #$3C ; $E1AC: A9 3C
|
|
00E1AE 1 20 41 EB jsr StoreObjectEventBankValue ; $E1AE: 20 41 EB
|
|
00E1B1 1
|
|
00E1B1 1 ; ----------------------------------------------------------------------------
|
|
00E1B1 1 ; Replace the animation with frame $67. Compact indices below $0C also receive
|
|
00E1B1 1 ; attribute $2F.
|
|
00E1B1 1 ; ----------------------------------------------------------------------------
|
|
00E1B1 1
|
|
00E1B1 1 A5 E1 lda CurrentObjectIndex ; $E1B1: A5 E1
|
|
00E1B3 1 4A lsr ; $E1B3: 4A
|
|
00E1B4 1 AA tax ; $E1B4: AA
|
|
00E1B5 1
|
|
00E1B5 1 E0 0C cpx #$0C ; $E1B5: E0 0C
|
|
00E1B7 1 B0 05 bcs ObjectStateDispatch_SaveFrame67
|
|
00E1B9 1 ; $E1B7: B0 05
|
|
00E1B9 1
|
|
00E1B9 1 A9 2F lda #$2F ; $E1B9: A9 2F
|
|
00E1BB 1 9D B0 03 sta $03B0,x ; $E1BB: 9D B0 03
|
|
00E1BE 1
|
|
00E1BE 1 ObjectStateDispatch_SaveFrame67: ; $E1BE
|
|
00E1BE 1 A9 67 lda #$67 ; $E1BE: A9 67
|
|
00E1C0 1 9D 9B 03 sta $039B,x ; $E1C0: 9D 9B 03
|
|
00E1C3 1
|
|
00E1C3 1 4C 6A EB jmp CommonEngineExit ; $E1C3: 4C 6A EB
|
|
00E1C6 1
|
|
00E1C6 1 ; ----------------------------------------------------------------------------
|
|
00E1C6 1 ; Special exit for object offset $04.
|
|
00E1C6 1 ; ----------------------------------------------------------------------------
|
|
00E1C6 1
|
|
00E1C6 1 ObjectStateDispatch_Object04: ; $E1C6
|
|
00E1C6 1 A9 13 lda #$13 ; $E1C6: A9 13
|
|
00E1C8 1 8D B2 03 sta $03B2 ; $E1C8: 8D B2 03
|
|
00E1CB 1
|
|
00E1CB 1 4C 6A EB jmp CommonEngineExit ; $E1CB: 4C 6A EB
|
|
00E1CE 1
|
|
00E1CE 1 ; ============================================================================
|
|
00E1CE 1 ; $E1CE-$E1E6
|
|
00E1CE 1 ; Repeat the geometry test while its result is at least two.
|
|
00E1CE 1 ;
|
|
00E1CE 1 ; The loop permits up to four geometry-test attempts.
|
|
00E1CE 1 ;
|
|
00E1CE 1 ; Return:
|
|
00E1CE 1 ; A < $02, or the four-attempt counter expired.
|
|
00E1CE 1 ; ============================================================================
|
|
00E1CE 1
|
|
00E1CE 1 ; ----------------------------------------------------------------------------
|
|
00E1CE 1 ; Contract:
|
|
00E1CE 1 ; Description: Implements Test Object Geometry Four Times.
|
|
00E1CE 1 ; Entry: Registers: A, Y
|
|
00E1CE 1 ; Returns/products: Registers/clobbers: Y
|
|
00E1CE 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E1CE 1 ; Memory effects: $c2
|
|
00E1CE 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E1CE 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E1CE 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E1CE 1 ; ----------------------------------------------------------------------------
|
|
00E1CE 1 TestObjectGeometryFourTimes: ; $E1CE
|
|
00E1CE 1 A0 04 ldy #$04 ; $E1CE: A0 04
|
|
00E1D0 1 84 C2 sty $C2 ; $E1D0: 84 C2
|
|
00E1D2 1
|
|
00E1D2 1 TestObjectGeometryFourTimes_Loop: ; $E1D2
|
|
00E1D2 1 20 74 E4 jsr SelectGeometryRecord_Default ; $E1D2: 20 74 E4
|
|
00E1D5 1 20 C2 E4 jsr LoadGeometryRecord ; $E1D5: 20 C2 E4
|
|
00E1D8 1 20 DB E4 jsr CalculateCurrentGeometryDifference ; $E1D8: 20 DB E4
|
|
00E1DB 1 20 02 E5 jsr EvaluateGeometryDifference ; $E1DB: 20 02 E5
|
|
00E1DE 1
|
|
00E1DE 1 C9 02 cmp #$02 ; $E1DE: C9 02
|
|
00E1E0 1 90 04 bcc TestObjectGeometryFourTimes_Return
|
|
00E1E2 1 ; $E1E0: 90 04
|
|
00E1E2 1
|
|
00E1E2 1 C6 C2 dec $C2 ; $E1E2: C6 C2
|
|
00E1E4 1 D0 EC bne TestObjectGeometryFourTimes_Loop
|
|
00E1E6 1 ; $E1E4: D0 EC
|
|
00E1E6 1
|
|
00E1E6 1 TestObjectGeometryFourTimes_Return: ; $E1E6
|
|
00E1E6 1 60 rts ; $E1E6: 60
|
|
00E1E7 1
|
|
00E1E7 1 ; ============================================================================
|
|
00E1E7 1 ; $E1E7-$E200
|
|
00E1E7 1 ; Search object-state entries $0598-$059B for an eligible geometry result.
|
|
00E1E7 1 ;
|
|
00E1E7 1 ; The routine scans indices three through zero. An entry is eligible when:
|
|
00E1E7 1 ;
|
|
00E1E7 1 ; 1. Its state byte is nonnegative.
|
|
00E1E7 1 ; 2. Bit zero of the state byte is set.
|
|
00E1E7 1 ; 3. Its geometry-test result is at least $0C.
|
|
00E1E7 1 ;
|
|
00E1E7 1 ; Return:
|
|
00E1E7 1 ; C = clear when a qualifying entry is found
|
|
00E1E7 1 ; C = set when no entry qualifies
|
|
00E1E7 1 ;
|
|
00E1E7 1 ; $C3 = qualifying index, or $FF after the search is exhausted
|
|
00E1E7 1 ; ============================================================================
|
|
00E1E7 1
|
|
00E1E7 1 ; ----------------------------------------------------------------------------
|
|
00E1E7 1 ; Contract:
|
|
00E1E7 1 ; Description: Implements Find Eligible Object State.
|
|
00E1E7 1 ; Entry: Registers: A, Y; Memory: $0598, $c3
|
|
00E1E7 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00E1E7 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E1E7 1 ; Memory effects: $c3
|
|
00E1E7 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E1E7 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E1E7 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E1E7 1 ; ----------------------------------------------------------------------------
|
|
00E1E7 1 FindEligibleObjectState: ; $E1E7
|
|
00E1E7 1 A0 03 ldy #$03 ; $E1E7: A0 03
|
|
00E1E9 1
|
|
00E1E9 1 ; ----------------------------------------------------------------------------
|
|
00E1E9 1 ; Save the current table index.
|
|
00E1E9 1 ; ----------------------------------------------------------------------------
|
|
00E1E9 1
|
|
00E1E9 1 FindEligibleObjectState_Loop: ; $E1E9
|
|
00E1E9 1 84 C3 sty $C3 ; $E1E9: 84 C3
|
|
00E1EB 1
|
|
00E1EB 1 ; ----------------------------------------------------------------------------
|
|
00E1EB 1 ; Reject inactive entries whose state byte is negative.
|
|
00E1EB 1 ; ----------------------------------------------------------------------------
|
|
00E1EB 1
|
|
00E1EB 1 B9 98 05 lda $0598,y ; $E1EB: B9 98 05
|
|
00E1EE 1 30 0A bmi FindEligibleObjectState_Next
|
|
00E1F0 1 ; $E1EE: 30 0A
|
|
00E1F0 1
|
|
00E1F0 1 ; ----------------------------------------------------------------------------
|
|
00E1F0 1 ; Shift the state byte and reject entries whose low bit was clear.
|
|
00E1F0 1 ; ----------------------------------------------------------------------------
|
|
00E1F0 1
|
|
00E1F0 1 4A lsr ; $E1F0: 4A
|
|
00E1F1 1 90 07 bcc FindEligibleObjectState_Next
|
|
00E1F3 1 ; $E1F1: 90 07
|
|
00E1F3 1
|
|
00E1F3 1 ; ----------------------------------------------------------------------------
|
|
00E1F3 1 ; Test the geometry associated with the current state-table index.
|
|
00E1F3 1 ;
|
|
00E1F3 1 ; Results below $0C qualify and return immediately with carry clear from
|
|
00E1F3 1 ; CMP #$0C. Results at least $0C continue searching.
|
|
00E1F3 1 ; ----------------------------------------------------------------------------
|
|
00E1F3 1
|
|
00E1F3 1 20 01 E2 jsr TestIndexedObjectGeometry
|
|
00E1F6 1 ; $E1F3: 20 01 E2
|
|
00E1F6 1
|
|
00E1F6 1 C9 0C cmp #$0C ; $E1F6: C9 0C
|
|
00E1F8 1 90 06 bcc FindEligibleObjectState_Return
|
|
00E1FA 1 ; $E1F8: 90 06
|
|
00E1FA 1
|
|
00E1FA 1 ; ----------------------------------------------------------------------------
|
|
00E1FA 1 ; Continue with the preceding state-table index.
|
|
00E1FA 1 ; ----------------------------------------------------------------------------
|
|
00E1FA 1
|
|
00E1FA 1 FindEligibleObjectState_Next: ; $E1FA
|
|
00E1FA 1 A4 C3 ldy $C3 ; $E1FA: A4 C3
|
|
00E1FC 1 88 dey ; $E1FC: 88
|
|
00E1FD 1 10 EA bpl FindEligibleObjectState_Loop
|
|
00E1FF 1 ; $E1FD: 10 EA
|
|
00E1FF 1
|
|
00E1FF 1 ; ----------------------------------------------------------------------------
|
|
00E1FF 1 ; No entry qualified. Return carry set.
|
|
00E1FF 1 ; ----------------------------------------------------------------------------
|
|
00E1FF 1
|
|
00E1FF 1 38 sec ; $E1FF: 38
|
|
00E200 1
|
|
00E200 1 FindEligibleObjectState_Return: ; $E200
|
|
00E200 1 60 rts ; $E200: 60
|
|
00E201 1
|
|
00E201 1 ; ============================================================================
|
|
00E201 1 ; $E201-$E221
|
|
00E201 1 ; Copy coordinates for the state-table entry selected in $C3 into the geometry
|
|
00E201 1 ; arguments, process them, and test the resulting region.
|
|
00E201 1 ;
|
|
00E201 1 ; Entry:
|
|
00E201 1 ; $C3 = compact object/state index
|
|
00E201 1 ;
|
|
00E201 1 ; Return:
|
|
00E201 1 ; A = result returned by $E502
|
|
00E201 1 ; Flags from CMP #$03
|
|
00E201 1 ; ============================================================================
|
|
00E201 1
|
|
00E201 1 TestIndexedObjectGeometry: ; $E201
|
|
00E201 1 A5 C3 lda $C3 ; $E201: A5 C3
|
|
00E203 1 0A asl ; $E203: 0A
|
|
00E204 1 A8 tay ; $E204: A8
|
|
00E205 1 ; Convert compact index to object-array offset.
|
|
00E205 1
|
|
00E205 1 ; ----------------------------------------------------------------------------
|
|
00E205 1 ; Copy the selected object's horizontal coordinate.
|
|
00E205 1 ; ----------------------------------------------------------------------------
|
|
00E205 1
|
|
00E205 1 B9 0F 05 lda $050F,y ; $E205: B9 0F 05
|
|
00E208 1 85 B2 sta $B2 ; $E208: 85 B2
|
|
00E20A 1
|
|
00E20A 1 B9 10 05 lda $0510,y ; $E20A: B9 10 05
|
|
00E20D 1 85 B3 sta $B3 ; $E20D: 85 B3
|
|
00E20F 1
|
|
00E20F 1 ; ----------------------------------------------------------------------------
|
|
00E20F 1 ; Copy the selected object's vertical coordinate.
|
|
00E20F 1 ; ----------------------------------------------------------------------------
|
|
00E20F 1
|
|
00E20F 1 B9 40 05 lda $0540,y ; $E20F: B9 40 05
|
|
00E212 1 85 B4 sta $B4 ; $E212: 85 B4
|
|
00E214 1
|
|
00E214 1 B9 41 05 lda $0541,y ; $E214: B9 41 05
|
|
00E217 1 85 B5 sta $B5 ; $E217: 85 B5
|
|
00E219 1
|
|
00E219 1 ; ----------------------------------------------------------------------------
|
|
00E219 1 ; Process the coordinates and perform the final geometry test.
|
|
00E219 1 ; ----------------------------------------------------------------------------
|
|
00E219 1
|
|
00E219 1 20 DB E4 jsr CalculateCurrentGeometryDifference ; $E219: 20 DB E4
|
|
00E21C 1 20 02 E5 jsr EvaluateGeometryDifference ; $E21C: 20 02 E5
|
|
00E21F 1
|
|
00E21F 1 C9 03 cmp #$03 ; $E21F: C9 03
|
|
00E221 1 60 rts ; $E221: 60
|
|
00E222 1
|
|
00E222 1 ; ============================================================================
|
|
00E222 1 ; $E222-$E245
|
|
00E222 1 ; Derive an object-state index, test its geometry, and route according to the
|
|
00E222 1 ; result.
|
|
00E222 1 ;
|
|
00E222 1 ; Return behavior:
|
|
00E222 1 ; This helper does not return directly. Both paths tail-jump elsewhere.
|
|
00E222 1 ; ============================================================================
|
|
00E222 1
|
|
00E222 1 ; ----------------------------------------------------------------------------
|
|
00E222 1 ; Contract:
|
|
00E222 1 ; Description: Processes Selected Object State.
|
|
00E222 1 ; Entry: Registers: A, Y
|
|
00E222 1 ; Returns/products: Registers/clobbers: A
|
|
00E222 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E222 1 ; Memory effects: $c3
|
|
00E222 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E222 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E222 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E222 1 ; ----------------------------------------------------------------------------
|
|
00E222 1 ProcessSelectedObjectState: ; $E222
|
|
00E222 1 20 DC E3 jsr GetCurrentObjectSelectorAndState ; $E222: 20 DC E3
|
|
00E225 1
|
|
00E225 1 ; ----------------------------------------------------------------------------
|
|
00E225 1 ; Complement the selector returned in Y and save it in $C3.
|
|
00E225 1 ; ----------------------------------------------------------------------------
|
|
00E225 1
|
|
00E225 1 98 tya ; $E225: 98
|
|
00E226 1 49 FF eor #$FF ; $E226: 49 FF
|
|
00E228 1 85 C3 sta $C3 ; $E228: 85 C3
|
|
00E22A 1
|
|
00E22A 1 ; ----------------------------------------------------------------------------
|
|
00E22A 1 ; Test the geometry for the selected entry.
|
|
00E22A 1 ;
|
|
00E22A 1 ; TestIndexedObjectGeometry returns flags from CMP #$03.
|
|
00E22A 1 ; Carry clear means the result is below three.
|
|
00E22A 1 ; ----------------------------------------------------------------------------
|
|
00E22A 1
|
|
00E22A 1 20 01 E2 jsr TestIndexedObjectGeometry
|
|
00E22D 1 ; $E22A: 20 01 E2
|
|
00E22D 1
|
|
00E22D 1 90 0B bcc ProcessSelectedObjectState_Clear
|
|
00E22F 1 ; $E22D: 90 0B
|
|
00E22F 1
|
|
00E22F 1 ; ----------------------------------------------------------------------------
|
|
00E22F 1 ; Geometry result is at least three.
|
|
00E22F 1 ;
|
|
00E22F 1 ; Configure value $0F, apply the geometry helpers, and jump to $E2DE.
|
|
00E22F 1 ; ----------------------------------------------------------------------------
|
|
00E22F 1
|
|
00E22F 1 A9 0F lda #$0F ; $E22F: A9 0F
|
|
00E231 1
|
|
00E231 1 20 13 E5 jsr BuildGeometryVector ; $E231: 20 13 E5
|
|
00E234 1 20 28 E5 jsr StoreCurrentObjectMovement ; $E234: 20 28 E5
|
|
00E237 1
|
|
00E237 1 4C DE E2 jmp UpdateCurrentObjectAnimationDelay ; $E237: 4C DE E2
|
|
00E23A 1
|
|
00E23A 1 ; ----------------------------------------------------------------------------
|
|
00E23A 1 ; Geometry result is below three.
|
|
00E23A 1 ;
|
|
00E23A 1 ; Run the state-update helpers, then return to the object-state dispatch path
|
|
00E23A 1 ; at $E08B.
|
|
00E23A 1 ; ----------------------------------------------------------------------------
|
|
00E23A 1
|
|
00E23A 1 ProcessSelectedObjectState_Clear: ; $E23A
|
|
00E23A 1 20 D3 E2 jsr ClearCurrentObjectMovement ; $E23A: 20 D3 E2
|
|
00E23D 1 20 E6 E3 jsr InitializeBaseObjectFromCurrent ; $E23D: 20 E6 E3
|
|
00E240 1 20 84 E3 jsr ProcessCompactObjectState_Validate ; $E240: 20 84 E3
|
|
00E243 1
|
|
00E243 1 4C 8B E0 jmp ObjectStateDispatch_NextPath
|
|
00E246 1 ; $E243: 4C 8B E0
|
|
00E246 1
|
|
00E246 1 ; ============================================================================
|
|
00E246 1 ; $E246-$E25D
|
|
00E246 1 ; Search the object-state entries at $0598-$059B using a caller-supplied
|
|
00E246 1 ; selector in Y.
|
|
00E246 1 ;
|
|
00E246 1 ; Entry:
|
|
00E246 1 ; Y = one-based selector value
|
|
00E246 1 ;
|
|
00E246 1 ; Exit:
|
|
00E246 1 ; X = selected state-table index, normally $00-$03
|
|
00E246 1 ; Y = adjusted selector value
|
|
00E246 1 ;
|
|
00E246 1 ; If $0598 is zero, the routine returns immediately without performing the
|
|
00E246 1 ; search.
|
|
00E246 1 ;
|
|
00E246 1 ; The comparison intentionally uses base address $0597,X. Since X begins at
|
|
00E246 1 ; four and is decremented after unsuccessful comparisons, the effective
|
|
00E246 1 ; entries are $059B, $059A, $0599, and $0598.
|
|
00E246 1 ; ============================================================================
|
|
00E246 1
|
|
00E246 1 ; ----------------------------------------------------------------------------
|
|
00E246 1 ; Contract:
|
|
00E246 1 ; Description: Implements Find Object State For Selector.
|
|
00E246 1 ; Entry: Registers: A, X, Y; Memory: $0598, $0597
|
|
00E246 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00E246 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E246 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E246 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E246 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E246 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00E246 1 ; ----------------------------------------------------------------------------
|
|
00E246 1 FindObjectStateForSelector: ; $E246
|
|
00E246 1 AD 98 05 lda $0598 ; $E246: AD 98 05
|
|
00E249 1 F0 12 beq FindObjectStateForSelector_Return
|
|
00E24B 1 ; $E249: F0 12
|
|
00E24B 1
|
|
00E24B 1 ; ----------------------------------------------------------------------------
|
|
00E24B 1 ; Convert the one-based selector in Y into an odd comparison value:
|
|
00E24B 1 ;
|
|
00E24B 1 ; A = ((Y - 1) * 2) + 1
|
|
00E24B 1 ;
|
|
00E24B 1 ; Y itself remains decremented by one.
|
|
00E24B 1 ; ----------------------------------------------------------------------------
|
|
00E24B 1
|
|
00E24B 1 88 dey ; $E24B: 88
|
|
00E24C 1
|
|
00E24C 1 98 tya ; $E24C: 98
|
|
00E24D 1 0A asl ; $E24D: 0A
|
|
00E24E 1 69 01 adc #$01 ; $E24E: 69 01
|
|
00E250 1
|
|
00E250 1 ; ----------------------------------------------------------------------------
|
|
00E250 1 ; Search the four state entries in reverse order.
|
|
00E250 1 ;
|
|
00E250 1 ; The indexed base is deliberately one byte before $0598:
|
|
00E250 1 ;
|
|
00E250 1 ; X=$04 -> $059B
|
|
00E250 1 ; X=$03 -> $059A
|
|
00E250 1 ; X=$02 -> $0599
|
|
00E250 1 ; X=$01 -> $0598
|
|
00E250 1 ; ----------------------------------------------------------------------------
|
|
00E250 1
|
|
00E250 1 A2 04 ldx #$04 ; $E250: A2 04
|
|
00E252 1
|
|
00E252 1 FindObjectStateForSelector_Search: ; $E252
|
|
00E252 1 DD 97 05 cmp $0597,x ; $E252: DD 97 05
|
|
00E255 1 90 03 bcc FindObjectStateForSelector_Previous
|
|
00E257 1 ; $E255: 90 03
|
|
00E257 1
|
|
00E257 1 ; ----------------------------------------------------------------------------
|
|
00E257 1 ; The current table value is not greater than A.
|
|
00E257 1 ;
|
|
00E257 1 ; Decrement Y once more. If it becomes negative, return immediately.
|
|
00E257 1 ; Otherwise, keep the current X.
|
|
00E257 1 ; ----------------------------------------------------------------------------
|
|
00E257 1
|
|
00E257 1 88 dey ; $E257: 88
|
|
00E258 1 30 03 bmi FindObjectStateForSelector_Return
|
|
00E25A 1 ; $E258: 30 03
|
|
00E25A 1
|
|
00E25A 1 ; ----------------------------------------------------------------------------
|
|
00E25A 1 ; Continue searching the preceding table entry.
|
|
00E25A 1 ; ----------------------------------------------------------------------------
|
|
00E25A 1
|
|
00E25A 1 FindObjectStateForSelector_Previous: ; $E25A
|
|
00E25A 1 CA dex ; $E25A: CA
|
|
00E25B 1 D0 F5 bne FindObjectStateForSelector_Search
|
|
00E25D 1 ; $E25B: D0 F5
|
|
00E25D 1
|
|
00E25D 1 FindObjectStateForSelector_Return: ; $E25D
|
|
00E25D 1 60 rts ; $E25D: 60
|
|
00E25E 1
|
|
00E25E 1 ; ============================================================================
|
|
00E25E 1 ; $E25E-$E294
|
|
00E25E 1 ; Find the nearest candidate object from a six-entry object-offset table.
|
|
00E25E 1 ;
|
|
00E25E 1 ; Entry:
|
|
00E25E 1 ; $C2 = index selecting a signed coordinate adjustment from the overlapping
|
|
00E25E 1 ; tables at $DFCA and $DFCB
|
|
00E25E 1 ;
|
|
00E25E 1 ; Exit:
|
|
00E25E 1 ; X = selected candidate-table index, $00-$05
|
|
00E25E 1 ; Y = selected object offset:
|
|
00E25E 1 ; $04, $0E, $10, $12, $14, or $16
|
|
00E25E 1 ;
|
|
00E25E 1 ; Working values:
|
|
00E25E 1 ; $06 = smallest distance found, initialized to $FF
|
|
00E25E 1 ; $05 = candidate-table index associated with that distance
|
|
00E25E 1 ; $41 = current candidate-table index
|
|
00E25E 1 ; ============================================================================
|
|
00E25E 1
|
|
00E25E 1 ; ----------------------------------------------------------------------------
|
|
00E25E 1 ; Contract:
|
|
00E25E 1 ; Description: Implements Find Nearest Candidate Object.
|
|
00E25E 1 ; Entry: Registers: A, X; Memory: $c2, $050a, $dfcb, $053b, $dfca, $06, $41
|
|
00E25E 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E25E 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E25E 1 ; Memory effects: $06, $41, mathtemp05
|
|
00E25E 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E25E 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E25E 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E25E 1 ; ----------------------------------------------------------------------------
|
|
00E25E 1 FindNearestCandidateObject: ; $E25E
|
|
00E25E 1 A9 FF lda #$FF ; $E25E: A9 FF
|
|
00E260 1 85 06 sta $06 ; $E260: 85 06
|
|
00E262 1 ; Initialize best distance to the maximum.
|
|
00E262 1
|
|
00E262 1 A2 05 ldx #$05 ; $E262: A2 05
|
|
00E264 1
|
|
00E264 1 ; ----------------------------------------------------------------------------
|
|
00E264 1 ; Save the current candidate-table index.
|
|
00E264 1 ; ----------------------------------------------------------------------------
|
|
00E264 1
|
|
00E264 1 FindNearestCandidateObject_Loop: ; $E264
|
|
00E264 1 86 41 stx $41 ; $E264: 86 41
|
|
00E266 1
|
|
00E266 1 ; ----------------------------------------------------------------------------
|
|
00E266 1 ; Load the candidate object offset into Y.
|
|
00E266 1 ; ----------------------------------------------------------------------------
|
|
00E266 1
|
|
00E266 1 BC 95 E2 ldy CandidateObjectOffsetTable,x
|
|
00E269 1 ; $E266: BC 95 E2
|
|
00E269 1
|
|
00E269 1 ; ----------------------------------------------------------------------------
|
|
00E269 1 ; Load the signed coordinate-adjustment index.
|
|
00E269 1 ; ----------------------------------------------------------------------------
|
|
00E269 1
|
|
00E269 1 A6 C2 ldx $C2 ; $E269: A6 C2
|
|
00E26B 1
|
|
00E26B 1 ; ----------------------------------------------------------------------------
|
|
00E26B 1 ; Calculate the adjusted horizontal high coordinate:
|
|
00E26B 1 ;
|
|
00E26B 1 ; candidateXHi + $DFCB,X
|
|
00E26B 1 ;
|
|
00E26B 1 ; The result is preserved on the stack.
|
|
00E26B 1 ; ----------------------------------------------------------------------------
|
|
00E26B 1
|
|
00E26B 1 18 clc ; $E26B: 18
|
|
00E26C 1
|
|
00E26C 1 B9 0A 05 lda $050A,y ; $E26C: B9 0A 05
|
|
00E26F 1 7D CB DF adc $DFCB,x ; $E26F: 7D CB DF
|
|
00E272 1
|
|
00E272 1 48 pha ; $E272: 48
|
|
00E273 1
|
|
00E273 1 ; ----------------------------------------------------------------------------
|
|
00E273 1 ; Calculate the adjusted vertical high coordinate:
|
|
00E273 1 ;
|
|
00E273 1 ; candidateYHi + $DFCA,X
|
|
00E273 1 ;
|
|
00E273 1 ; The result is passed to $E80B in Y.
|
|
00E273 1 ; ----------------------------------------------------------------------------
|
|
00E273 1
|
|
00E273 1 18 clc ; $E273: 18
|
|
00E274 1
|
|
00E274 1 B9 3B 05 lda $053B,y ; $E274: B9 3B 05
|
|
00E277 1 7D CA DF adc $DFCA,x ; $E277: 7D CA DF
|
|
00E27A 1
|
|
00E27A 1 A8 tay ; $E27A: A8
|
|
00E27B 1
|
|
00E27B 1 ; ----------------------------------------------------------------------------
|
|
00E27B 1 ; Restore the adjusted horizontal value into X and calculate a distance or
|
|
00E27B 1 ; magnitude through $E80B.
|
|
00E27B 1 ; ----------------------------------------------------------------------------
|
|
00E27B 1
|
|
00E27B 1 68 pla ; $E27B: 68
|
|
00E27C 1 AA tax ; $E27C: AA
|
|
00E27D 1
|
|
00E27D 1 20 0B E8 jsr CalculateVectorMagnitude ; $E27D: 20 0B E8
|
|
00E280 1
|
|
00E280 1 ; ----------------------------------------------------------------------------
|
|
00E280 1 ; Keep this candidate only when its returned distance in A is lower than the
|
|
00E280 1 ; current best distance in $06.
|
|
00E280 1 ; ----------------------------------------------------------------------------
|
|
00E280 1
|
|
00E280 1 C5 06 cmp $06 ; $E280: C5 06
|
|
00E282 1 B0 06 bcs FindNearestCandidateObject_Next
|
|
00E284 1 ; $E282: B0 06
|
|
00E284 1
|
|
00E284 1 85 06 sta $06 ; $E284: 85 06
|
|
00E286 1
|
|
00E286 1 A5 41 lda $41 ; $E286: A5 41
|
|
00E288 1 85 05 sta MathTemp05 ; $E288: 85 05
|
|
00E28A 1 ; Save the winning candidate-table index.
|
|
00E28A 1
|
|
00E28A 1 ; ----------------------------------------------------------------------------
|
|
00E28A 1 ; Continue through all six candidate entries, from index five down to zero.
|
|
00E28A 1 ; ----------------------------------------------------------------------------
|
|
00E28A 1
|
|
00E28A 1 FindNearestCandidateObject_Next: ; $E28A
|
|
00E28A 1 A6 41 ldx $41 ; $E28A: A6 41
|
|
00E28C 1 CA dex ; $E28C: CA
|
|
00E28D 1 10 D5 bpl FindNearestCandidateObject_Loop
|
|
00E28F 1 ; $E28D: 10 D5
|
|
00E28F 1
|
|
00E28F 1 ; ----------------------------------------------------------------------------
|
|
00E28F 1 ; Return the winning candidate-table index in X and its object offset in Y.
|
|
00E28F 1 ; ----------------------------------------------------------------------------
|
|
00E28F 1
|
|
00E28F 1 A6 05 ldx MathTemp05 ; $E28F: A6 05
|
|
00E291 1 BC 95 E2 ldy CandidateObjectOffsetTable,x
|
|
00E294 1 ; $E291: BC 95 E2
|
|
00E294 1
|
|
00E294 1 60 rts ; $E294: 60
|
|
00E295 1
|
|
00E295 1 ; ============================================================================
|
|
00E295 1 ; $E295-$E29A
|
|
00E295 1 ; Candidate object offsets searched by FindNearestCandidateObject.
|
|
00E295 1 ;
|
|
00E295 1 ; The values are even object-array offsets. Their compact indices are obtained
|
|
00E295 1 ; by dividing by two.
|
|
00E295 1 ; ============================================================================
|
|
00E295 1
|
|
00E295 1 CandidateObjectOffsetTable: ; $E295
|
|
00E295 1 04 .byte $04 ; Compact index $02
|
|
00E296 1 0E .byte $0E ; Compact index $07
|
|
00E297 1 10 .byte $10 ; Compact index $08
|
|
00E298 1 12 .byte $12 ; Compact index $09
|
|
00E299 1 14 .byte $14 ; Compact index $0A
|
|
00E29A 1 16 .byte $16 ; Compact index $0B
|
|
00E29B 1
|
|
00E29B 1 ; ============================================================================
|
|
00E29B 1 ; $E29B-$E2A4
|
|
00E29B 1 ; Dispatch an inline command for a caller-supplied object offset.
|
|
00E29B 1 ;
|
|
00E29B 1 ; Entry:
|
|
00E29B 1 ; X = object or event offset
|
|
00E29B 1 ;
|
|
00E29B 1 ; Inline caller data:
|
|
00E29B 1 ; The bytes immediately following the caller's JSR are interpreted by
|
|
00E29B 1 ; $E99A. Existing call sites provide records such as:
|
|
00E29B 1 ;
|
|
00E29B 1 ; .byte $00
|
|
00E29B 1 ; .word HandlerAddress - 1
|
|
00E29B 1 ;
|
|
00E29B 1 ; Operation:
|
|
00E29B 1 ; 1. Preserve X in zero-page $06.
|
|
00E29B 1 ; 2. Call $E99A to locate or decode the caller's inline data.
|
|
00E29B 1 ; 3. Restore X.
|
|
00E29B 1 ; 4. Tail-call the command dispatcher at $EB0D.
|
|
00E29B 1 ;
|
|
00E29B 1 ; The jump to $EB0D enters three bytes after the normal QueueInlineObjectEvent entry, which
|
|
00E29B 1 ; suggests $E99A has already completed the inline-record setup normally
|
|
00E29B 1 ; performed by QueueInlineObjectEvent.
|
|
00E29B 1 ; ============================================================================
|
|
00E29B 1
|
|
00E29B 1 ; ----------------------------------------------------------------------------
|
|
00E29B 1 ; Contract:
|
|
00E29B 1 ; Description: Implements Dispatch Inline Object Command.
|
|
00E29B 1 ; Entry: Registers: X; Memory: $06
|
|
00E29B 1 ; Returns/products: Registers/clobbers: X
|
|
00E29B 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E29B 1 ; Memory effects: $06
|
|
00E29B 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E29B 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E29B 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00E29B 1 ; ----------------------------------------------------------------------------
|
|
00E29B 1 DispatchInlineObjectCommand: ; $E29B
|
|
00E29B 1 86 06 stx $06 ; $E29B: 86 06
|
|
00E29D 1 ; Preserve the caller-supplied object offset.
|
|
00E29D 1
|
|
00E29D 1 20 9A E9 jsr DecodeInlineParameters ; $E29D: 20 9A E9
|
|
00E2A0 1 ; Decode or locate the inline record following
|
|
00E2A0 1 ; the caller's JSR.
|
|
00E2A0 1
|
|
00E2A0 1 A6 06 ldx $06 ; $E2A0: A6 06
|
|
00E2A2 1 ; Restore the object offset.
|
|
00E2A2 1
|
|
00E2A2 1 4C 0D EB jmp QueueDecodedObjectEvent ; $E2A2: 4C 0D EB
|
|
00E2A5 1 ; Tail-call the command dispatcher after its
|
|
00E2A5 1 ; normal inline-record setup entry.
|
|
00E2A5 1
|
|
00E2A5 1 ; ============================================================================
|
|
00E2A5 1 ; $E2A5-$E2D2
|
|
00E2A5 1 ; Calculate scaled coordinate differences between the base object and the
|
|
00E2A5 1 ; object selected by X.
|
|
00E2A5 1 ;
|
|
00E2A5 1 ; Entry:
|
|
00E2A5 1 ; X = object-array offset
|
|
00E2A5 1 ;
|
|
00E2A5 1 ; Exit:
|
|
00E2A5 1 ; A = scaled horizontal high/result byte
|
|
00E2A5 1 ; Y = scaled vertical high/result byte
|
|
00E2A5 1 ;
|
|
00E2A5 1 ; Working values:
|
|
00E2A5 1 ; $AE = horizontal low difference
|
|
00E2A5 1 ; $B0 = vertical low difference
|
|
00E2A5 1 ;
|
|
00E2A5 1 ; Both signed 16-bit differences are shifted left twice across their low and
|
|
00E2A5 1 ; high bytes. The low result bytes remain in $AE and $B0.
|
|
00E2A5 1 ; ============================================================================
|
|
00E2A5 1
|
|
00E2A5 1 CalculateObjectCoordinateDifference: ; $E2A5
|
|
00E2A5 1 38 sec ; $E2A5: 38
|
|
00E2A6 1
|
|
00E2A6 1 ; ----------------------------------------------------------------------------
|
|
00E2A6 1 ; Calculate the signed vertical difference:
|
|
00E2A6 1 ;
|
|
00E2A6 1 ; baseY - objectY
|
|
00E2A6 1 ;
|
|
00E2A6 1 ; Low byte:
|
|
00E2A6 1 ; $053A - $053A,X
|
|
00E2A6 1 ;
|
|
00E2A6 1 ; High byte:
|
|
00E2A6 1 ; $053B - $053B,X
|
|
00E2A6 1 ; ----------------------------------------------------------------------------
|
|
00E2A6 1
|
|
00E2A6 1 AD 3A 05 lda $053A ; $E2A6: AD 3A 05
|
|
00E2A9 1 FD 3A 05 sbc $053A,x ; $E2A9: FD 3A 05
|
|
00E2AC 1 85 B0 sta $B0 ; $E2AC: 85 B0
|
|
00E2AE 1
|
|
00E2AE 1 AD 3B 05 lda $053B ; $E2AE: AD 3B 05
|
|
00E2B1 1 FD 3B 05 sbc $053B,x ; $E2B1: FD 3B 05
|
|
00E2B4 1
|
|
00E2B4 1 ; ----------------------------------------------------------------------------
|
|
00E2B4 1 ; Multiply the signed vertical difference by four.
|
|
00E2B4 1 ;
|
|
00E2B4 1 ; First shift:
|
|
00E2B4 1 ; ASL $B0
|
|
00E2B4 1 ; ROL A
|
|
00E2B4 1 ;
|
|
00E2B4 1 ; Second shift:
|
|
00E2B4 1 ; ASL $B0
|
|
00E2B4 1 ; ADC #$00
|
|
00E2B4 1 ;
|
|
00E2B4 1 ; The second ADC incorporates carry from the low-byte shift into the high byte.
|
|
00E2B4 1 ; ----------------------------------------------------------------------------
|
|
00E2B4 1
|
|
00E2B4 1 06 B0 asl $B0 ; $E2B4: 06 B0
|
|
00E2B6 1 2A rol ; $E2B6: 2A
|
|
00E2B7 1
|
|
00E2B7 1 06 B0 asl $B0 ; $E2B7: 06 B0
|
|
00E2B9 1 69 00 adc #$00 ; $E2B9: 69 00
|
|
00E2BB 1
|
|
00E2BB 1 A8 tay ; $E2BB: A8
|
|
00E2BC 1 ; Y = scaled vertical high/result byte.
|
|
00E2BC 1
|
|
00E2BC 1 ; ----------------------------------------------------------------------------
|
|
00E2BC 1 ; Calculate the signed horizontal difference:
|
|
00E2BC 1 ;
|
|
00E2BC 1 ; baseX - objectX
|
|
00E2BC 1 ;
|
|
00E2BC 1 ; Low byte:
|
|
00E2BC 1 ; $0509 - $0509,X
|
|
00E2BC 1 ;
|
|
00E2BC 1 ; High byte:
|
|
00E2BC 1 ; $050A - $050A,X
|
|
00E2BC 1 ; ----------------------------------------------------------------------------
|
|
00E2BC 1
|
|
00E2BC 1 38 sec ; $E2BC: 38
|
|
00E2BD 1
|
|
00E2BD 1 AD 09 05 lda $0509 ; $E2BD: AD 09 05
|
|
00E2C0 1 FD 09 05 sbc $0509,x ; $E2C0: FD 09 05
|
|
00E2C3 1 85 AE sta CalculatedCoordinateLow ; $E2C3: 85 AE
|
|
00E2C5 1
|
|
00E2C5 1 AD 0A 05 lda $050A ; $E2C5: AD 0A 05
|
|
00E2C8 1 FD 0A 05 sbc $050A,x ; $E2C8: FD 0A 05
|
|
00E2CB 1
|
|
00E2CB 1 ; ----------------------------------------------------------------------------
|
|
00E2CB 1 ; Multiply the signed horizontal difference by four.
|
|
00E2CB 1 ; ----------------------------------------------------------------------------
|
|
00E2CB 1
|
|
00E2CB 1 06 AE asl CalculatedCoordinateLow ; $E2CB: 06 AE
|
|
00E2CD 1 2A rol ; $E2CD: 2A
|
|
00E2CE 1
|
|
00E2CE 1 06 AE asl CalculatedCoordinateLow ; $E2CE: 06 AE
|
|
00E2D0 1 69 00 adc #$00 ; $E2D0: 69 00
|
|
00E2D2 1
|
|
00E2D2 1 60 rts ; $E2D2: 60
|
|
00E2D3 1
|
|
00E2D3 1 ; ============================================================================
|
|
00E2D3 1 ; $E2D3-$E2DF
|
|
00E2D3 1 ; Clear the current object's two movement or velocity state bytes.
|
|
00E2D3 1 ;
|
|
00E2D3 1 ; Entry:
|
|
00E2D3 1 ; CurrentObjectIndex = object-array offset
|
|
00E2D3 1 ;
|
|
00E2D3 1 ; Exit:
|
|
00E2D3 1 ; A = $00
|
|
00E2D3 1 ; X = CurrentObjectIndex
|
|
00E2D3 1 ; Z = set
|
|
00E2D3 1 ;
|
|
00E2D3 1 ; Modified object fields:
|
|
00E2D3 1 ; $056D,X = $00
|
|
00E2D3 1 ; $056E,X = $00
|
|
00E2D3 1 ; ============================================================================
|
|
00E2D3 1
|
|
00E2D3 1 ; ----------------------------------------------------------------------------
|
|
00E2D3 1 ; Contract:
|
|
00E2D3 1 ; Description: Clears or resets Current Object Movement.
|
|
00E2D3 1 ; Entry: Registers: A; Memory: currentobjectindex
|
|
00E2D3 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E2D3 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E2D3 1 ; Memory effects: $056d, $056e
|
|
00E2D3 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E2D3 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E2D3 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 8.
|
|
00E2D3 1 ; ----------------------------------------------------------------------------
|
|
00E2D3 1 ClearCurrentObjectMovement: ; $E2D3
|
|
00E2D3 1 A6 E1 ldx CurrentObjectIndex ; $E2D3: A6 E1
|
|
00E2D5 1
|
|
00E2D5 1 A9 00 lda #$00 ; $E2D5: A9 00
|
|
00E2D7 1 9D 6D 05 sta $056D,x ; $E2D7: 9D 6D 05
|
|
00E2DA 1 9D 6E 05 sta $056E,x ; $E2DA: 9D 6E 05
|
|
00E2DD 1
|
|
00E2DD 1 60 rts ; $E2DD: 60
|
|
00E2DE 1
|
|
00E2DE 1 ; ============================================================================
|
|
00E2DE 1 ; $E2DE-$E312
|
|
00E2DE 1 ; Update the current object's animation frame and return a delay selected from
|
|
00E2DE 1 ; a table.
|
|
00E2DE 1 ;
|
|
00E2DE 1 ; Entry:
|
|
00E2DE 1 ; CurrentObjectIndex = object-array offset
|
|
00E2DE 1 ;
|
|
00E2DE 1 ; Return:
|
|
00E2DE 1 ; A = selector-specific delay from $E329,Y
|
|
00E2DE 1 ;
|
|
00E2DE 1 ; If either call to $E6B7 returns carry set:
|
|
00E2DE 1 ; A = $06
|
|
00E2DE 1 ; ============================================================================
|
|
00E2DE 1
|
|
00E2DE 1 ; ----------------------------------------------------------------------------
|
|
00E2DE 1 ; Contract:
|
|
00E2DE 1 ; Description: Updates Current Object Animation Delay.
|
|
00E2DE 1 ; Entry: Registers: A, X; Memory: currentobjectindex, $056e, $056d, $039a
|
|
00E2DE 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E2DE 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E2DE 1 ; Memory effects: $039a
|
|
00E2DE 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E2DE 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E2DE 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 4.
|
|
00E2DE 1 ; ----------------------------------------------------------------------------
|
|
00E2DE 1 UpdateCurrentObjectAnimationDelay: ; $E2DE
|
|
00E2DE 1 A6 E1 ldx CurrentObjectIndex ; $E2DE: A6 E1
|
|
00E2E0 1
|
|
00E2E0 1 ; ----------------------------------------------------------------------------
|
|
00E2E0 1 ; Derive a preliminary three-bit animation selector from the current object's
|
|
00E2E0 1 ; state bytes at $056D/$056E.
|
|
00E2E0 1 ;
|
|
00E2E0 1 ; Bit flow:
|
|
00E2E0 1 ;
|
|
00E2E0 1 ; ASL $056E,X puts its high bit in carry.
|
|
00E2E0 1 ; ROL $056D,X shifts that carry into A.
|
|
00E2E0 1 ; A second ROL expands the selector.
|
|
00E2E0 1 ; ----------------------------------------------------------------------------
|
|
00E2E0 1
|
|
00E2E0 1 BD 6E 05 lda $056E,x ; $E2E0: BD 6E 05
|
|
00E2E3 1 0A asl ; $E2E3: 0A
|
|
00E2E4 1
|
|
00E2E4 1 BD 6D 05 lda $056D,x ; $E2E4: BD 6D 05
|
|
00E2E7 1 2A rol ; $E2E7: 2A
|
|
00E2E8 1 2A rol ; $E2E8: 2A
|
|
00E2E9 1
|
|
00E2E9 1 48 pha ; $E2E9: 48
|
|
00E2EA 1 ; Preserve the preliminary selector.
|
|
00E2EA 1
|
|
00E2EA 1 ; ----------------------------------------------------------------------------
|
|
00E2EA 1 ; Update or test the current object through $E6B7.
|
|
00E2EA 1 ; ----------------------------------------------------------------------------
|
|
00E2EA 1
|
|
00E2EA 1 20 B7 E6 jsr ClearMovementTransforms ; $E2EA: 20 B7 E6
|
|
00E2ED 1
|
|
00E2ED 1 68 pla ; $E2ED: 68
|
|
00E2EE 1 B0 20 bcs UpdateCurrentObjectAnimationDelay_Default
|
|
00E2F0 1 ; $E2EE: B0 20
|
|
00E2F0 1
|
|
00E2F0 1 ; ----------------------------------------------------------------------------
|
|
00E2F0 1 ; Incorporate whether X is at least $15 into the selector.
|
|
00E2F0 1 ;
|
|
00E2F0 1 ; CPX sets carry, then ROL shifts that condition into A.
|
|
00E2F0 1 ; ----------------------------------------------------------------------------
|
|
00E2F0 1
|
|
00E2F0 1 E0 15 cpx #$15 ; $E2F0: E0 15
|
|
00E2F2 1 2A rol ; $E2F2: 2A
|
|
00E2F3 1
|
|
00E2F3 1 29 07 and #$07 ; $E2F3: 29 07
|
|
00E2F5 1 A8 tay ; $E2F5: A8
|
|
00E2F6 1 ; Y selects one of eight animation ranges.
|
|
00E2F6 1
|
|
00E2F6 1 ; ----------------------------------------------------------------------------
|
|
00E2F6 1 ; Increment the current frame while preserving its original value in A for
|
|
00E2F6 1 ; the range comparisons.
|
|
00E2F6 1 ; ----------------------------------------------------------------------------
|
|
00E2F6 1
|
|
00E2F6 1 BD 9A 03 lda $039A,x ; $E2F6: BD 9A 03
|
|
00E2F9 1 FE 9A 03 inc $039A,x ; $E2F9: FE 9A 03
|
|
00E2FC 1
|
|
00E2FC 1 ; ----------------------------------------------------------------------------
|
|
00E2FC 1 ; If the original frame is at or beyond its upper limit, reset it to the base
|
|
00E2FC 1 ; frame.
|
|
00E2FC 1 ;
|
|
00E2FC 1 ; If it is between the base and upper limit, keep the incremented frame.
|
|
00E2FC 1 ;
|
|
00E2FC 1 ; If it is below the base frame, reset it to the base frame.
|
|
00E2FC 1 ; ----------------------------------------------------------------------------
|
|
00E2FC 1
|
|
00E2FC 1 D9 21 E3 cmp CurrentObjectAnimationLimitTable,y
|
|
00E2FF 1 ; $E2FC: D9 21 E3
|
|
00E2FF 1 B0 05 bcs UpdateCurrentObjectAnimationDelay_Reset
|
|
00E301 1 ; $E2FF: B0 05
|
|
00E301 1
|
|
00E301 1 D9 19 E3 cmp CurrentObjectAnimationBaseTable,y
|
|
00E304 1 ; $E301: D9 19 E3
|
|
00E304 1 B0 06 bcs UpdateCurrentObjectAnimationDelay_LoadDelay
|
|
00E306 1 ; $E304: B0 06
|
|
00E306 1
|
|
00E306 1 UpdateCurrentObjectAnimationDelay_Reset: ; $E306
|
|
00E306 1 B9 19 E3 lda CurrentObjectAnimationBaseTable,y
|
|
00E309 1 ; $E306: B9 19 E3
|
|
00E309 1 9D 9A 03 sta $039A,x ; $E309: 9D 9A 03
|
|
00E30C 1
|
|
00E30C 1 ; ----------------------------------------------------------------------------
|
|
00E30C 1 ; Return the delay associated with this animation range.
|
|
00E30C 1 ; ----------------------------------------------------------------------------
|
|
00E30C 1
|
|
00E30C 1 UpdateCurrentObjectAnimationDelay_LoadDelay: ; $E30C
|
|
00E30C 1 B9 29 E3 lda CurrentObjectAnimationDelayTable,y
|
|
00E30F 1 ; $E30C: B9 29 E3
|
|
00E30F 1 60 rts ; $E30F: 60
|
|
00E310 1
|
|
00E310 1 ; ----------------------------------------------------------------------------
|
|
00E310 1 ; Carry-set fallback from $E6B7.
|
|
00E310 1 ; ----------------------------------------------------------------------------
|
|
00E310 1
|
|
00E310 1 UpdateCurrentObjectAnimationDelay_Default: ; $E310
|
|
00E310 1 A9 06 lda #$06 ; $E310: A9 06
|
|
00E312 1 60 rts ; $E312: 60
|
|
00E313 1
|
|
00E313 1 ; ============================================================================
|
|
00E313 1 ; $E313-$E318
|
|
00E313 1 ; Update the current object's animation and immediately wait for the returned
|
|
00E313 1 ; delay.
|
|
00E313 1 ;
|
|
00E313 1 ; This is a compact wrapper around UpdateCurrentObjectAnimationDelay and
|
|
00E313 1 ; $EB41.
|
|
00E313 1 ; ============================================================================
|
|
00E313 1
|
|
00E313 1 ; ----------------------------------------------------------------------------
|
|
00E313 1 ; Contract:
|
|
00E313 1 ; Description: Updates Current Object Animation And Wait.
|
|
00E313 1 ; Entry: No register input inferred
|
|
00E313 1 ; Returns/products: No direct product inferred
|
|
00E313 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E313 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E313 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E313 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E313 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00E313 1 ; ----------------------------------------------------------------------------
|
|
00E313 1 UpdateCurrentObjectAnimationAndWait: ; $E313
|
|
00E313 1 20 DE E2 jsr UpdateCurrentObjectAnimationDelay
|
|
00E316 1 ; $E313: 20 DE E2
|
|
00E316 1
|
|
00E316 1 4C 41 EB jmp StoreObjectEventBankValue ; $E316: 4C 41 EB
|
|
00E319 1 ; Tail-call the delay helper.
|
|
00E319 1
|
|
00E319 1 ; ============================================================================
|
|
00E319 1 ; $E319-$E320
|
|
00E319 1 ; Base/reset frames for the eight current-object animation ranges.
|
|
00E319 1 ; ============================================================================
|
|
00E319 1
|
|
00E319 1 CurrentObjectAnimationBaseTable: ; $E319
|
|
00E319 1 61 32 64 35 .byte $61,$32,$64,$35
|
|
00E31D 1 5C 3B 5C 38 .byte $5C,$3B,$5C,$38
|
|
00E321 1
|
|
00E321 1 ; ============================================================================
|
|
00E321 1 ; $E321-$E328
|
|
00E321 1 ; Exclusive upper frame limits for the eight animation ranges.
|
|
00E321 1 ; ============================================================================
|
|
00E321 1
|
|
00E321 1 CurrentObjectAnimationLimitTable: ; $E321
|
|
00E321 1 63 34 66 37 .byte $63,$34,$66,$37
|
|
00E325 1 5D 3D 5D 3A .byte $5D,$3D,$5D,$3A
|
|
00E329 1
|
|
00E329 1 ; ============================================================================
|
|
00E329 1 ; $E329-$E330
|
|
00E329 1 ; Delay values associated with the eight animation ranges.
|
|
00E329 1 ; ============================================================================
|
|
00E329 1
|
|
00E329 1 CurrentObjectAnimationDelayTable: ; $E329
|
|
00E329 1 06 06 06 06 .byte $06,$06,$06,$06
|
|
00E32D 1 09 06 09 06 .byte $09,$06,$09,$06
|
|
00E331 1
|
|
00E331 1 ; ============================================================================
|
|
00E331 1 ; $E331-$E346
|
|
00E331 1 ; Find an object-state entry equal to twice the selected compact state.
|
|
00E331 1 ;
|
|
00E331 1 ; Entry:
|
|
00E331 1 ; $C2 = compact state value
|
|
00E331 1 ;
|
|
00E331 1 ; Search:
|
|
00E331 1 ; $059B, $059A, $0599, $0598
|
|
00E331 1 ;
|
|
00E331 1 ; If a matching entry is found:
|
|
00E331 1 ; 1. Copy $C2 to StateSelector.
|
|
00E331 1 ; 2. Call the state-marker helper at $CD2E.
|
|
00E331 1 ;
|
|
00E331 1 ; If no entry matches:
|
|
00E331 1 ; Return without changing StateSelector.
|
|
00E331 1 ;
|
|
00E331 1 ; Exit:
|
|
00E331 1 ; X = matching object-state index, or $FF if no match was found
|
|
00E331 1 ; ============================================================================
|
|
00E331 1
|
|
00E331 1 ; ----------------------------------------------------------------------------
|
|
00E331 1 ; Contract:
|
|
00E331 1 ; Description: Implements Find And Queue Selected State.
|
|
00E331 1 ; Entry: Registers: A, X; Memory: $c2, $0598
|
|
00E331 1 ; Returns/products: Registers/clobbers: A, X; Flags: condition flags may carry result state
|
|
00E331 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E331 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E331 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E331 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E331 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E331 1 ; ----------------------------------------------------------------------------
|
|
00E331 1 FindAndQueueSelectedState: ; $E331
|
|
00E331 1 A2 03 ldx #$03 ; $E331: A2 03
|
|
00E333 1
|
|
00E333 1 ; ----------------------------------------------------------------------------
|
|
00E333 1 ; Double the compact state value.
|
|
00E333 1 ;
|
|
00E333 1 ; The loop branches back to the CMP at $E336, not to LDA/ASL. The doubled
|
|
00E333 1 ; value therefore remains in A for all four comparisons.
|
|
00E333 1 ; ----------------------------------------------------------------------------
|
|
00E333 1
|
|
00E333 1 A5 C2 lda $C2 ; $E333: A5 C2
|
|
00E335 1 0A asl ; $E335: 0A
|
|
00E336 1
|
|
00E336 1 FindAndQueueSelectedState_Search: ; $E336
|
|
00E336 1 DD 98 05 cmp $0598,x ; $E336: DD 98 05
|
|
00E339 1 F0 04 beq FindAndQueueSelectedState_Found
|
|
00E33B 1 ; $E339: F0 04
|
|
00E33B 1
|
|
00E33B 1 CA dex ; $E33B: CA
|
|
00E33C 1 10 F8 bpl FindAndQueueSelectedState_Search
|
|
00E33E 1 ; $E33C: 10 F8
|
|
00E33E 1
|
|
00E33E 1 ; ----------------------------------------------------------------------------
|
|
00E33E 1 ; No matching state entry was found.
|
|
00E33E 1 ; ----------------------------------------------------------------------------
|
|
00E33E 1
|
|
00E33E 1 60 rts ; $E33E: 60
|
|
00E33F 1
|
|
00E33F 1 ; ----------------------------------------------------------------------------
|
|
00E33F 1 ; Matching entry found.
|
|
00E33F 1 ;
|
|
00E33F 1 ; Restore the undoubled state value from $C2, save it in StateSelector, and
|
|
00E33F 1 ; invoke the state-marker helper at $CD2E.
|
|
00E33F 1 ; ----------------------------------------------------------------------------
|
|
00E33F 1
|
|
00E33F 1 FindAndQueueSelectedState_Found: ; $E33F
|
|
00E33F 1 A5 C2 lda $C2 ; $E33F: A5 C2
|
|
00E341 1 85 72 sta StateSelector ; $E341: 85 72
|
|
00E343 1
|
|
00E343 1 20 2E CD jsr QueueSelectedStateMarker ; $E343: 20 2E CD
|
|
00E346 1
|
|
00E346 1 60 rts ; $E346: 60
|
|
00E347 1
|
|
00E347 1 ; ============================================================================
|
|
00E347 1 ; $E347-$E3AB
|
|
00E347 1 ; Validate and consume the compact object-state selected in $C2.
|
|
00E347 1 ;
|
|
00E347 1 ; The routine inspects the corresponding entries in $0598-$059B and $95-$98,
|
|
00E347 1 ; may search for an alternate state, updates PendingScoreIncrement, marks an object
|
|
00E347 1 ; state inactive, and advances the alternate state sequence.
|
|
00E347 1 ;
|
|
00E347 1 ; Entry:
|
|
00E347 1 ; $C2 = compact object-state index
|
|
00E347 1 ; ============================================================================
|
|
00E347 1
|
|
00E347 1 ; ----------------------------------------------------------------------------
|
|
00E347 1 ; Contract:
|
|
00E347 1 ; Description: Processes Compact Object State.
|
|
00E347 1 ; Entry: Registers: A, X, Y; Memory: $c2, $0598, $95, objecttransitionstate, secondarysequencestate, $c3
|
|
00E347 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E347 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E347 1 ; Memory effects: $c3, $c2, $96, $97, $98, pendingscoreincrement
|
|
00E347 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E347 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E347 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E347 1 ; ----------------------------------------------------------------------------
|
|
00E347 1 ProcessCompactObjectState: ; $E347
|
|
00E347 1 A6 C2 ldx $C2 ; $E347: A6 C2
|
|
00E349 1
|
|
00E349 1 ; ----------------------------------------------------------------------------
|
|
00E349 1 ; Compact state values of four or greater are rejected.
|
|
00E349 1 ; ----------------------------------------------------------------------------
|
|
00E349 1
|
|
00E349 1 E0 04 cpx #$04 ; $E349: E0 04
|
|
00E34B 1 B0 5E bcs ProcessCompactObjectState_Return
|
|
00E34D 1 ; $E34B: B0 5E
|
|
00E34D 1
|
|
00E34D 1 ; ----------------------------------------------------------------------------
|
|
00E34D 1 ; Reject inactive state-table entries.
|
|
00E34D 1 ; ----------------------------------------------------------------------------
|
|
00E34D 1
|
|
00E34D 1 BD 98 05 lda $0598,x ; $E34D: BD 98 05
|
|
00E350 1 30 59 bmi ProcessCompactObjectState_Return
|
|
00E352 1 ; $E350: 30 59
|
|
00E352 1
|
|
00E352 1 ; ----------------------------------------------------------------------------
|
|
00E352 1 ; Reject entries whose corresponding zero-page state at $95-$98 is nonzero.
|
|
00E352 1 ; ----------------------------------------------------------------------------
|
|
00E352 1
|
|
00E352 1 B5 95 lda $95,x ; $E352: B5 95
|
|
00E354 1 D0 55 bne ProcessCompactObjectState_Return
|
|
00E356 1 ; $E354: D0 55
|
|
00E356 1
|
|
00E356 1 ; ----------------------------------------------------------------------------
|
|
00E356 1 ; Preserve the selected compact index.
|
|
00E356 1 ;
|
|
00E356 1 ; Index zero uses the shared PendingScoreIncrement path at $E380.
|
|
00E356 1 ; ----------------------------------------------------------------------------
|
|
00E356 1
|
|
00E356 1 86 C3 stx $C3 ; $E356: 86 C3
|
|
00E358 1 F0 26 beq ProcessCompactObjectState_SavePending
|
|
00E35A 1 ; $E358: F0 26
|
|
00E35A 1
|
|
00E35A 1 ; ============================================================================
|
|
00E35A 1 ; $E35A
|
|
00E35A 1 ; Search for an alternate state entry.
|
|
00E35A 1 ; ============================================================================
|
|
00E35A 1
|
|
00E35A 1 ; ----------------------------------------------------------------------------
|
|
00E35A 1 ; Contract:
|
|
00E35A 1 ; Description: Processes Compact Object State Find Alternate.
|
|
00E35A 1 ; Entry: Registers: A, X, Y; Memory: $c2, objecttransitionstate, secondarysequencestate, $c3, $0598
|
|
00E35A 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E35A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E35A 1 ; Memory effects: $c2, $c3, $96, $97, $98, pendingscoreincrement
|
|
00E35A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E35A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E35A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E35A 1 ; ----------------------------------------------------------------------------
|
|
00E35A 1 ProcessCompactObjectState_FindAlternate: ; $E35A
|
|
00E35A 1 A9 04 lda #$04 ; $E35A: A9 04
|
|
00E35C 1 85 C2 sta $C2 ; $E35C: 85 C2
|
|
00E35E 1
|
|
00E35E 1 A9 00 lda #$00 ; $E35E: A9 00
|
|
00E360 1 85 C3 sta $C3 ; $E360: 85 C3
|
|
00E362 1
|
|
00E362 1 85 96 sta $96 ; $E362: 85 96
|
|
00E364 1 85 97 sta $97 ; $E364: 85 97
|
|
00E366 1 85 98 sta $98 ; $E366: 85 98
|
|
00E368 1
|
|
00E368 1 ; ----------------------------------------------------------------------------
|
|
00E368 1 ; A is zero, so this branch is always taken to the state comparison at $E379.
|
|
00E368 1 ;
|
|
00E368 1 ; The entry at $E36A is also called directly by earlier code.
|
|
00E368 1 ; ----------------------------------------------------------------------------
|
|
00E368 1
|
|
00E368 1 F0 0F beq ProcessCompactObjectState_CompareState64
|
|
00E36A 1 ; $E368: F0 0F
|
|
00E36A 1
|
|
00E36A 1 ; ============================================================================
|
|
00E36A 1 ; $E36A
|
|
00E36A 1 ; Alternate entry used by the main object-state dispatcher.
|
|
00E36A 1 ;
|
|
00E36A 1 ; Test whether the selector derived from $C2 has a valid matching object state.
|
|
00E36A 1 ; ============================================================================
|
|
00E36A 1
|
|
00E36A 1 ; ----------------------------------------------------------------------------
|
|
00E36A 1 ; Contract:
|
|
00E36A 1 ; Description: Processes Compact Object State Test Selector.
|
|
00E36A 1 ; Entry: Registers: A, X, Y; Memory: $c2, objecttransitionstate, secondarysequencestate, $c3, $0598
|
|
00E36A 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E36A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E36A 1 ; Memory effects: $c3, pendingscoreincrement, $c2, $0598, stateselector
|
|
00E36A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E36A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E36A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E36A 1 ; ----------------------------------------------------------------------------
|
|
00E36A 1 ProcessCompactObjectState_TestSelector: ; $E36A
|
|
00E36A 1 A4 C2 ldy $C2 ; $E36A: A4 C2
|
|
00E36C 1 88 dey ; $E36C: 88
|
|
00E36D 1 84 C3 sty $C3 ; $E36D: 84 C3
|
|
00E36F 1 C8 iny ; $E36F: C8
|
|
00E370 1
|
|
00E370 1 20 46 E2 jsr FindObjectStateForSelector
|
|
00E373 1 ; $E370: 20 46 E2
|
|
00E373 1
|
|
00E373 1 10 36 bpl ProcessCompactObjectState_Return
|
|
00E375 1 ; $E373: 10 36
|
|
00E375 1
|
|
00E375 1 A5 6E lda ObjectTransitionState ; $E375: A5 6E
|
|
00E377 1 D0 32 bne ProcessCompactObjectState_Return
|
|
00E379 1 ; $E377: D0 32
|
|
00E379 1
|
|
00E379 1 ; ----------------------------------------------------------------------------
|
|
00E379 1 ; Compare SecondarySequenceState against two.
|
|
00E379 1 ;
|
|
00E379 1 ; The subtraction result becomes the value stored in PendingScoreIncrement.
|
|
00E379 1 ; ----------------------------------------------------------------------------
|
|
00E379 1
|
|
00E379 1 ProcessCompactObjectState_CompareState64: ; $E379
|
|
00E379 1 38 sec ; $E379: 38
|
|
00E37A 1
|
|
00E37A 1 A5 64 lda SecondarySequenceState ; $E37A: A5 64
|
|
00E37C 1 E9 02 sbc #$02 ; $E37C: E9 02
|
|
00E37E 1 D0 1D bne ProcessCompactObjectState_Consume
|
|
00E380 1 ; $E37E: D0 1D
|
|
00E380 1
|
|
00E380 1 ; ----------------------------------------------------------------------------
|
|
00E380 1 ; Store the subtraction result in PendingScoreIncrement.
|
|
00E380 1 ;
|
|
00E380 1 ; Entry from $E358 uses A from LDA $95,X, which is known to be zero.
|
|
00E380 1 ; Therefore both paths normally store zero.
|
|
00E380 1 ; ----------------------------------------------------------------------------
|
|
00E380 1
|
|
00E380 1 ProcessCompactObjectState_SavePending: ; $E380
|
|
00E380 1 85 65 sta PendingScoreIncrement ; $E380: 85 65
|
|
00E382 1 F0 19 beq ProcessCompactObjectState_Consume
|
|
00E384 1 ; $E382: F0 19
|
|
00E384 1
|
|
00E384 1 ; ============================================================================
|
|
00E384 1 ; $E384
|
|
00E384 1 ; Validate the selected state when ObjectTransitionState is nonzero.
|
|
00E384 1 ;
|
|
00E384 1 ; This entry is also called independently from $E240.
|
|
00E384 1 ; ============================================================================
|
|
00E384 1
|
|
00E384 1 ; ----------------------------------------------------------------------------
|
|
00E384 1 ; Contract:
|
|
00E384 1 ; Description: Processes Compact Object State Validate.
|
|
00E384 1 ; Entry: Registers: A, X, Y; Memory: objecttransitionstate, $c3, $0598, $c2
|
|
00E384 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E384 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E384 1 ; Memory effects: $c2, $0598, stateselector
|
|
00E384 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E384 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E384 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E384 1 ; ----------------------------------------------------------------------------
|
|
00E384 1 ProcessCompactObjectState_Validate: ; $E384
|
|
00E384 1 A5 6E lda ObjectTransitionState ; $E384: A5 6E
|
|
00E386 1 F0 09 beq ProcessCompactObjectState_LoadEntry
|
|
00E388 1 ; $E386: F0 09
|
|
00E388 1
|
|
00E388 1 A5 C3 lda $C3 ; $E388: A5 C3
|
|
00E38A 1 A8 tay ; $E38A: A8
|
|
00E38B 1 C8 iny ; $E38B: C8
|
|
00E38C 1
|
|
00E38C 1 20 46 E2 jsr FindObjectStateForSelector
|
|
00E38F 1 ; $E38C: 20 46 E2
|
|
00E38F 1
|
|
00E38F 1 30 1A bmi ProcessCompactObjectState_Return
|
|
00E391 1 ; $E38F: 30 1A
|
|
00E391 1
|
|
00E391 1 ; ----------------------------------------------------------------------------
|
|
00E391 1 ; Load the selected state entry, divide it by two, and save the compact result
|
|
00E391 1 ; in $C2.
|
|
00E391 1 ; ----------------------------------------------------------------------------
|
|
00E391 1
|
|
00E391 1 ProcessCompactObjectState_LoadEntry: ; $E391
|
|
00E391 1 A6 C3 ldx $C3 ; $E391: A6 C3
|
|
00E393 1
|
|
00E393 1 BD 98 05 lda $0598,x ; $E393: BD 98 05
|
|
00E396 1 4A lsr ; $E396: 4A
|
|
00E397 1 85 C2 sta $C2 ; $E397: 85 C2
|
|
00E399 1
|
|
00E399 1 ; ----------------------------------------------------------------------------
|
|
00E399 1 ; If the original state byte was even, carry is clear and processing branches
|
|
00E399 1 ; backward to the found path in FindAndQueueSelectedState at $E33F.
|
|
00E399 1 ; ----------------------------------------------------------------------------
|
|
00E399 1
|
|
00E399 1 90 A4 bcc FindAndQueueSelectedState_Found
|
|
00E39B 1 ; $E399: 90 A4
|
|
00E39B 1
|
|
00E39B 1 ; ----------------------------------------------------------------------------
|
|
00E39B 1 ; Odd state values increment the compact state before being consumed.
|
|
00E39B 1 ; ----------------------------------------------------------------------------
|
|
00E39B 1
|
|
00E39B 1 E6 C2 inc $C2 ; $E39B: E6 C2
|
|
00E39D 1
|
|
00E39D 1 ; ============================================================================
|
|
00E39D 1 ; $E39D
|
|
00E39D 1 ; Mark the selected object-state entry inactive and advance the state sequence.
|
|
00E39D 1 ; ============================================================================
|
|
00E39D 1
|
|
00E39D 1 ProcessCompactObjectState_Consume: ; $E39D
|
|
00E39D 1 A6 C3 ldx $C3 ; $E39D: A6 C3
|
|
00E39F 1
|
|
00E39F 1 A9 FF lda #$FF ; $E39F: A9 FF
|
|
00E3A1 1 9D 98 05 sta $0598,x ; $E3A1: 9D 98 05
|
|
00E3A4 1
|
|
00E3A4 1 A6 C2 ldx $C2 ; $E3A4: A6 C2
|
|
00E3A6 1 86 72 stx StateSelector ; $E3A6: 86 72
|
|
00E3A8 1
|
|
00E3A8 1 20 E4 CC jsr AdvanceAlternateStateSequence
|
|
00E3AB 1 ; $E3A8: 20 E4 CC
|
|
00E3AB 1 ; Advance the alternate state sequence.
|
|
00E3AB 1
|
|
00E3AB 1 ProcessCompactObjectState_Return: ; $E3AB
|
|
00E3AB 1 60 rts ; $E3AB: 60
|
|
00E3AC 1
|
|
00E3AC 1 ; ============================================================================
|
|
00E3AC 1 ; $E3AC-$E3DB
|
|
00E3AC 1 ; Run the selected object's geometry and animation transition.
|
|
00E3AC 1 ;
|
|
00E3AC 1 ; The routine:
|
|
00E3AC 1 ; 1. Initializes geometry or object state through $E59D.
|
|
00E3AC 1 ; 2. Repeats the geometry test until it clears.
|
|
00E3AC 1 ; 3. Updates the current object's display state.
|
|
00E3AC 1 ; 4. Waits until the test at $E57E returns carry clear.
|
|
00E3AC 1 ; 5. Resets shared state and returns to the main object dispatcher.
|
|
00E3AC 1 ; ============================================================================
|
|
00E3AC 1
|
|
00E3AC 1 RunSelectedObjectTransition: ; $E3AC
|
|
00E3AC 1 20 9D E5 jsr InitializeSharedObjectMotion ; $E3AC: 20 9D E5
|
|
00E3AF 1
|
|
00E3AF 1 ; ----------------------------------------------------------------------------
|
|
00E3AF 1 ; Prepare and test the current object's geometry.
|
|
00E3AF 1 ;
|
|
00E3AF 1 ; Carry set runs the animation-and-wait helper at $E313, then retries from
|
|
00E3AF 1 ; $E3AF. Carry clear continues with display-state processing.
|
|
00E3AF 1 ; ----------------------------------------------------------------------------
|
|
00E3AF 1
|
|
00E3AF 1 RunSelectedObjectTransition_TestGeometry: ; $E3AF
|
|
00E3AF 1 20 74 E4 jsr SelectGeometryRecord_Default ; $E3AF: 20 74 E4
|
|
00E3B2 1 20 5F E5 jsr ApplyCurrentObjectGeometry ; $E3B2: 20 5F E5
|
|
00E3B5 1
|
|
00E3B5 1 90 06 bcc RunSelectedObjectTransition_GeometryClear
|
|
00E3B7 1 ; $E3B5: 90 06
|
|
00E3B7 1
|
|
00E3B7 1 20 13 E3 jsr UpdateCurrentObjectAnimationAndWait
|
|
00E3BA 1 ; $E3B7: 20 13 E3
|
|
00E3BA 1
|
|
00E3BA 1 4C AF E3 jmp RunSelectedObjectTransition_TestGeometry
|
|
00E3BD 1 ; $E3BA: 4C AF E3
|
|
00E3BD 1
|
|
00E3BD 1 ; ----------------------------------------------------------------------------
|
|
00E3BD 1 ; Geometry cleared. Update the current object's display state.
|
|
00E3BD 1 ; ----------------------------------------------------------------------------
|
|
00E3BD 1
|
|
00E3BD 1 RunSelectedObjectTransition_GeometryClear: ; $E3BD
|
|
00E3BD 1 20 D4 DF jsr UpdateCurrentObjectDisplayState
|
|
00E3C0 1 ; $E3BD: 20 D4 DF
|
|
00E3C0 1
|
|
00E3C0 1 ; ----------------------------------------------------------------------------
|
|
00E3C0 1 ; Wait three ticks, then test the condition at $E57E.
|
|
00E3C0 1 ;
|
|
00E3C0 1 ; Carry set repeats the delay and test. Carry clear completes the transition.
|
|
00E3C0 1 ; ----------------------------------------------------------------------------
|
|
00E3C0 1
|
|
00E3C0 1 RunSelectedObjectTransition_WaitLoop: ; $E3C0
|
|
00E3C0 1 A9 03 lda #$03 ; $E3C0: A9 03
|
|
00E3C2 1 20 41 EB jsr StoreObjectEventBankValue ; $E3C2: 20 41 EB
|
|
00E3C5 1
|
|
00E3C5 1 20 7E E5 jsr ApplyBaseObjectGeometry ; $E3C5: 20 7E E5
|
|
00E3C8 1 B0 F6 bcs RunSelectedObjectTransition_WaitLoop
|
|
00E3CA 1 ; $E3C8: B0 F6
|
|
00E3CA 1
|
|
00E3CA 1 ; ----------------------------------------------------------------------------
|
|
00E3CA 1 ; Set the shared engine flags and clear the selector remapping state.
|
|
00E3CA 1 ; ----------------------------------------------------------------------------
|
|
00E3CA 1
|
|
00E3CA 1 A9 20 lda #$20 ; $E3CA: A9 20
|
|
00E3CC 1 85 FE sta PendingAudioFlags ; $E3CC: 85 FE
|
|
00E3CE 1
|
|
00E3CE 1 A9 00 lda #$00 ; $E3CE: A9 00
|
|
00E3D0 1 85 BB sta $BB ; $E3D0: 85 BB
|
|
00E3D2 1
|
|
00E3D2 1 ; ----------------------------------------------------------------------------
|
|
00E3D2 1 ; Derive the current selector through GetCurrentObjectSelectorAndState and save
|
|
00E3D2 1 ; it to both $9E and $C2.
|
|
00E3D2 1 ; ----------------------------------------------------------------------------
|
|
00E3D2 1
|
|
00E3D2 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00E3D5 1 ; $E3D2: 20 DC E3
|
|
00E3D5 1
|
|
00E3D5 1 84 9E sty $9E ; $E3D5: 84 9E
|
|
00E3D7 1 84 C2 sty $C2 ; $E3D7: 84 C2
|
|
00E3D9 1
|
|
00E3D9 1 ; ----------------------------------------------------------------------------
|
|
00E3D9 1 ; Return to the main object-state dispatcher setup at $E040.
|
|
00E3D9 1 ; ----------------------------------------------------------------------------
|
|
00E3D9 1
|
|
00E3D9 1 4C 40 E0 jmp ProcessObjectStateSelection ; $E3D9: 4C 40 E0
|
|
00E3DC 1
|
|
00E3DC 1 ; ============================================================================
|
|
00E3DC 1 ; $E3DC-$E3E5
|
|
00E3DC 1 ; Derive the compact state index and saved selector for CurrentObjectIndex.
|
|
00E3DC 1 ;
|
|
00E3DC 1 ; Exit:
|
|
00E3DC 1 ; X = CurrentObjectIndex
|
|
00E3DC 1 ; Y = $0595[CurrentObjectIndex / 2]
|
|
00E3DC 1 ; A = CurrentObjectIndex / 2
|
|
00E3DC 1 ;
|
|
00E3DC 1 ; The final LDX restores the full object-array offset in X while leaving the
|
|
00E3DC 1 ; compact index in A and the saved selector in Y.
|
|
00E3DC 1 ; ============================================================================
|
|
00E3DC 1
|
|
00E3DC 1 ; ----------------------------------------------------------------------------
|
|
00E3DC 1 ; Contract:
|
|
00E3DC 1 ; Description: Implements Get Current Object Selector And State.
|
|
00E3DC 1 ; Entry: Registers: A; Memory: currentobjectindex, $0595
|
|
00E3DC 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00E3DC 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E3DC 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E3DC 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E3DC 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E3DC 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 13.
|
|
00E3DC 1 ; ----------------------------------------------------------------------------
|
|
00E3DC 1 GetCurrentObjectSelectorAndState: ; $E3DC
|
|
00E3DC 1 A5 E1 lda CurrentObjectIndex ; $E3DC: A5 E1
|
|
00E3DE 1 4A lsr ; $E3DE: 4A
|
|
00E3DF 1 AA tax ; $E3DF: AA
|
|
00E3E0 1
|
|
00E3E0 1 BC 95 05 ldy $0595,x ; $E3E0: BC 95 05
|
|
00E3E3 1
|
|
00E3E3 1 A6 E1 ldx CurrentObjectIndex ; $E3E3: A6 E1
|
|
00E3E5 1 60 rts ; $E3E5: 60
|
|
00E3E6 1
|
|
00E3E6 1 ; ============================================================================
|
|
00E3E6 1 ; $E3E6-$E412
|
|
00E3E6 1 ; Copy the current object's position into the base-object position fields,
|
|
00E3E6 1 ; initialize the base object's motion state, clear its auxiliary fields, and
|
|
00E3E6 1 ; save the result in BaseMotionActive.
|
|
00E3E6 1 ;
|
|
00E3E6 1 ; Entry:
|
|
00E3E6 1 ; CurrentObjectIndex = source object-array offset
|
|
00E3E6 1 ;
|
|
00E3E6 1 ; Exit:
|
|
00E3E6 1 ; A = value returned by ClearBaseAccelerationFields
|
|
00E3E6 1 ; X = CurrentObjectIndex
|
|
00E3E6 1 ; BaseMotionActive = returned value
|
|
00E3E6 1 ; ============================================================================
|
|
00E3E6 1
|
|
00E3E6 1 ; ----------------------------------------------------------------------------
|
|
00E3E6 1 ; Contract:
|
|
00E3E6 1 ; Description: Initializes Base Object From Current.
|
|
00E3E6 1 ; Entry: Registers: A; Memory: currentobjectindex, $0509, $050a, $053a, $053b
|
|
00E3E6 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E3E6 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E3E6 1 ; Memory effects: $0509, $050a, $053a, $053b, $056b, $056c, basemotionactive
|
|
00E3E6 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E3E6 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E3E6 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 6.
|
|
00E3E6 1 ; ----------------------------------------------------------------------------
|
|
00E3E6 1 InitializeBaseObjectFromCurrent: ; $E3E6
|
|
00E3E6 1 A6 E1 ldx CurrentObjectIndex ; $E3E6: A6 E1
|
|
00E3E8 1
|
|
00E3E8 1 ; ----------------------------------------------------------------------------
|
|
00E3E8 1 ; Copy the current object's horizontal coordinate to the base object.
|
|
00E3E8 1 ; ----------------------------------------------------------------------------
|
|
00E3E8 1
|
|
00E3E8 1 ; ----------------------------------------------------------------------------
|
|
00E3E8 1 ; Contract:
|
|
00E3E8 1 ; Description: Internal position-copy entry with X already loaded.
|
|
00E3E8 1 ; Entry: X = current object array offset.
|
|
00E3E8 1 ; Returns/products: Base object position fields updated.
|
|
00E3E8 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E3E8 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E3E8 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E3E8 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E3E8 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00E3E8 1 ; ----------------------------------------------------------------------------
|
|
00E3E8 1 CopyCurrentObjectPositionToBaseAfterIndex:
|
|
00E3E8 1 BD 09 05 lda $0509,x ; $E3E8: BD 09 05
|
|
00E3EB 1 8D 09 05 sta $0509 ; $E3EB: 8D 09 05
|
|
00E3EE 1
|
|
00E3EE 1 BD 0A 05 lda $050A,x ; $E3EE: BD 0A 05
|
|
00E3F1 1 8D 0A 05 sta $050A ; $E3F1: 8D 0A 05
|
|
00E3F4 1
|
|
00E3F4 1 ; ----------------------------------------------------------------------------
|
|
00E3F4 1 ; Copy the current object's vertical coordinate to the base object.
|
|
00E3F4 1 ; ----------------------------------------------------------------------------
|
|
00E3F4 1
|
|
00E3F4 1 BD 3A 05 lda $053A,x ; $E3F4: BD 3A 05
|
|
00E3F7 1 8D 3A 05 sta $053A ; $E3F7: 8D 3A 05
|
|
00E3FA 1
|
|
00E3FA 1 BD 3B 05 lda $053B,x ; $E3FA: BD 3B 05
|
|
00E3FD 1 8D 3B 05 sta $053B ; $E3FD: 8D 3B 05
|
|
00E400 1
|
|
00E400 1 ; ----------------------------------------------------------------------------
|
|
00E400 1 ; Initialize the base object's movement/state pair.
|
|
00E400 1 ; ----------------------------------------------------------------------------
|
|
00E400 1
|
|
00E400 1 A9 00 lda #$00 ; $E400: A9 00
|
|
00E402 1 8D 6B 05 sta $056B ; $E402: 8D 6B 05
|
|
00E405 1
|
|
00E405 1 A9 01 lda #$01 ; $E405: A9 01
|
|
00E407 1 8D 6C 05 sta $056C ; $E407: 8D 6C 05
|
|
00E40A 1
|
|
00E40A 1 ; ----------------------------------------------------------------------------
|
|
00E40A 1 ; Clear the base object's position/motion fields.
|
|
00E40A 1 ;
|
|
00E40A 1 ; These calls use the earlier helpers at $C94F and ClearBaseAccelerationFields
|
|
00E40A 1 ; ----------------------------------------------------------------------------
|
|
00E40A 1
|
|
00E40A 1 20 4F C9 jsr ClearBasePositionFields ; $E40A: 20 4F C9
|
|
00E40D 1 20 43 C9 jsr ClearBaseAccelerationFields ; $E40D: 20 43 C9
|
|
00E410 1
|
|
00E410 1 ; ----------------------------------------------------------------------------
|
|
00E410 1 ; Save the result from ClearBaseAccelerationFields as the active-motion state.
|
|
00E410 1 ; ----------------------------------------------------------------------------
|
|
00E410 1
|
|
00E410 1 85 5C sta BaseMotionActive ; $E410: 85 5C
|
|
00E412 1
|
|
00E412 1 60 rts ; $E412: 60
|
|
00E413 1
|
|
00E413 1 ; ============================================================================
|
|
00E413 1 ; $E413-$E432
|
|
00E413 1 ; Geometry parameter data, first 32 bytes.
|
|
00E413 1 ;
|
|
00E413 1 ; Keep this region as raw bytes. Later routines use calculated and overlapping
|
|
00E413 1 ; offsets into the larger data structure.
|
|
00E413 1 ; ============================================================================
|
|
00E413 1
|
|
00E413 1 GeometryParameterData: ; $E413
|
|
00E413 1 D0 05 00 00 .byte $D0,$05,$00,$00,$00,$02,$30,$08
|
|
00E417 1 00 02 30 08
|
|
00E41B 1 20 F9 C0 00 .byte $20,$F9,$C0,$00,$00,$00,$40,$F7
|
|
00E41F 1 00 00 40 F7
|
|
00E423 1 00 FE 00 FC .byte $00,$FE,$00,$FC,$00,$02,$00,$04
|
|
00E427 1 00 02 00 04
|
|
00E42B 1 80 06 00 00 .byte $80,$06,$00,$00,$D0,$00,$50,$08
|
|
00E42F 1 D0 00 50 08
|
|
00E433 1 GeometryParameterData_Block2: ; $E433
|
|
00E433 1 40 F8 C0 00 .byte $40,$F8,$C0,$00,$00,$00,$40,$F7
|
|
00E437 1 00 00 40 F7
|
|
00E43B 1 00 08 00 00 .byte $00,$08,$00,$00,$00,$00,$00,$08
|
|
00E43F 1 00 00 00 08
|
|
00E443 1 00 F8 00 00 .byte $00,$F8,$00,$00,$00,$00,$00,$F8
|
|
00E447 1 00 00 00 F8
|
|
00E44B 1 00 07 80 00 .byte $00,$07,$80,$00,$00,$FF,$00,$08
|
|
00E44F 1 00 FF 00 08
|
|
00E453 1 GeometryParameterData_Block3: ; $E453
|
|
00E453 1 80 F8 80 FF .byte $80,$F8,$80,$FF,$00,$03,$00,$F5
|
|
00E457 1 00 03 00 F5
|
|
00E45B 1 A0 06 60 01 .byte $A0,$06,$60,$01,$40,$FE,$C0,$06
|
|
00E45F 1 40 FE C0 06
|
|
00E463 1 40 F9 60 FE .byte $40,$F9,$60,$FE,$80,$06,$80,$FE
|
|
00E467 1 80 06 80 FE
|
|
00E46B 1
|
|
00E46B 1 ; ============================================================================
|
|
00E46B 1 ; $E46B-$E473
|
|
00E46B 1 ; Convert the current object's saved selector into a four-byte geometry-record
|
|
00E46B 1 ; offset.
|
|
00E46B 1 ;
|
|
00E46B 1 ; GetCurrentObjectSelectorAndState returns the saved selector in Y.
|
|
00E46B 1 ;
|
|
00E46B 1 ; Exit:
|
|
00E46B 1 ; Y = (saved selector - 1) * 4
|
|
00E46B 1 ; ============================================================================
|
|
00E46B 1
|
|
00E46B 1 GetCurrentGeometryRecordOffset: ; $E46B
|
|
00E46B 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00E46E 1 ; $E46B: 20 DC E3
|
|
00E46E 1
|
|
00E46E 1 88 dey ; $E46E: 88
|
|
00E46F 1 98 tya ; $E46F: 98
|
|
00E470 1
|
|
00E470 1 0A asl ; $E470: 0A
|
|
00E471 1 0A asl ; $E471: 0A
|
|
00E472 1
|
|
00E472 1 A8 tay ; $E472: A8
|
|
00E473 1 60 rts ; $E473: 60
|
|
00E474 1
|
|
00E474 1 ; ============================================================================
|
|
00E474 1 ; $E474-$E4B7
|
|
00E474 1 ; Geometry-record selection helpers.
|
|
00E474 1 ;
|
|
00E474 1 ; Each entry selects:
|
|
00E474 1 ;
|
|
00E474 1 ; Y = offset into the geometry data beginning at GeometryParameterData
|
|
00E474 1 ; A = geometry parameter stored in $C6
|
|
00E474 1 ;
|
|
00E474 1 ; The entries at $E474 and $E481 preserve parameters $0F and $05 by branching
|
|
00E474 1 ; directly to STA $C6 at $E4B5.
|
|
00E474 1 ;
|
|
00E474 1 ; The remaining entries merge at $E4B2, convert their calculated offset from
|
|
00E474 1 ; A to Y, and use the default geometry parameter $07.
|
|
00E474 1 ; ============================================================================
|
|
00E474 1
|
|
00E474 1 ; ----------------------------------------------------------------------------
|
|
00E474 1 ; Contract:
|
|
00E474 1 ; Description: Implements Select Geometry Record Default.
|
|
00E474 1 ; Entry: Registers: A, Y
|
|
00E474 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00E474 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E474 1 ; Memory effects: $c6
|
|
00E474 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E474 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E474 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00E474 1 ; ----------------------------------------------------------------------------
|
|
00E474 1 SelectGeometryRecord_Default: ; $E474
|
|
00E474 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00E477 1 ; $E474: 20 DC E3
|
|
00E477 1
|
|
00E477 1 98 tya ; $E477: 98
|
|
00E478 1 0A asl ; $E478: 0A
|
|
00E479 1 0A asl ; $E479: 0A
|
|
00E47A 1
|
|
00E47A 1 69 14 adc #$14 ; $E47A: 69 14
|
|
00E47C 1 A8 tay ; $E47C: A8
|
|
00E47D 1
|
|
00E47D 1 A9 0F lda #$0F ; $E47D: A9 0F
|
|
00E47F 1 D0 34 bne StoreGeometryParameter ; $E47F: D0 34
|
|
00E481 1 ; Always taken.
|
|
00E481 1 ; Target $E4B5.
|
|
00E481 1
|
|
00E481 1 ; ----------------------------------------------------------------------------
|
|
00E481 1 ; Select from the geometry-record group beginning at offset $44.
|
|
00E481 1 ;
|
|
00E481 1 ; Return:
|
|
00E481 1 ; Y = (($selector << 1) & $0C) + $44
|
|
00E481 1 ; $C6 = $05
|
|
00E481 1 ; ----------------------------------------------------------------------------
|
|
00E481 1
|
|
00E481 1 ; ----------------------------------------------------------------------------
|
|
00E481 1 ; Contract:
|
|
00E481 1 ; Description: Implements Select Geometry Record 4 4.
|
|
00E481 1 ; Entry: Registers: A, Y
|
|
00E481 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00E481 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E481 1 ; Memory effects: $c6
|
|
00E481 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E481 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E481 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E481 1 ; ----------------------------------------------------------------------------
|
|
00E481 1 SelectGeometryRecord_44: ; $E481
|
|
00E481 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00E484 1 ; $E481: 20 DC E3
|
|
00E484 1
|
|
00E484 1 98 tya ; $E484: 98
|
|
00E485 1 0A asl ; $E485: 0A
|
|
00E486 1 29 0C and #$0C ; $E486: 29 0C
|
|
00E488 1
|
|
00E488 1 69 44 adc #$44 ; $E488: 69 44
|
|
00E48A 1 A8 tay ; $E48A: A8
|
|
00E48B 1
|
|
00E48B 1 A9 05 lda #$05 ; $E48B: A9 05
|
|
00E48D 1 D0 26 bne StoreGeometryParameter ; $E48D: D0 26
|
|
00E48F 1 ; Always taken.
|
|
00E48F 1 ; Target $E4B5.
|
|
00E48F 1
|
|
00E48F 1 ; ----------------------------------------------------------------------------
|
|
00E48F 1 ; Select from the geometry-record group beginning at offset $34.
|
|
00E48F 1 ;
|
|
00E48F 1 ; Return:
|
|
00E48F 1 ; Y = (($selector << 1) & $1C) + $34
|
|
00E48F 1 ; $C6 = $07
|
|
00E48F 1 ; ----------------------------------------------------------------------------
|
|
00E48F 1
|
|
00E48F 1 ; ----------------------------------------------------------------------------
|
|
00E48F 1 ; Contract:
|
|
00E48F 1 ; Description: Implements Select Geometry Record 3 4.
|
|
00E48F 1 ; Entry: Registers: A, Y
|
|
00E48F 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00E48F 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E48F 1 ; Memory effects: $c6
|
|
00E48F 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E48F 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E48F 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00E48F 1 ; ----------------------------------------------------------------------------
|
|
00E48F 1 SelectGeometryRecord_34: ; $E48F
|
|
00E48F 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00E492 1 ; $E48F: 20 DC E3
|
|
00E492 1
|
|
00E492 1 98 tya ; $E492: 98
|
|
00E493 1 0A asl ; $E493: 0A
|
|
00E494 1 29 1C and #$1C ; $E494: 29 1C
|
|
00E496 1
|
|
00E496 1 69 34 adc #$34 ; $E496: 69 34
|
|
00E498 1 D0 18 bne UseGeometryRecordOffset ; $E498: D0 18
|
|
00E49A 1 ; Target $E4B2.
|
|
00E49A 1
|
|
00E49A 1 ; ----------------------------------------------------------------------------
|
|
00E49A 1 ; Select from the geometry-record group beginning at offset $28.
|
|
00E49A 1 ;
|
|
00E49A 1 ; Return:
|
|
00E49A 1 ; Y = (($selector << 1) & $0C) + $28
|
|
00E49A 1 ; $C6 = $07
|
|
00E49A 1 ; ----------------------------------------------------------------------------
|
|
00E49A 1
|
|
00E49A 1 ; ----------------------------------------------------------------------------
|
|
00E49A 1 ; Contract:
|
|
00E49A 1 ; Description: Implements Select Geometry Record 2 8.
|
|
00E49A 1 ; Entry: Registers: A, Y
|
|
00E49A 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00E49A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E49A 1 ; Memory effects: $c6
|
|
00E49A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E49A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E49A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E49A 1 ; ----------------------------------------------------------------------------
|
|
00E49A 1 SelectGeometryRecord_28: ; $E49A
|
|
00E49A 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00E49D 1 ; $E49A: 20 DC E3
|
|
00E49D 1
|
|
00E49D 1 98 tya ; $E49D: 98
|
|
00E49E 1 0A asl ; $E49E: 0A
|
|
00E49F 1 29 0C and #$0C ; $E49F: 29 0C
|
|
00E4A1 1
|
|
00E4A1 1 69 28 adc #$28 ; $E4A1: 69 28
|
|
00E4A3 1 D0 0D bne UseGeometryRecordOffset ; $E4A3: D0 0D
|
|
00E4A5 1 ; Target $E4B2.
|
|
00E4A5 1
|
|
00E4A5 1 ; ----------------------------------------------------------------------------
|
|
00E4A5 1 ; Select from the geometry-record group beginning at offset $24.
|
|
00E4A5 1 ;
|
|
00E4A5 1 ; If the calculation produces zero, substitute fixed offset $54.
|
|
00E4A5 1 ;
|
|
00E4A5 1 ; Return:
|
|
00E4A5 1 ; Y = calculated offset or $54
|
|
00E4A5 1 ; $C6 = $07
|
|
00E4A5 1 ; ----------------------------------------------------------------------------
|
|
00E4A5 1
|
|
00E4A5 1 ; ----------------------------------------------------------------------------
|
|
00E4A5 1 ; Contract:
|
|
00E4A5 1 ; Description: Implements Select Geometry Record 2 4.
|
|
00E4A5 1 ; Entry: Registers: A, Y
|
|
00E4A5 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00E4A5 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E4A5 1 ; Memory effects: $c6
|
|
00E4A5 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E4A5 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E4A5 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E4A5 1 ; ----------------------------------------------------------------------------
|
|
00E4A5 1 SelectGeometryRecord_24: ; $E4A5
|
|
00E4A5 1 20 DC E3 jsr GetCurrentObjectSelectorAndState
|
|
00E4A8 1 ; $E4A5: 20 DC E3
|
|
00E4A8 1
|
|
00E4A8 1 98 tya ; $E4A8: 98
|
|
00E4A9 1 0A asl ; $E4A9: 0A
|
|
00E4AA 1 29 0C and #$0C ; $E4AA: 29 0C
|
|
00E4AC 1
|
|
00E4AC 1 69 24 adc #$24 ; $E4AC: 69 24
|
|
00E4AE 1 D0 02 bne UseGeometryRecordOffset ; $E4AE: D0 02
|
|
00E4B0 1 ; Target $E4B2.
|
|
00E4B0 1
|
|
00E4B0 1 ; ----------------------------------------------------------------------------
|
|
00E4B0 1 ; Contract:
|
|
00E4B0 1 ; Description: Internal geometry-selector path using fixed record offset $54.
|
|
00E4B0 1 ; Entry: No additional register input beyond parent selector state.
|
|
00E4B0 1 ; Returns/products: Y receives record offset; shared geometry parameter set.
|
|
00E4B0 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E4B0 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E4B0 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E4B0 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E4B0 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00E4B0 1 ; ----------------------------------------------------------------------------
|
|
00E4B0 1 UseFixedGeometryRecord54:
|
|
00E4B0 1 A9 54 lda #$54 ; $E4B0: A9 54
|
|
00E4B2 1
|
|
00E4B2 1 ; ----------------------------------------------------------------------------
|
|
00E4B2 1 ; Convert the selected geometry-record offset from A to Y.
|
|
00E4B2 1 ; ----------------------------------------------------------------------------
|
|
00E4B2 1
|
|
00E4B2 1 UseGeometryRecordOffset: ; $E4B2
|
|
00E4B2 1 A8 tay ; $E4B2: A8
|
|
00E4B3 1
|
|
00E4B3 1 A9 07 lda #$07 ; $E4B3: A9 07
|
|
00E4B5 1
|
|
00E4B5 1 ; ----------------------------------------------------------------------------
|
|
00E4B5 1 ; Shared parameter store.
|
|
00E4B5 1 ;
|
|
00E4B5 1 ; The branches from $E47F and $E48D enter directly here, preserving their
|
|
00E4B5 1 ; respective values $0F and $05.
|
|
00E4B5 1 ; ----------------------------------------------------------------------------
|
|
00E4B5 1
|
|
00E4B5 1 StoreGeometryParameter: ; $E4B5
|
|
00E4B5 1 85 C6 sta $C6 ; $E4B5: 85 C6
|
|
00E4B7 1
|
|
00E4B7 1 60 rts ; $E4B7: 60
|
|
00E4B8 1
|
|
00E4B8 1 ; ============================================================================
|
|
00E4B8 1 ; $E4B8-$E4C1
|
|
00E4B8 1 ; Select a geometry record directly from CurrentObjectIndex.
|
|
00E4B8 1 ;
|
|
00E4B8 1 ; Return:
|
|
00E4B8 1 ; Y = (CurrentObjectIndex * 2) + $F4
|
|
00E4B8 1 ; $C6 = $0F
|
|
00E4B8 1 ;
|
|
00E4B8 1 ; The BNE branches backward directly to STA $C6 at $E4B5.
|
|
00E4B8 1 ; ============================================================================
|
|
00E4B8 1
|
|
00E4B8 1 ; ----------------------------------------------------------------------------
|
|
00E4B8 1 ; Contract:
|
|
00E4B8 1 ; Description: Implements Select Geometry Record From Object.
|
|
00E4B8 1 ; Entry: Registers: A; Memory: currentobjectindex, GeometryParameterData, $e414, $e415, $e416
|
|
00E4B8 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00E4B8 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E4B8 1 ; Memory effects: $b2, $b3, $b4, $b5
|
|
00E4B8 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E4B8 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E4B8 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E4B8 1 ; ----------------------------------------------------------------------------
|
|
00E4B8 1 SelectGeometryRecordFromObject: ; $E4B8
|
|
00E4B8 1 A5 E1 lda CurrentObjectIndex ; $E4B8: A5 E1
|
|
00E4BA 1 0A asl ; $E4BA: 0A
|
|
00E4BB 1
|
|
00E4BB 1 69 F4 adc #$F4 ; $E4BB: 69 F4
|
|
00E4BD 1 A8 tay ; $E4BD: A8
|
|
00E4BE 1
|
|
00E4BE 1 A9 0F lda #$0F ; $E4BE: A9 0F
|
|
00E4C0 1 D0 F3 bne StoreGeometryParameter ; $E4C0: D0 F3
|
|
00E4C2 1 ; Always taken.
|
|
00E4C2 1 ; Target $E4B5.
|
|
00E4C2 1
|
|
00E4C2 1 ; ============================================================================
|
|
00E4C2 1 ; $E4C2-$E4D6
|
|
00E4C2 1 ; Load a four-byte geometry record into $B2-$B5.
|
|
00E4C2 1 ;
|
|
00E4C2 1 ; Entry:
|
|
00E4C2 1 ; Y = byte offset into the geometry data beginning at GeometryParameterData
|
|
00E4C2 1 ;
|
|
00E4C2 1 ; Exit:
|
|
00E4C2 1 ; $B2 = byte at $E413+Y
|
|
00E4C2 1 ; $B3 = byte at $E414+Y
|
|
00E4C2 1 ; $B4 = byte at $E415+Y
|
|
00E4C2 1 ; $B5 = byte at $E416+Y
|
|
00E4C2 1 ;
|
|
00E4C2 1 ; Literal addresses are used because the geometry data was decoded as several
|
|
00E4C2 1 ; smaller source blocks.
|
|
00E4C2 1 ; ============================================================================
|
|
00E4C2 1
|
|
00E4C2 1 ; ----------------------------------------------------------------------------
|
|
00E4C2 1 ; Contract:
|
|
00E4C2 1 ; Description: Implements Load Geometry Record.
|
|
00E4C2 1 ; Entry: Registers: A; Memory: GeometryParameterData, $e414, $e415, $e416
|
|
00E4C2 1 ; Returns/products: Registers/clobbers: A
|
|
00E4C2 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E4C2 1 ; Memory effects: $b2, $b3, $b4, $b5
|
|
00E4C2 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E4C2 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E4C2 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 6.
|
|
00E4C2 1 ; ----------------------------------------------------------------------------
|
|
00E4C2 1 LoadGeometryRecord: ; $E4C2
|
|
00E4C2 1 B9 13 E4 lda GeometryParameterData,y ; $E4C2: B9 13 E4
|
|
00E4C5 1 85 B2 sta $B2 ; $E4C5: 85 B2
|
|
00E4C7 1
|
|
00E4C7 1 B9 14 E4 lda GeometryParameterData+1,y ; $E4C7: B9 14 E4
|
|
00E4CA 1 85 B3 sta $B3 ; $E4CA: 85 B3
|
|
00E4CC 1
|
|
00E4CC 1 B9 15 E4 lda GeometryParameterData+2,y ; $E4CC: B9 15 E4
|
|
00E4CF 1 85 B4 sta $B4 ; $E4CF: 85 B4
|
|
00E4D1 1
|
|
00E4D1 1 B9 16 E4 lda GeometryParameterData+3,y ; $E4D1: B9 16 E4
|
|
00E4D4 1 85 B5 sta $B5 ; $E4D4: 85 B5
|
|
00E4D6 1
|
|
00E4D6 1 60 rts ; $E4D6: 60
|
|
00E4D7 1
|
|
00E4D7 1 ; ============================================================================
|
|
00E4D7 1 ; $E4D7-$E501
|
|
00E4D7 1 ; Calculate doubled signed coordinate differences between geometry arguments
|
|
00E4D7 1 ; $B2-$B5 and an object position.
|
|
00E4D7 1 ;
|
|
00E4D7 1 ; Two entry points select the object:
|
|
00E4D7 1 ;
|
|
00E4D7 1 ; $E4D7: compare against the base object at array offset $00
|
|
00E4D7 1 ; $E4DB: compare against CurrentObjectIndex
|
|
00E4D7 1 ;
|
|
00E4D7 1 ; Results:
|
|
00E4D7 1 ; $AE/$AF = doubled horizontal difference
|
|
00E4D7 1 ; $B0/$B1 = doubled vertical difference
|
|
00E4D7 1 ; ============================================================================
|
|
00E4D7 1
|
|
00E4D7 1 CalculateBaseGeometryDifference: ; $E4D7
|
|
00E4D7 1 A2 00 ldx #$00 ; $E4D7: A2 00
|
|
00E4D9 1 F0 02 beq CalculateGeometryDifference
|
|
00E4DB 1 ; $E4D9: F0 02
|
|
00E4DB 1 ; Always taken because X is zero.
|
|
00E4DB 1
|
|
00E4DB 1 ; ----------------------------------------------------------------------------
|
|
00E4DB 1 ; Contract:
|
|
00E4DB 1 ; Description: Calculates Current Geometry Difference.
|
|
00E4DB 1 ; Entry: Registers: A; Memory: currentobjectindex, $b2, $0509, $b3, $050a, $b4, $053a, $b5
|
|
00E4DB 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E4DB 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E4DB 1 ; Memory effects: calculatedcoordinatelow, calculatedcoordinatehigh, $b0, $b1
|
|
00E4DB 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E4DB 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E4DB 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00E4DB 1 ; ----------------------------------------------------------------------------
|
|
00E4DB 1 CalculateCurrentGeometryDifference: ; $E4DB
|
|
00E4DB 1 A6 E1 ldx CurrentObjectIndex ; $E4DB: A6 E1
|
|
00E4DD 1
|
|
00E4DD 1 ; ----------------------------------------------------------------------------
|
|
00E4DD 1 ; Calculate the signed horizontal difference:
|
|
00E4DD 1 ;
|
|
00E4DD 1 ; ($B2/$B3) - ($0509/$050A,X)
|
|
00E4DD 1 ;
|
|
00E4DD 1 ; Then multiply the 16-bit result by two.
|
|
00E4DD 1 ; ----------------------------------------------------------------------------
|
|
00E4DD 1
|
|
00E4DD 1 ; ----------------------------------------------------------------------------
|
|
00E4DD 1 ; Contract:
|
|
00E4DD 1 ; Description: Calculates Geometry Difference.
|
|
00E4DD 1 ; Entry: Registers: A; Memory: $b2, $0509, $b3, $050a, $b4, $053a, $b5, $053b
|
|
00E4DD 1 ; Returns/products: Registers/clobbers: A
|
|
00E4DD 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E4DD 1 ; Memory effects: calculatedcoordinatelow, calculatedcoordinatehigh, $b0, $b1
|
|
00E4DD 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E4DD 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E4DD 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E4DD 1 ; ----------------------------------------------------------------------------
|
|
00E4DD 1 CalculateGeometryDifference: ; $E4DD
|
|
00E4DD 1 38 sec ; $E4DD: 38
|
|
00E4DE 1
|
|
00E4DE 1 A5 B2 lda $B2 ; $E4DE: A5 B2
|
|
00E4E0 1 FD 09 05 sbc $0509,x ; $E4E0: FD 09 05
|
|
00E4E3 1 85 AE sta CalculatedCoordinateLow ; $E4E3: 85 AE
|
|
00E4E5 1
|
|
00E4E5 1 A5 B3 lda $B3 ; $E4E5: A5 B3
|
|
00E4E7 1 FD 0A 05 sbc $050A,x ; $E4E7: FD 0A 05
|
|
00E4EA 1
|
|
00E4EA 1 06 AE asl CalculatedCoordinateLow ; $E4EA: 06 AE
|
|
00E4EC 1 2A rol ; $E4EC: 2A
|
|
00E4ED 1 85 AF sta CalculatedCoordinateHigh ; $E4ED: 85 AF
|
|
00E4EF 1
|
|
00E4EF 1 ; ----------------------------------------------------------------------------
|
|
00E4EF 1 ; Calculate the signed vertical difference:
|
|
00E4EF 1 ;
|
|
00E4EF 1 ; ($B4/$B5) - ($053A/$053B,X)
|
|
00E4EF 1 ;
|
|
00E4EF 1 ; Then multiply the 16-bit result by two.
|
|
00E4EF 1 ; ----------------------------------------------------------------------------
|
|
00E4EF 1
|
|
00E4EF 1 38 sec ; $E4EF: 38
|
|
00E4F0 1
|
|
00E4F0 1 A5 B4 lda $B4 ; $E4F0: A5 B4
|
|
00E4F2 1 FD 3A 05 sbc $053A,x ; $E4F2: FD 3A 05
|
|
00E4F5 1 85 B0 sta $B0 ; $E4F5: 85 B0
|
|
00E4F7 1
|
|
00E4F7 1 A5 B5 lda $B5 ; $E4F7: A5 B5
|
|
00E4F9 1 FD 3B 05 sbc $053B,x ; $E4F9: FD 3B 05
|
|
00E4FC 1
|
|
00E4FC 1 06 B0 asl $B0 ; $E4FC: 06 B0
|
|
00E4FE 1 2A rol ; $E4FE: 2A
|
|
00E4FF 1 85 B1 sta $B1 ; $E4FF: 85 B1
|
|
00E501 1
|
|
00E501 1 60 rts ; $E501: 60
|
|
00E502 1
|
|
00E502 1 ; ============================================================================
|
|
00E502 1 ; $E502-$E512
|
|
00E502 1 ; Normalize or measure the signed coordinate difference in $AE-$B1.
|
|
00E502 1 ;
|
|
00E502 1 ; The high bytes are adjusted upward when the corresponding low signed value
|
|
00E502 1 ; is negative, then passed to the vector or distance helper at $E80B.
|
|
00E502 1 ;
|
|
00E502 1 ; Entry:
|
|
00E502 1 ; $AE/$AF = signed horizontal difference
|
|
00E502 1 ; $B0/$B1 = signed vertical difference
|
|
00E502 1 ;
|
|
00E502 1 ; Exit:
|
|
00E502 1 ; Returned directly from $E80B
|
|
00E502 1 ; ============================================================================
|
|
00E502 1
|
|
00E502 1 ; ----------------------------------------------------------------------------
|
|
00E502 1 ; Contract:
|
|
00E502 1 ; Description: Implements Evaluate Geometry Difference.
|
|
00E502 1 ; Entry: Registers: X, Y; Memory: calculatedcoordinatehigh, calculatedcoordinatelow, $b1, $b0
|
|
00E502 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E502 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E502 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E502 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E502 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E502 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00E502 1 ; ----------------------------------------------------------------------------
|
|
00E502 1 EvaluateGeometryDifference: ; $E502
|
|
00E502 1 A6 AF ldx CalculatedCoordinateHigh ; $E502: A6 AF
|
|
00E504 1
|
|
00E504 1 A5 AE lda CalculatedCoordinateLow ; $E504: A5 AE
|
|
00E506 1 10 01 bpl EvaluateGeometryDifference_HorizontalReady
|
|
00E508 1 ; $E506: 10 01
|
|
00E508 1
|
|
00E508 1 E8 inx ; $E508: E8
|
|
00E509 1
|
|
00E509 1 EvaluateGeometryDifference_HorizontalReady: ; $E509
|
|
00E509 1 A4 B1 ldy $B1 ; $E509: A4 B1
|
|
00E50B 1
|
|
00E50B 1 A5 B0 lda $B0 ; $E50B: A5 B0
|
|
00E50D 1 10 01 bpl EvaluateGeometryDifference_VerticalReady
|
|
00E50F 1 ; $E50D: 10 01
|
|
00E50F 1
|
|
00E50F 1 C8 iny ; $E50F: C8
|
|
00E510 1
|
|
00E510 1 EvaluateGeometryDifference_VerticalReady: ; $E510
|
|
00E510 1 4C 0B E8 jmp CalculateVectorMagnitude ; $E510: 4C 0B E8
|
|
00E513 1
|
|
00E513 1 ; ============================================================================
|
|
00E513 1 ; $E513-$E527
|
|
00E513 1 ; Convert geometry parameter bytes into a signed vector.
|
|
00E513 1 ;
|
|
00E513 1 ; Entry:
|
|
00E513 1 ; A = horizontal parameter
|
|
00E513 1 ; $B5 = vertical parameter or zero
|
|
00E513 1 ; $AF/$B1 = signed coordinate-difference high bytes
|
|
00E513 1 ;
|
|
00E513 1 ; Operation:
|
|
00E513 1 ; 1. Save A in $B3.
|
|
00E513 1 ; 2. Clear $B5.
|
|
00E513 1 ; 3. Copy $B3/$B5 into $D6/$D7.
|
|
00E513 1 ; 4. Pass X=$AF and Y=$B1 to $E828.
|
|
00E513 1 ;
|
|
00E513 1 ; Exit:
|
|
00E513 1 ; Returned directly from $E828
|
|
00E513 1 ; ============================================================================
|
|
00E513 1
|
|
00E513 1 ; ----------------------------------------------------------------------------
|
|
00E513 1 ; Contract:
|
|
00E513 1 ; Description: Implements Build Geometry Vector.
|
|
00E513 1 ; Entry: Registers: A; Memory: $b3, $b5, calculatedcoordinatehigh, $b1
|
|
00E513 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E513 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E513 1 ; Memory effects: $b3, $b5, $d6, $d7
|
|
00E513 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E513 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E513 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00E513 1 ; ----------------------------------------------------------------------------
|
|
00E513 1 BuildGeometryVector: ; $E513
|
|
00E513 1 85 B3 sta $B3 ; $E513: 85 B3
|
|
00E515 1
|
|
00E515 1 A9 00 lda #$00 ; $E515: A9 00
|
|
00E517 1 85 B5 sta $B5 ; $E517: 85 B5
|
|
00E519 1
|
|
00E519 1 ; ----------------------------------------------------------------------------
|
|
00E519 1 ; Alternate entry used when $B3 and $B5 are already initialized.
|
|
00E519 1 ; ----------------------------------------------------------------------------
|
|
00E519 1
|
|
00E519 1 ; ----------------------------------------------------------------------------
|
|
00E519 1 ; Contract:
|
|
00E519 1 ; Description: Implements Build Geometry Vector From Arguments.
|
|
00E519 1 ; Entry: Registers: A; Memory: $b3, $b5, calculatedcoordinatehigh, $b1
|
|
00E519 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E519 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E519 1 ; Memory effects: $d6, $d7
|
|
00E519 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E519 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E519 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00E519 1 ; ----------------------------------------------------------------------------
|
|
00E519 1 BuildGeometryVectorFromArguments: ; $E519
|
|
00E519 1 A5 B3 lda $B3 ; $E519: A5 B3
|
|
00E51B 1 85 D6 sta $D6 ; $E51B: 85 D6
|
|
00E51D 1
|
|
00E51D 1 A5 B5 lda $B5 ; $E51D: A5 B5
|
|
00E51F 1 85 D7 sta $D7 ; $E51F: 85 D7
|
|
00E521 1
|
|
00E521 1 A6 AF ldx CalculatedCoordinateHigh ; $E521: A6 AF
|
|
00E523 1 A4 B1 ldy $B1 ; $E523: A4 B1
|
|
00E525 1
|
|
00E525 1 4C 28 E8 jmp CalculateSignedVectorFromResult ; $E525: 4C 28 E8
|
|
00E528 1
|
|
00E528 1 ; ============================================================================
|
|
00E528 1 ; $E528-$E532
|
|
00E528 1 ; Store a calculated movement vector into the current object.
|
|
00E528 1 ;
|
|
00E528 1 ; Entry:
|
|
00E528 1 ; A = horizontal movement low/result byte
|
|
00E528 1 ; Y = vertical movement low/result byte
|
|
00E528 1 ;
|
|
00E528 1 ; Exit:
|
|
00E528 1 ; X = CurrentObjectIndex
|
|
00E528 1 ;
|
|
00E528 1 ; Modified fields:
|
|
00E528 1 ; $056D,X = A
|
|
00E528 1 ; $056E,X = Y
|
|
00E528 1 ; ============================================================================
|
|
00E528 1
|
|
00E528 1 ; ----------------------------------------------------------------------------
|
|
00E528 1 ; Contract:
|
|
00E528 1 ; Description: Implements Store Current Object Movement.
|
|
00E528 1 ; Entry: Registers: A, Y; Memory: currentobjectindex
|
|
00E528 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E528 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E528 1 ; Memory effects: $056d, $056e
|
|
00E528 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E528 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E528 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 4.
|
|
00E528 1 ; ----------------------------------------------------------------------------
|
|
00E528 1 StoreCurrentObjectMovement: ; $E528
|
|
00E528 1 AA tax ; $E528: AA
|
|
00E529 1 ; Temporarily preserve A in X.
|
|
00E529 1
|
|
00E529 1 A6 E1 ldx CurrentObjectIndex ; $E529: A6 E1
|
|
00E52B 1
|
|
00E52B 1 9D 6D 05 sta $056D,x ; $E52B: 9D 6D 05
|
|
00E52E 1
|
|
00E52E 1 98 tya ; $E52E: 98
|
|
00E52F 1 9D 6E 05 sta $056E,x ; $E52F: 9D 6E 05
|
|
00E532 1
|
|
00E532 1 60 rts ; $E532: 60
|
|
00E533 1
|
|
00E533 1 ; ============================================================================
|
|
00E533 1 ; $E533-$E547
|
|
00E533 1 ; Store a calculated position in the base object and clear its movement fields.
|
|
00E533 1 ;
|
|
00E533 1 ; Entry:
|
|
00E533 1 ; A = horizontal low/result byte
|
|
00E533 1 ; Y = vertical low/result byte
|
|
00E533 1 ;
|
|
00E533 1 ; Modified fields:
|
|
00E533 1 ; $0508 = A
|
|
00E533 1 ; $0539 = Y
|
|
00E533 1 ;
|
|
00E533 1 ; $056A = $00
|
|
00E533 1 ; $0507 = $00
|
|
00E533 1 ; $0538 = $00
|
|
00E533 1 ; $0569 = $00
|
|
00E533 1 ;
|
|
00E533 1 ; Exit:
|
|
00E533 1 ; A = $00
|
|
00E533 1 ; ============================================================================
|
|
00E533 1
|
|
00E533 1 StoreBaseObjectPositionAndClearMovement: ; $E533
|
|
00E533 1 8D 08 05 sta $0508 ; $E533: 8D 08 05
|
|
00E536 1 8C 39 05 sty $0539 ; $E536: 8C 39 05
|
|
00E539 1
|
|
00E539 1 ; ----------------------------------------------------------------------------
|
|
00E539 1 ; Clear the remaining base-object movement components.
|
|
00E539 1 ; ----------------------------------------------------------------------------
|
|
00E539 1
|
|
00E539 1 A9 00 lda #$00 ; $E539: A9 00
|
|
00E53B 1
|
|
00E53B 1 8D 6A 05 sta $056A ; $E53B: 8D 6A 05
|
|
00E53E 1 8D 07 05 sta $0507 ; $E53E: 8D 07 05
|
|
00E541 1 8D 38 05 sta $0538 ; $E541: 8D 38 05
|
|
00E544 1 8D 69 05 sta $0569 ; $E544: 8D 69 05
|
|
00E547 1
|
|
00E547 1 60 rts ; $E547: 60
|
|
00E548 1
|
|
00E548 1 ; ============================================================================
|
|
00E548 1 ; $E548-$E54E
|
|
00E548 1 ; Begin copying geometry arguments into the current object's coordinates.
|
|
00E548 1 ; ============================================================================
|
|
00E548 1
|
|
00E548 1 ; ----------------------------------------------------------------------------
|
|
00E548 1 ; Contract:
|
|
00E548 1 ; Description: Implements Store Geometry In Current Object.
|
|
00E548 1 ; Entry: Registers: A; Memory: currentobjectindex, $b2, $b3, $b4, $b5
|
|
00E548 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E548 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E548 1 ; Memory effects: $0509, $050a, $053a, $053b
|
|
00E548 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E548 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E548 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E548 1 ; ----------------------------------------------------------------------------
|
|
00E548 1 StoreGeometryInCurrentObject: ; $E548
|
|
00E548 1 A6 E1 ldx CurrentObjectIndex ; $E548: A6 E1
|
|
00E54A 1
|
|
00E54A 1 A5 B2 lda $B2 ; $E54A: A5 B2
|
|
00E54C 1 9D 09 05 sta $0509,x ; $E54C: 9D 09 05
|
|
00E54F 1
|
|
00E54F 1 ; ============================================================================
|
|
00E54F 1 ; $E54F-$E561
|
|
00E54F 1 ; Complete the copy of geometry arguments $B2-$B5 into the current object's
|
|
00E54F 1 ; coordinate fields.
|
|
00E54F 1 ;
|
|
00E54F 1 ; Entry:
|
|
00E54F 1 ; X = CurrentObjectIndex, loaded by the preceding code at $E548
|
|
00E54F 1 ;
|
|
00E54F 1 ; Geometry source:
|
|
00E54F 1 ; $B2 = horizontal low byte
|
|
00E54F 1 ; $B3 = horizontal high byte
|
|
00E54F 1 ; $B4 = vertical low byte
|
|
00E54F 1 ; $B5 = vertical high byte
|
|
00E54F 1 ;
|
|
00E54F 1 ; Object destination:
|
|
00E54F 1 ; $0509,X/$050A,X = horizontal coordinate
|
|
00E54F 1 ; $053A,X/$053B,X = vertical coordinate
|
|
00E54F 1 ; ============================================================================
|
|
00E54F 1
|
|
00E54F 1 A5 B3 lda $B3 ; $E54F: A5 B3
|
|
00E551 1 9D 0A 05 sta $050A,x ; $E551: 9D 0A 05
|
|
00E554 1
|
|
00E554 1 A5 B4 lda $B4 ; $E554: A5 B4
|
|
00E556 1 9D 3A 05 sta $053A,x ; $E556: 9D 3A 05
|
|
00E559 1
|
|
00E559 1 A5 B5 lda $B5 ; $E559: A5 B5
|
|
00E55B 1 9D 3B 05 sta $053B,x ; $E55B: 9D 3B 05
|
|
00E55E 1
|
|
00E55E 1 60 rts ; $E55E: 60
|
|
00E55F 1
|
|
00E55F 1 ; ============================================================================
|
|
00E55F 1 ; $E55F-$E57D
|
|
00E55F 1 ; Load the selected geometry record, compare it with the current object, and
|
|
00E55F 1 ; either apply a calculated movement vector or copy the geometry directly into
|
|
00E55F 1 ; the current object's position.
|
|
00E55F 1 ;
|
|
00E55F 1 ; Entry:
|
|
00E55F 1 ; Y = geometry-record offset
|
|
00E55F 1 ; $C6 = geometry/vector parameter
|
|
00E55F 1 ;
|
|
00E55F 1 ; Return:
|
|
00E55F 1 ; C = set when the geometry result is at least $02
|
|
00E55F 1 ; C = clear when the geometry result is below $02
|
|
00E55F 1 ; ============================================================================
|
|
00E55F 1
|
|
00E55F 1 ; ----------------------------------------------------------------------------
|
|
00E55F 1 ; Contract:
|
|
00E55F 1 ; Description: Implements Apply Current Object Geometry.
|
|
00E55F 1 ; Entry: Registers: A; Memory: $c6
|
|
00E55F 1 ; Returns/products: Registers/clobbers: A; Flags: condition flags may carry result state
|
|
00E55F 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E55F 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E55F 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E55F 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E55F 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 11.
|
|
00E55F 1 ; ----------------------------------------------------------------------------
|
|
00E55F 1 ApplyCurrentObjectGeometry: ; $E55F
|
|
00E55F 1 20 C2 E4 jsr LoadGeometryRecord ; $E55F: 20 C2 E4
|
|
00E562 1
|
|
00E562 1 ; ----------------------------------------------------------------------------
|
|
00E562 1 ; Calculate and evaluate the difference between the loaded geometry record
|
|
00E562 1 ; and the current object.
|
|
00E562 1 ; ----------------------------------------------------------------------------
|
|
00E562 1 EvaluateLoadedCurrentObjectGeometry:
|
|
00E562 1 20 DB E4 jsr CalculateCurrentGeometryDifference
|
|
00E565 1 ; $E562: 20 DB E4
|
|
00E565 1
|
|
00E565 1 20 02 E5 jsr EvaluateGeometryDifference
|
|
00E568 1 ; $E565: 20 02 E5
|
|
00E568 1
|
|
00E568 1 C9 02 cmp #$02 ; $E568: C9 02
|
|
00E56A 1 90 0A bcc ApplyCurrentObjectGeometry_CopyPosition
|
|
00E56C 1 ; $E56A: 90 0A
|
|
00E56C 1
|
|
00E56C 1 ; ----------------------------------------------------------------------------
|
|
00E56C 1 ; Geometry result is at least two.
|
|
00E56C 1 ;
|
|
00E56C 1 ; Use the selected parameter in $C6 to build a movement vector and store it in
|
|
00E56C 1 ; the current object's movement fields.
|
|
00E56C 1 ; ----------------------------------------------------------------------------
|
|
00E56C 1
|
|
00E56C 1 A5 C6 lda $C6 ; $E56C: A5 C6
|
|
00E56E 1
|
|
00E56E 1 20 13 E5 jsr BuildGeometryVector ; $E56E: 20 13 E5
|
|
00E571 1 20 28 E5 jsr StoreCurrentObjectMovement
|
|
00E574 1 ; $E571: 20 28 E5
|
|
00E574 1
|
|
00E574 1 38 sec ; $E574: 38
|
|
00E575 1 60 rts ; $E575: 60
|
|
00E576 1
|
|
00E576 1 ; ----------------------------------------------------------------------------
|
|
00E576 1 ; Geometry result is below two.
|
|
00E576 1 ;
|
|
00E576 1 ; Copy the loaded geometry record directly into the current object's position,
|
|
00E576 1 ; clear the object's movement fields, and return carry clear.
|
|
00E576 1 ; ----------------------------------------------------------------------------
|
|
00E576 1
|
|
00E576 1 ApplyCurrentObjectGeometry_CopyPosition: ; $E576
|
|
00E576 1 20 48 E5 jsr StoreGeometryInCurrentObject
|
|
00E579 1 ; $E576: 20 48 E5
|
|
00E579 1
|
|
00E579 1 20 D3 E2 jsr ClearCurrentObjectMovement
|
|
00E57C 1 ; $E579: 20 D3 E2
|
|
00E57C 1
|
|
00E57C 1 18 clc ; $E57C: 18
|
|
00E57D 1 60 rts ; $E57D: 60
|
|
00E57E 1
|
|
00E57E 1 ; ============================================================================
|
|
00E57E 1 ; $E57E-$E59C
|
|
00E57E 1 ; Select a geometry record from the current object's saved selector, compare
|
|
00E57E 1 ; it with the base object, and either update the base object's movement or
|
|
00E57E 1 ; initialize the base object from the current object.
|
|
00E57E 1 ;
|
|
00E57E 1 ; Entry:
|
|
00E57E 1 ; CurrentObjectIndex selects the current object.
|
|
00E57E 1 ;
|
|
00E57E 1 ; Return:
|
|
00E57E 1 ; C = set when the geometry result is at least $02
|
|
00E57E 1 ; C = clear when the geometry result is below $02
|
|
00E57E 1 ; ============================================================================
|
|
00E57E 1
|
|
00E57E 1 ; ----------------------------------------------------------------------------
|
|
00E57E 1 ; Contract:
|
|
00E57E 1 ; Description: Implements Apply Base Object Geometry.
|
|
00E57E 1 ; Entry: Registers: A; Memory: $c5
|
|
00E57E 1 ; Returns/products: Registers/clobbers: A; Flags: condition flags may carry result state
|
|
00E57E 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E57E 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E57E 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E57E 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E57E 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E57E 1 ; ----------------------------------------------------------------------------
|
|
00E57E 1 ApplyBaseObjectGeometry: ; $E57E
|
|
00E57E 1 20 6B E4 jsr GetCurrentGeometryRecordOffset
|
|
00E581 1 ; $E57E: 20 6B E4
|
|
00E581 1
|
|
00E581 1 20 C2 E4 jsr LoadGeometryRecord ; $E581: 20 C2 E4
|
|
00E584 1
|
|
00E584 1 ; ----------------------------------------------------------------------------
|
|
00E584 1 ; Calculate and evaluate the difference between the loaded geometry record
|
|
00E584 1 ; and the base object at array offset zero.
|
|
00E584 1 ; ----------------------------------------------------------------------------
|
|
00E584 1
|
|
00E584 1 20 D7 E4 jsr CalculateBaseGeometryDifference
|
|
00E587 1 ; $E584: 20 D7 E4
|
|
00E587 1
|
|
00E587 1 20 02 E5 jsr EvaluateGeometryDifference
|
|
00E58A 1 ; $E587: 20 02 E5
|
|
00E58A 1
|
|
00E58A 1 C9 02 cmp #$02 ; $E58A: C9 02
|
|
00E58C 1 90 0A bcc ApplyBaseObjectGeometry_CopyCurrent
|
|
00E58E 1 ; $E58C: 90 0A
|
|
00E58E 1
|
|
00E58E 1 ; ----------------------------------------------------------------------------
|
|
00E58E 1 ; Geometry result is at least two.
|
|
00E58E 1 ;
|
|
00E58E 1 ; Build a vector using the parameter in $C5, then store the result in the base
|
|
00E58E 1 ; object's position/movement fields.
|
|
00E58E 1 ; ----------------------------------------------------------------------------
|
|
00E58E 1
|
|
00E58E 1 A5 C5 lda $C5 ; $E58E: A5 C5
|
|
00E590 1
|
|
00E590 1 20 13 E5 jsr BuildGeometryVector ; $E590: 20 13 E5
|
|
00E593 1 20 33 E5 jsr StoreBaseObjectPositionAndClearMovement
|
|
00E596 1 ; $E593: 20 33 E5
|
|
00E596 1
|
|
00E596 1 38 sec ; $E596: 38
|
|
00E597 1 60 rts ; $E597: 60
|
|
00E598 1
|
|
00E598 1 ; ----------------------------------------------------------------------------
|
|
00E598 1 ; Geometry result is below two.
|
|
00E598 1 ;
|
|
00E598 1 ; Initialize the base object from the current object and return carry clear.
|
|
00E598 1 ; ----------------------------------------------------------------------------
|
|
00E598 1
|
|
00E598 1 ApplyBaseObjectGeometry_CopyCurrent: ; $E598
|
|
00E598 1 20 E6 E3 jsr InitializeBaseObjectFromCurrent
|
|
00E59B 1 ; $E598: 20 E6 E3
|
|
00E59B 1
|
|
00E59B 1 18 clc ; $E59B: 18
|
|
00E59C 1 60 rts ; $E59C: 60
|
|
00E59D 1
|
|
00E59D 1 ; ============================================================================
|
|
00E59D 1 ; $E59D-$E5CE
|
|
00E59D 1 ; Evaluate both current-object and base-object geometry, calculate a bounded
|
|
00E59D 1 ; shared vector parameter, apply that vector to the base object, and activate
|
|
00E59D 1 ; motion.
|
|
00E59D 1 ;
|
|
00E59D 1 ; This routine combines the geometry results from two separate record
|
|
00E59D 1 ; selections:
|
|
00E59D 1 ;
|
|
00E59D 1 ; 1. Selector-dependent record chosen by $E474.
|
|
00E59D 1 ; 2. Current-selector record chosen by $E46B.
|
|
00E59D 1 ; ============================================================================
|
|
00E59D 1
|
|
00E59D 1 ; ----------------------------------------------------------------------------
|
|
00E59D 1 ; Contract:
|
|
00E59D 1 ; Description: Initializes Shared Object Motion.
|
|
00E59D 1 ; Entry: Registers: A
|
|
00E59D 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E59D 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E59D 1 ; Memory effects: $c5
|
|
00E59D 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E59D 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E59D 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E59D 1 ; ----------------------------------------------------------------------------
|
|
00E59D 1 InitializeSharedObjectMotion: ; $E59D
|
|
00E59D 1 20 74 E4 jsr SelectGeometryRecord_Default
|
|
00E5A0 1 ; $E59D: 20 74 E4
|
|
00E5A0 1
|
|
00E5A0 1 20 C2 E4 jsr LoadGeometryRecord ; $E5A0: 20 C2 E4
|
|
00E5A3 1
|
|
00E5A3 1 20 DB E4 jsr CalculateCurrentGeometryDifference
|
|
00E5A6 1 ; $E5A3: 20 DB E4
|
|
00E5A6 1
|
|
00E5A6 1 20 02 E5 jsr EvaluateGeometryDifference
|
|
00E5A9 1 ; $E5A6: 20 02 E5
|
|
00E5A9 1
|
|
00E5A9 1 48 pha ; $E5A9: 48
|
|
00E5AA 1 ; Preserve the current-object geometry result.
|
|
00E5AA 1
|
|
00E5AA 1 ; ----------------------------------------------------------------------------
|
|
00E5AA 1 ; Select and evaluate the corresponding geometry relative to the base object.
|
|
00E5AA 1 ; ----------------------------------------------------------------------------
|
|
00E5AA 1
|
|
00E5AA 1 20 6B E4 jsr GetCurrentGeometryRecordOffset
|
|
00E5AD 1 ; $E5AA: 20 6B E4
|
|
00E5AD 1
|
|
00E5AD 1 20 C2 E4 jsr LoadGeometryRecord ; $E5AD: 20 C2 E4
|
|
00E5B0 1
|
|
00E5B0 1 20 D7 E4 jsr CalculateBaseGeometryDifference
|
|
00E5B3 1 ; $E5B0: 20 D7 E4
|
|
00E5B3 1
|
|
00E5B3 1 20 02 E5 jsr EvaluateGeometryDifference
|
|
00E5B6 1 ; $E5B3: 20 02 E5
|
|
00E5B6 1
|
|
00E5B6 1 AA tax ; $E5B6: AA
|
|
00E5B7 1 ; X = base-object geometry result.
|
|
00E5B7 1
|
|
00E5B7 1 68 pla ; $E5B7: 68
|
|
00E5B8 1 A8 tay ; $E5B8: A8
|
|
00E5B9 1 ; Y = current-object geometry result.
|
|
00E5B9 1
|
|
00E5B9 1 ; ----------------------------------------------------------------------------
|
|
00E5B9 1 ; Call the math helper at $E965 with:
|
|
00E5B9 1 ;
|
|
00E5B9 1 ; A = $0F
|
|
00E5B9 1 ; X = base-object result
|
|
00E5B9 1 ; Y = current-object result
|
|
00E5B9 1 ;
|
|
00E5B9 1 ; Clamp its returned value to a maximum of $19.
|
|
00E5B9 1 ; ----------------------------------------------------------------------------
|
|
00E5B9 1
|
|
00E5B9 1 A9 0F lda #$0F ; $E5B9: A9 0F
|
|
00E5BB 1 20 65 E9 jsr CalculateScaledRatio ; $E5BB: 20 65 E9
|
|
00E5BE 1
|
|
00E5BE 1 C9 19 cmp #$19 ; $E5BE: C9 19
|
|
00E5C0 1 90 02 bcc InitializeSharedObjectMotion_Save
|
|
00E5C2 1 ; $E5C0: 90 02
|
|
00E5C2 1
|
|
00E5C2 1 A9 19 lda #$19 ; $E5C2: A9 19
|
|
00E5C4 1
|
|
00E5C4 1 InitializeSharedObjectMotion_Save: ; $E5C4
|
|
00E5C4 1 85 C5 sta $C5 ; $E5C4: 85 C5
|
|
00E5C6 1
|
|
00E5C6 1 ; ----------------------------------------------------------------------------
|
|
00E5C6 1 ; Build and store the resulting vector in the base object.
|
|
00E5C6 1 ; ----------------------------------------------------------------------------
|
|
00E5C6 1
|
|
00E5C6 1 20 13 E5 jsr BuildGeometryVector ; $E5C6: 20 13 E5
|
|
00E5C9 1
|
|
00E5C9 1 20 33 E5 jsr StoreBaseObjectPositionAndClearMovement
|
|
00E5CC 1 ; $E5C9: 20 33 E5
|
|
00E5CC 1
|
|
00E5CC 1 ; ----------------------------------------------------------------------------
|
|
00E5CC 1 ; Mark base motion active.
|
|
00E5CC 1 ; ----------------------------------------------------------------------------
|
|
00E5CC 1
|
|
00E5CC 1 E6 5C inc BaseMotionActive ; $E5CC: E6 5C
|
|
00E5CE 1
|
|
00E5CE 1 60 rts ; $E5CE: 60
|
|
00E5CF 1
|
|
00E5CF 1 ; ============================================================================
|
|
00E5CF 1 ; $E5CF-$E5F3
|
|
00E5CF 1 ; Build a short PPU/display queue entry in the buffer at $0300.
|
|
00E5CF 1 ;
|
|
00E5CF 1 ; The routine:
|
|
00E5CF 1 ; 1. Calls $EA3E with A=$22, X=$A8, Y=$03, and carry set.
|
|
00E5CF 1 ; 2. Saves the returned buffer index from X in $05.
|
|
00E5CF 1 ; 3. Writes three copies of tile/value $25 into $0300,X.
|
|
00E5CF 1 ; 4. Uses bit zero of ModeFlags to select one of two final buffer positions.
|
|
00E5CF 1 ; 5. Writes tile/value $AE at that selected position.
|
|
00E5CF 1 ;
|
|
00E5CF 1 ; The exact semantics of $EA3E are not yet decoded, but it appears to prepare
|
|
00E5CF 1 ; or reserve a display/PPU queue entry and return its starting index in X.
|
|
00E5CF 1 ; ============================================================================
|
|
00E5CF 1
|
|
00E5CF 1 ; ----------------------------------------------------------------------------
|
|
00E5CF 1 ; Contract:
|
|
00E5CF 1 ; Description: Queues Mode Indicator Tiles.
|
|
00E5CF 1 ; Entry: Registers: A, X, Y; Memory: modeflags, $05
|
|
00E5CF 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E5CF 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E5CF 1 ; Memory effects: $05, $0300
|
|
00E5CF 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E5CF 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E5CF 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E5CF 1 ; ----------------------------------------------------------------------------
|
|
00E5CF 1 QueueModeIndicatorTiles: ; $E5CF
|
|
00E5CF 1 A9 22 lda #$22 ; $E5CF: A9 22
|
|
00E5D1 1 ; Display/PPU destination parameter.
|
|
00E5D1 1
|
|
00E5D1 1 A2 A8 ldx #$A8 ; $E5D1: A2 A8
|
|
00E5D3 1 ; Tile, address, or queue parameter.
|
|
00E5D3 1
|
|
00E5D3 1 A0 03 ldy #$03 ; $E5D3: A0 03
|
|
00E5D5 1 ; Record length or field count.
|
|
00E5D5 1
|
|
00E5D5 1 38 sec ; $E5D5: 38
|
|
00E5D6 1 ; Carry is an input to $EA3E.
|
|
00E5D6 1
|
|
00E5D6 1 20 3E EA jsr AllocateDisplayBufferRecord ; $E5D6: 20 3E EA
|
|
00E5D9 1 ; Prepare the queue entry.
|
|
00E5D9 1 ; Returns a buffer index in X.
|
|
00E5D9 1
|
|
00E5D9 1 ; ----------------------------------------------------------------------------
|
|
00E5D9 1 ; Preserve the returned buffer index.
|
|
00E5D9 1 ; ----------------------------------------------------------------------------
|
|
00E5D9 1
|
|
00E5D9 1 86 05 stx $05 ; $E5D9: 86 05
|
|
00E5DB 1
|
|
00E5DB 1 ; ----------------------------------------------------------------------------
|
|
00E5DB 1 ; Write three copies of $25 into consecutive bytes of the $0300 buffer.
|
|
00E5DB 1 ;
|
|
00E5DB 1 ; The loop writes:
|
|
00E5DB 1 ;
|
|
00E5DB 1 ; $0300,X = $25
|
|
00E5DB 1 ; $0301,X = $25
|
|
00E5DB 1 ; $0302,X = $25
|
|
00E5DB 1 ; ----------------------------------------------------------------------------
|
|
00E5DB 1
|
|
00E5DB 1 A0 03 ldy #$03 ; $E5DB: A0 03
|
|
00E5DD 1 A9 25 lda #$25 ; $E5DD: A9 25
|
|
00E5DF 1
|
|
00E5DF 1 QueueModeIndicatorTiles_Fill: ; $E5DF
|
|
00E5DF 1 9D 00 03 sta $0300,x ; $E5DF: 9D 00 03
|
|
00E5E2 1 E8 inx ; $E5E2: E8
|
|
00E5E3 1
|
|
00E5E3 1 88 dey ; $E5E3: 88
|
|
00E5E4 1 D0 F9 bne QueueModeIndicatorTiles_Fill
|
|
00E5E6 1 ; $E5E4: D0 F9
|
|
00E5E6 1
|
|
00E5E6 1 ; ----------------------------------------------------------------------------
|
|
00E5E6 1 ; Select the final marker position according to bit zero of ModeFlags.
|
|
00E5E6 1 ;
|
|
00E5E6 1 ; Selected offset:
|
|
00E5E6 1 ;
|
|
00E5E6 1 ; X = saved buffer index + ((ModeFlags & $01) * 2)
|
|
00E5E6 1 ; ----------------------------------------------------------------------------
|
|
00E5E6 1
|
|
00E5E6 1 A5 40 lda ModeFlags ; $E5E6: A5 40
|
|
00E5E8 1 29 01 and #$01 ; $E5E8: 29 01
|
|
00E5EA 1 0A asl ; $E5EA: 0A
|
|
00E5EB 1
|
|
00E5EB 1 65 05 adc $05 ; $E5EB: 65 05
|
|
00E5ED 1 ; Carry is clear after ASL because the input
|
|
00E5ED 1 ; can only be zero or one.
|
|
00E5ED 1
|
|
00E5ED 1 AA tax ; $E5ED: AA
|
|
00E5EE 1
|
|
00E5EE 1 ; ----------------------------------------------------------------------------
|
|
00E5EE 1 ; Write marker tile/value $AE into the selected buffer position.
|
|
00E5EE 1 ; ----------------------------------------------------------------------------
|
|
00E5EE 1
|
|
00E5EE 1 A9 AE lda #$AE ; $E5EE: A9 AE
|
|
00E5F0 1 9D 00 03 sta $0300,x ; $E5F0: 9D 00 03
|
|
00E5F3 1
|
|
00E5F3 1 60 rts ; $E5F3: 60
|
|
00E5F4 1
|
|
00E5F4 1 ; ============================================================================
|
|
00E5F4 1 ; $E5F4
|
|
00E5F4 1 ; Standalone return entry.
|
|
00E5F4 1 ;
|
|
00E5F4 1 ; No decoded branch currently targets this byte, but it is a valid one-byte
|
|
00E5F4 1 ; routine/alternate return immediately before the random-number generator.
|
|
00E5F4 1 ; ============================================================================
|
|
00E5F4 1
|
|
00E5F4 1 Return_E5F4: ; $E5F4
|
|
00E5F4 1 60 rts ; $E5F4: 60
|
|
00E5F5 1
|
|
00E5F5 1 ; ============================================================================
|
|
00E5F5 1 ; $E5F5-$E610
|
|
00E5F5 1 ; Advance the 16-bit pseudo-random state by eight rounds.
|
|
00E5F5 1 ;
|
|
00E5F5 1 ; Random state:
|
|
00E5F5 1 ; $19 = low/output byte
|
|
00E5F5 1 ; $1A = high/feedback byte
|
|
00E5F5 1 ;
|
|
00E5F5 1 ; Working state:
|
|
00E5F5 1 ; $DC = eight-round loop counter
|
|
00E5F5 1 ;
|
|
00E5F5 1 ; Return:
|
|
00E5F5 1 ; A = updated $19
|
|
00E5F5 1 ;
|
|
00E5F5 1 ; The routine shifts the combined random state right. When the shifted-out bit
|
|
00E5F5 1 ; is clear, feedback masks $88 and $10 are XORed into $1A and $19.
|
|
00E5F5 1 ; ============================================================================
|
|
00E5F5 1
|
|
00E5F5 1 ; ----------------------------------------------------------------------------
|
|
00E5F5 1 ; Contract:
|
|
00E5F5 1 ; Description: Implements Advance Random State.
|
|
00E5F5 1 ; Entry: Registers: A; Memory: randomstatelo, randomstatehi
|
|
00E5F5 1 ; Returns/products: Registers/clobbers: A
|
|
00E5F5 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E5F5 1 ; Memory effects: $dc, randomstatehi, randomstatelo
|
|
00E5F5 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E5F5 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E5F5 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 21.
|
|
00E5F5 1 ; ----------------------------------------------------------------------------
|
|
00E5F5 1 AdvanceRandomState: ; $E5F5
|
|
00E5F5 1 A9 08 lda #$08 ; $E5F5: A9 08
|
|
00E5F7 1 85 DC sta $DC ; $E5F7: 85 DC
|
|
00E5F9 1
|
|
00E5F9 1 ; ----------------------------------------------------------------------------
|
|
00E5F9 1 ; Load the low random-state byte once at the start of each round.
|
|
00E5F9 1 ; ----------------------------------------------------------------------------
|
|
00E5F9 1
|
|
00E5F9 1 AdvanceRandomState_Loop: ; $E5F9
|
|
00E5F9 1 A5 19 lda RandomStateLo ; $E5F9: A5 19
|
|
00E5FB 1
|
|
00E5FB 1 ; ----------------------------------------------------------------------------
|
|
00E5FB 1 ; Shift the combined 16-bit state right:
|
|
00E5FB 1 ;
|
|
00E5FB 1 ; LSR $1A shifts the high byte and places its old bit zero in carry.
|
|
00E5FB 1 ; ROR A shifts that carry into bit seven of the low byte.
|
|
00E5FB 1 ;
|
|
00E5FB 1 ; Carry after ROR contains the former bit zero of $19.
|
|
00E5FB 1 ; ----------------------------------------------------------------------------
|
|
00E5FB 1
|
|
00E5FB 1 46 1A lsr RandomStateHi ; $E5FB: 46 1A
|
|
00E5FD 1 6A ror ; $E5FD: 6A
|
|
00E5FE 1
|
|
00E5FE 1 ; ----------------------------------------------------------------------------
|
|
00E5FE 1 ; If the shifted-out low bit was one, store the shifted low byte directly.
|
|
00E5FE 1 ; ----------------------------------------------------------------------------
|
|
00E5FE 1
|
|
00E5FE 1 B0 0A bcs AdvanceRandomState_SaveLow
|
|
00E600 1 ; $E5FE: B0 0A
|
|
00E600 1
|
|
00E600 1 ; ----------------------------------------------------------------------------
|
|
00E600 1 ; The shifted-out low bit was zero.
|
|
00E600 1 ;
|
|
00E600 1 ; Apply feedback masks to both bytes:
|
|
00E600 1 ;
|
|
00E600 1 ; $1A ^= $88
|
|
00E600 1 ; A ^= $10
|
|
00E600 1 ;
|
|
00E600 1 ; A is preserved on the stack while $1A is updated.
|
|
00E600 1 ; ----------------------------------------------------------------------------
|
|
00E600 1
|
|
00E600 1 48 pha ; $E600: 48
|
|
00E601 1
|
|
00E601 1 A5 1A lda RandomStateHi ; $E601: A5 1A
|
|
00E603 1 49 88 eor #$88 ; $E603: 49 88
|
|
00E605 1 85 1A sta RandomStateHi ; $E605: 85 1A
|
|
00E607 1
|
|
00E607 1 68 pla ; $E607: 68
|
|
00E608 1 49 10 eor #$10 ; $E608: 49 10
|
|
00E60A 1
|
|
00E60A 1 ; ----------------------------------------------------------------------------
|
|
00E60A 1 ; Save the updated low byte and continue for eight total rounds.
|
|
00E60A 1 ; ----------------------------------------------------------------------------
|
|
00E60A 1
|
|
00E60A 1 AdvanceRandomState_SaveLow: ; $E60A
|
|
00E60A 1 85 19 sta RandomStateLo ; $E60A: 85 19
|
|
00E60C 1
|
|
00E60C 1 C6 DC dec $DC ; $E60C: C6 DC
|
|
00E60E 1 D0 E9 bne AdvanceRandomState_Loop ; $E60E: D0 E9
|
|
00E610 1
|
|
00E610 1 60 rts ; $E610: 60
|
|
00E611 1
|
|
00E611 1 ; ============================================================================
|
|
00E611 1 ; $E611-$E63D
|
|
00E611 1 ; Multiply an 8-bit value by a signed 16-bit value using eight rounds of
|
|
00E611 1 ; conditional addition and arithmetic right shifting.
|
|
00E611 1 ;
|
|
00E611 1 ; Entry:
|
|
00E611 1 ; A = 8-bit multiplier
|
|
00E611 1 ; Y = multiplicand low byte
|
|
00E611 1 ; X = multiplicand high byte
|
|
00E611 1 ;
|
|
00E611 1 ; Working storage:
|
|
00E611 1 ; $28 = shifting multiplier
|
|
00E611 1 ; $2B/$2C = signed 16-bit multiplicand
|
|
00E611 1 ; $29/$2A = signed 16-bit accumulator/result
|
|
00E611 1 ;
|
|
00E611 1 ; Exit:
|
|
00E611 1 ; Y = result low byte
|
|
00E611 1 ; X = result high byte
|
|
00E611 1 ;
|
|
00E611 1 ; The accumulator is arithmetically shifted right after every round. This
|
|
00E611 1 ; produces a fixed-point scaled result rather than the full 24-bit product.
|
|
00E611 1 ; ============================================================================
|
|
00E611 1
|
|
00E611 1 MultiplyByteBySignedWord: ; $E611
|
|
00E611 1 84 2B sty $2B ; $E611: 84 2B
|
|
00E613 1 ; Save multiplicand low byte.
|
|
00E613 1
|
|
00E613 1 86 2C stx $2C ; $E613: 86 2C
|
|
00E615 1 ; Save multiplicand high byte.
|
|
00E615 1
|
|
00E615 1 85 28 sta $28 ; $E615: 85 28
|
|
00E617 1 ; Save the 8-bit multiplier.
|
|
00E617 1
|
|
00E617 1 ; ----------------------------------------------------------------------------
|
|
00E617 1 ; Clear the signed 16-bit accumulator.
|
|
00E617 1 ; ----------------------------------------------------------------------------
|
|
00E617 1
|
|
00E617 1 A9 00 lda #$00 ; $E617: A9 00
|
|
00E619 1 85 29 sta $29 ; $E619: 85 29
|
|
00E61B 1 ; Accumulator low byte.
|
|
00E61B 1
|
|
00E61B 1 85 2A sta $2A ; $E61B: 85 2A
|
|
00E61D 1 ; Accumulator high byte.
|
|
00E61D 1
|
|
00E61D 1 ; ----------------------------------------------------------------------------
|
|
00E61D 1 ; Process all eight multiplier bits.
|
|
00E61D 1 ; ----------------------------------------------------------------------------
|
|
00E61D 1
|
|
00E61D 1 A2 08 ldx #$08 ; $E61D: A2 08
|
|
00E61F 1
|
|
00E61F 1 MultiplyByteBySignedWord_Loop: ; $E61F
|
|
00E61F 1 66 28 ror $28 ; $E61F: 66 28
|
|
00E621 1 ; Shift the next multiplier bit into carry.
|
|
00E621 1
|
|
00E621 1 90 0D bcc MultiplyByteBySignedWord_Shift
|
|
00E623 1 ; $E621: 90 0D
|
|
00E623 1
|
|
00E623 1 ; ----------------------------------------------------------------------------
|
|
00E623 1 ; The current multiplier bit is one.
|
|
00E623 1 ;
|
|
00E623 1 ; Add the signed 16-bit multiplicand to the accumulator.
|
|
00E623 1 ; ----------------------------------------------------------------------------
|
|
00E623 1
|
|
00E623 1 18 clc ; $E623: 18
|
|
00E624 1
|
|
00E624 1 A5 29 lda $29 ; $E624: A5 29
|
|
00E626 1 65 2B adc $2B ; $E626: 65 2B
|
|
00E628 1 85 29 sta $29 ; $E628: 85 29
|
|
00E62A 1
|
|
00E62A 1 A5 2A lda $2A ; $E62A: A5 2A
|
|
00E62C 1 65 2C adc $2C ; $E62C: 65 2C
|
|
00E62E 1 85 2A sta $2A ; $E62E: 85 2A
|
|
00E630 1
|
|
00E630 1 ; ----------------------------------------------------------------------------
|
|
00E630 1 ; Arithmetically shift the signed accumulator right by one bit.
|
|
00E630 1 ;
|
|
00E630 1 ; CMP #$80 copies the sign bit of the high accumulator byte into carry:
|
|
00E630 1 ;
|
|
00E630 1 ; $2A >= $80 -> carry set
|
|
00E630 1 ; $2A < $80 -> carry clear
|
|
00E630 1 ;
|
|
00E630 1 ; ROR $2A therefore preserves the sign bit. ROR $29 completes the signed
|
|
00E630 1 ; 16-bit right shift.
|
|
00E630 1 ; ----------------------------------------------------------------------------
|
|
00E630 1
|
|
00E630 1 MultiplyByteBySignedWord_Shift: ; $E630
|
|
00E630 1 C9 80 cmp #$80 ; $E630: C9 80
|
|
00E632 1
|
|
00E632 1 66 2A ror $2A ; $E632: 66 2A
|
|
00E634 1 66 29 ror $29 ; $E634: 66 29
|
|
00E636 1
|
|
00E636 1 ; ----------------------------------------------------------------------------
|
|
00E636 1 ; Continue until all eight multiplier bits have been processed.
|
|
00E636 1 ; ----------------------------------------------------------------------------
|
|
00E636 1
|
|
00E636 1 CA dex ; $E636: CA
|
|
00E637 1 D0 E6 bne MultiplyByteBySignedWord_Loop
|
|
00E639 1 ; $E637: D0 E6
|
|
00E639 1
|
|
00E639 1 ; ----------------------------------------------------------------------------
|
|
00E639 1 ; Return the signed 16-bit result in Y:X.
|
|
00E639 1 ; ----------------------------------------------------------------------------
|
|
00E639 1
|
|
00E639 1 A4 29 ldy $29 ; $E639: A4 29
|
|
00E63B 1 A6 2A ldx $2A ; $E63B: A6 2A
|
|
00E63D 1
|
|
00E63D 1 60 rts ; $E63D: 60
|
|
00E63E 1
|
|
00E63E 1 ; ============================================================================
|
|
00E63E 1 ; $E63E-$E672
|
|
00E63E 1 ; Perform an eight-round restoring division or normalization operation.
|
|
00E63E 1 ;
|
|
00E63E 1 ; Entry:
|
|
00E63E 1 ; Y = initial low working byte
|
|
00E63E 1 ; A = initial high working byte
|
|
00E63E 1 ; $2D/$2E = 16-bit divisor or comparison value
|
|
00E63E 1 ; $28 = quotient/result shift register
|
|
00E63E 1 ;
|
|
00E63E 1 ; Working values:
|
|
00E63E 1 ; $29/$2A = 16-bit partial remainder
|
|
00E63E 1 ;
|
|
00E63E 1 ; Exit:
|
|
00E63E 1 ; A = quotient/result byte from $28
|
|
00E63E 1 ; X = adjustment or status value
|
|
00E63E 1 ;
|
|
00E63E 1 ; Failure/overflow:
|
|
00E63E 1 ; A = $00
|
|
00E63E 1 ;
|
|
00E63E 1 ; The exact numeric interpretation should remain provisional until all callers
|
|
00E63E 1 ; are analyzed, but the implementation follows a restoring-division pattern.
|
|
00E63E 1 ; ============================================================================
|
|
00E63E 1
|
|
00E63E 1 ; ----------------------------------------------------------------------------
|
|
00E63E 1 ; Contract:
|
|
00E63E 1 ; Description: Implements Divide Or Normalize Word.
|
|
00E63E 1 ; Entry: Registers: A, X, Y; Memory: $29, $2d, $2a, $2e
|
|
00E63E 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E63E 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E63E 1 ; Memory effects: $29, $2a
|
|
00E63E 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E63E 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E63E 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00E63E 1 ; ----------------------------------------------------------------------------
|
|
00E63E 1 DivideOrNormalizeWord: ; $E63E
|
|
00E63E 1 84 29 sty $29 ; $E63E: 84 29
|
|
00E640 1 85 2A sta $2A ; $E640: 85 2A
|
|
00E642 1
|
|
00E642 1 A2 08 ldx #$08 ; $E642: A2 08
|
|
00E644 1 ; Process eight output bits.
|
|
00E644 1
|
|
00E644 1 ; ----------------------------------------------------------------------------
|
|
00E644 1 ; Add the divisor to the current partial remainder.
|
|
00E644 1 ; ----------------------------------------------------------------------------
|
|
00E644 1
|
|
00E644 1 DivideOrNormalizeWord_Loop: ; $E644
|
|
00E644 1 18 clc ; $E644: 18
|
|
00E645 1
|
|
00E645 1 A5 29 lda $29 ; $E645: A5 29
|
|
00E647 1 65 2D adc $2D ; $E647: 65 2D
|
|
00E649 1 A8 tay ; $E649: A8
|
|
00E64A 1
|
|
00E64A 1 A5 2A lda $2A ; $E64A: A5 2A
|
|
00E64C 1 65 2E adc $2E ; $E64C: 65 2E
|
|
00E64E 1
|
|
00E64E 1 ; ----------------------------------------------------------------------------
|
|
00E64E 1 ; If the addition overflowed, retain the previous partial remainder.
|
|
00E64E 1 ;
|
|
00E64E 1 ; Otherwise, save the candidate remainder from A:Y.
|
|
00E64E 1 ; ----------------------------------------------------------------------------
|
|
00E64E 1 DivideOrNormalizeWord_CheckCarry: ; $E64E
|
|
00E64E 1 90 04 bcc DivideOrNormalizeWord_Shift
|
|
00E650 1 ; $E64E: 90 04
|
|
00E650 1
|
|
00E650 1 84 29 sty $29 ; $E650: 84 29
|
|
00E652 1 85 2A sta $2A ; $E652: 85 2A
|
|
00E654 1
|
|
00E654 1 ; ----------------------------------------------------------------------------
|
|
00E654 1 ; Shift the quotient/result and partial remainder left.
|
|
00E654 1 ; ----------------------------------------------------------------------------
|
|
00E654 1
|
|
00E654 1 DivideOrNormalizeWord_Shift: ; $E654
|
|
00E654 1 26 28 rol $28 ; $E654: 26 28
|
|
00E656 1
|
|
00E656 1 06 29 asl $29 ; $E656: 06 29
|
|
00E658 1 26 2A rol $2A ; $E658: 26 2A
|
|
00E65A 1
|
|
00E65A 1 B0 14 bcs DivideOrNormalizeWord_Overflow
|
|
00E65C 1 ; $E65A: B0 14
|
|
00E65C 1
|
|
00E65C 1 ; ----------------------------------------------------------------------------
|
|
00E65C 1 ; Subtract the divisor to prepare the next candidate remainder.
|
|
00E65C 1 ; ----------------------------------------------------------------------------
|
|
00E65C 1
|
|
00E65C 1 38 sec ; $E65C: 38
|
|
00E65D 1
|
|
00E65D 1 A5 29 lda $29 ; $E65D: A5 29
|
|
00E65F 1 E5 2D sbc $2D ; $E65F: E5 2D
|
|
00E661 1 A8 tay ; $E661: A8
|
|
00E662 1
|
|
00E662 1 A5 2A lda $2A ; $E662: A5 2A
|
|
00E664 1 E5 2E sbc $2E ; $E664: E5 2E
|
|
00E666 1
|
|
00E666 1 CA dex ; $E666: CA
|
|
00E667 1 D0 E5 bne DivideOrNormalizeWord_CheckCarry
|
|
00E669 1 ; $E667: D0 E5
|
|
00E669 1 ; Continue from the quotient/remainder shift.
|
|
00E669 1
|
|
00E669 1 ; ----------------------------------------------------------------------------
|
|
00E669 1 ; Return the quotient/result byte.
|
|
00E669 1 ;
|
|
00E669 1 ; X is adjusted according to carry from the final subtraction.
|
|
00E669 1 ; ----------------------------------------------------------------------------
|
|
00E669 1
|
|
00E669 1 A5 28 lda $28 ; $E669: A5 28
|
|
00E66B 1
|
|
00E66B 1 CA dex ; $E66B: CA
|
|
00E66C 1 B0 01 bcs DivideOrNormalizeWord_Return
|
|
00E66E 1 ; $E66C: B0 01
|
|
00E66E 1
|
|
00E66E 1 CA dex ; $E66E: CA
|
|
00E66F 1
|
|
00E66F 1 DivideOrNormalizeWord_Return: ; $E66F
|
|
00E66F 1 60 rts ; $E66F: 60
|
|
00E670 1
|
|
00E670 1 ; ----------------------------------------------------------------------------
|
|
00E670 1 ; Overflow path.
|
|
00E670 1 ; ----------------------------------------------------------------------------
|
|
00E670 1
|
|
00E670 1 DivideOrNormalizeWord_Overflow: ; $E670
|
|
00E670 1 A9 00 lda #$00 ; $E670: A9 00
|
|
00E672 1 60 rts ; $E672: 60
|
|
00E673 1
|
|
00E673 1 ; ============================================================================
|
|
00E673 1 ; $E673-$E6C0
|
|
00E673 1 ; Build transformed movement/vector components from object state.
|
|
00E673 1 ;
|
|
00E673 1 ; Three entry paths are present:
|
|
00E673 1 ;
|
|
00E673 1 ; $E673 uses movement values at $056D/$056E.
|
|
00E673 1 ; $E695 uses movement values at $056B/$056C.
|
|
00E673 1 ; $E6B7 clears all four transformed results.
|
|
00E673 1 ;
|
|
00E673 1 ; Results:
|
|
00E673 1 ; $31/$32 = first transformed 16-bit component
|
|
00E673 1 ; $2F/$30 = second transformed 16-bit component
|
|
00E673 1 ;
|
|
00E673 1 ; The transformation helper is MultiplyByteBySignedWord at $E611.
|
|
00E673 1 ; ============================================================================
|
|
00E673 1
|
|
00E673 1 ; ----------------------------------------------------------------------------
|
|
00E673 1 ; Contract:
|
|
00E673 1 ; Description: Implements Build Current Movement Transforms.
|
|
00E673 1 ; Entry: Registers: A, X, Y; Memory: $056d, $056e, $cf, $d1, $056b, $056c
|
|
00E673 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E673 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E673 1 ; Memory effects: $31, selectionvalue0, $2f, $30, $32
|
|
00E673 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E673 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E673 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E673 1 ; ----------------------------------------------------------------------------
|
|
00E673 1 BuildCurrentMovementTransforms: ; $E673
|
|
00E673 1 AC 6D 05 ldy $056D ; $E673: AC 6D 05
|
|
00E676 1 AE 6E 05 ldx $056E ; $E676: AE 6E 05
|
|
00E679 1
|
|
00E679 1 A5 CF lda $CF ; $E679: A5 CF
|
|
00E67B 1 20 11 E6 jsr MultiplyByteBySignedWord
|
|
00E67E 1 ; $E67B: 20 11 E6
|
|
00E67E 1
|
|
00E67E 1 84 31 sty $31 ; $E67E: 84 31
|
|
00E680 1 86 32 stx SelectionValue0 ; $E680: 86 32
|
|
00E682 1
|
|
00E682 1 AC 6D 05 ldy $056D ; $E682: AC 6D 05
|
|
00E685 1 AE 6E 05 ldx $056E ; $E685: AE 6E 05
|
|
00E688 1
|
|
00E688 1 A5 D1 lda $D1 ; $E688: A5 D1
|
|
00E68A 1 20 11 E6 jsr MultiplyByteBySignedWord
|
|
00E68D 1 ; $E68A: 20 11 E6
|
|
00E68D 1
|
|
00E68D 1 84 2F sty $2F ; $E68D: 84 2F
|
|
00E68F 1 86 30 stx $30 ; $E68F: 86 30
|
|
00E691 1
|
|
00E691 1 ; ----------------------------------------------------------------------------
|
|
00E691 1 ; X is cleared and BEQ is therefore unconditional.
|
|
00E691 1 ; ----------------------------------------------------------------------------
|
|
00E691 1
|
|
00E691 1 A2 00 ldx #$00 ; $E691: A2 00
|
|
00E693 1 F0 2C beq ProjectObjectCoordinates
|
|
00E695 1 ; $E693: F0 2C
|
|
00E695 1
|
|
00E695 1 ; ----------------------------------------------------------------------------
|
|
00E695 1 ; Alternate entry using the base movement values at $056B/$056C.
|
|
00E695 1 ; ----------------------------------------------------------------------------
|
|
00E695 1
|
|
00E695 1 ; ----------------------------------------------------------------------------
|
|
00E695 1 ; Contract:
|
|
00E695 1 ; Description: Implements Build Base Movement Transforms.
|
|
00E695 1 ; Entry: Registers: A, X, Y; Memory: $056b, $056c, $cf, $d1, $053a, $d2
|
|
00E695 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E695 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E695 1 ; Memory effects: $31, $32, $2f, $30
|
|
00E695 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E695 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E695 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E695 1 ; ----------------------------------------------------------------------------
|
|
00E695 1 BuildBaseMovementTransforms: ; $E695
|
|
00E695 1 AC 6B 05 ldy $056B ; $E695: AC 6B 05
|
|
00E698 1 AE 6C 05 ldx $056C ; $E698: AE 6C 05
|
|
00E69B 1
|
|
00E69B 1 A5 CF lda $CF ; $E69B: A5 CF
|
|
00E69D 1 20 11 E6 jsr MultiplyByteBySignedWord
|
|
00E6A0 1 ; $E69D: 20 11 E6
|
|
00E6A0 1
|
|
00E6A0 1 84 31 sty $31 ; $E6A0: 84 31
|
|
00E6A2 1 86 32 stx SelectionValue0 ; $E6A2: 86 32
|
|
00E6A4 1
|
|
00E6A4 1 AC 6B 05 ldy $056B ; $E6A4: AC 6B 05
|
|
00E6A7 1 AE 6C 05 ldx $056C ; $E6A7: AE 6C 05
|
|
00E6AA 1
|
|
00E6AA 1 A5 D1 lda $D1 ; $E6AA: A5 D1
|
|
00E6AC 1 20 11 E6 jsr MultiplyByteBySignedWord
|
|
00E6AF 1 ; $E6AC: 20 11 E6
|
|
00E6AF 1
|
|
00E6AF 1 84 2F sty $2F ; $E6AF: 84 2F
|
|
00E6B1 1 86 30 stx $30 ; $E6B1: 86 30
|
|
00E6B3 1
|
|
00E6B3 1 A2 00 ldx #$00 ; $E6B3: A2 00
|
|
00E6B5 1 F0 0A beq ProjectObjectCoordinates
|
|
00E6B7 1 ; $E6B5: F0 0A
|
|
00E6B7 1
|
|
00E6B7 1 ; ----------------------------------------------------------------------------
|
|
00E6B7 1 ; Alternate entry that clears every transformed component.
|
|
00E6B7 1 ; ----------------------------------------------------------------------------
|
|
00E6B7 1
|
|
00E6B7 1 ; ----------------------------------------------------------------------------
|
|
00E6B7 1 ; Contract:
|
|
00E6B7 1 ; Description: Clears or resets Movement Transforms.
|
|
00E6B7 1 ; Entry: Registers: A, X, Y; Memory: $053a, $d2, $053b, $d3, $ce, $cc, $cd, $31
|
|
00E6B7 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E6B7 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E6B7 1 ; Memory effects: $31, $32, $2f, $30, $06, $08, $09, $2d
|
|
00E6B7 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E6B7 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E6B7 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 15.
|
|
00E6B7 1 ; ----------------------------------------------------------------------------
|
|
00E6B7 1 ClearMovementTransforms: ; $E6B7
|
|
00E6B7 1 A9 00 lda #$00 ; $E6B7: A9 00
|
|
00E6B9 1
|
|
00E6B9 1 85 31 sta $31 ; $E6B9: 85 31
|
|
00E6BB 1 85 32 sta SelectionValue0 ; $E6BB: 85 32
|
|
00E6BD 1 85 2F sta $2F ; $E6BD: 85 2F
|
|
00E6BF 1 85 30 sta $30 ; $E6BF: 85 30
|
|
00E6C1 1
|
|
00E6C1 1 ; ============================================================================
|
|
00E6C1 1 ; $E6C1-$E737
|
|
00E6C1 1 ; Project one object's coordinates through the current transformation state.
|
|
00E6C1 1 ;
|
|
00E6C1 1 ; Entry:
|
|
00E6C1 1 ; X = source object offset
|
|
00E6C1 1 ;
|
|
00E6C1 1 ; Working values:
|
|
00E6C1 1 ; $06 = saved object offset
|
|
00E6C1 1 ; $08/$09 = adjusted source vertical coordinate
|
|
00E6C1 1 ; $2D/$2E = transformed intermediate vector
|
|
00E6C1 1 ; $36/$37 = projected horizontal result
|
|
00E6C1 1 ; $38/$39 = projected vertical result
|
|
00E6C1 1 ;
|
|
00E6C1 1 ; Return:
|
|
00E6C1 1 ; C = clear when projection succeeds
|
|
00E6C1 1 ; C = set when projection fails or lies outside the accepted range
|
|
00E6C1 1 ;
|
|
00E6C1 1 ; On success, selected projections are written to:
|
|
00E6C1 1 ; $03BC,X
|
|
00E6C1 1 ; $03DE,X
|
|
00E6C1 1 ; ============================================================================
|
|
00E6C1 1
|
|
00E6C1 1 ProjectObjectCoordinates: ; $E6C1
|
|
00E6C1 1 86 06 stx $06 ; $E6C1: 86 06
|
|
00E6C3 1
|
|
00E6C3 1 ; ----------------------------------------------------------------------------
|
|
00E6C3 1 ; Add the global vertical offset $D2/$D3 to the object's vertical coordinate.
|
|
00E6C3 1 ; ----------------------------------------------------------------------------
|
|
00E6C3 1
|
|
00E6C3 1 18 clc ; $E6C3: 18
|
|
00E6C4 1
|
|
00E6C4 1 BD 3A 05 lda $053A,x ; $E6C4: BD 3A 05
|
|
00E6C7 1 65 D2 adc $D2 ; $E6C7: 65 D2
|
|
00E6C9 1 85 08 sta $08 ; $E6C9: 85 08
|
|
00E6CB 1 A8 tay ; $E6CB: A8
|
|
00E6CC 1
|
|
00E6CC 1 BD 3B 05 lda $053B,x ; $E6CC: BD 3B 05
|
|
00E6CF 1 65 D3 adc $D3 ; $E6CF: 65 D3
|
|
00E6D1 1 85 09 sta $09 ; $E6D1: 85 09
|
|
00E6D3 1 AA tax ; $E6D3: AA
|
|
00E6D4 1
|
|
00E6D4 1 ; ----------------------------------------------------------------------------
|
|
00E6D4 1 ; Scale or transform the adjusted coordinate using parameter $CE.
|
|
00E6D4 1 ; ----------------------------------------------------------------------------
|
|
00E6D4 1
|
|
00E6D4 1 A5 CE lda $CE ; $E6D4: A5 CE
|
|
00E6D6 1 20 11 E6 jsr MultiplyByteBySignedWord
|
|
00E6D9 1 ; $E6D6: 20 11 E6
|
|
00E6D9 1
|
|
00E6D9 1 ; ----------------------------------------------------------------------------
|
|
00E6D9 1 ; Add global offsets $CC/$CD to the transformed result.
|
|
00E6D9 1 ; ----------------------------------------------------------------------------
|
|
00E6D9 1
|
|
00E6D9 1 18 clc ; $E6D9: 18
|
|
00E6DA 1
|
|
00E6DA 1 98 tya ; $E6DA: 98
|
|
00E6DB 1 65 CC adc $CC ; $E6DB: 65 CC
|
|
00E6DD 1 A8 tay ; $E6DD: A8
|
|
00E6DE 1
|
|
00E6DE 1 8A txa ; $E6DE: 8A
|
|
00E6DF 1 65 CD adc $CD ; $E6DF: 65 CD
|
|
00E6E1 1 AA tax ; $E6E1: AA
|
|
00E6E2 1
|
|
00E6E2 1 ; ----------------------------------------------------------------------------
|
|
00E6E2 1 ; Subtract transformed component $31/$32 and divide the result by two.
|
|
00E6E2 1 ; ----------------------------------------------------------------------------
|
|
00E6E2 1
|
|
00E6E2 1 98 tya ; $E6E2: 98
|
|
00E6E3 1 38 sec ; $E6E3: 38
|
|
00E6E4 1 E5 31 sbc $31 ; $E6E4: E5 31
|
|
00E6E6 1 85 2D sta $2D ; $E6E6: 85 2D
|
|
00E6E8 1
|
|
00E6E8 1 8A txa ; $E6E8: 8A
|
|
00E6E9 1 E5 32 sbc SelectionValue0 ; $E6E9: E5 32
|
|
00E6EB 1
|
|
00E6EB 1 4A lsr ; $E6EB: 4A
|
|
00E6EC 1 85 2E sta $2E ; $E6EC: 85 2E
|
|
00E6EE 1 66 2D ror $2D ; $E6EE: 66 2D
|
|
00E6F0 1
|
|
00E6F0 1 ; ----------------------------------------------------------------------------
|
|
00E6F0 1 ; Transform the adjusted source coordinate using parameter $D0.
|
|
00E6F0 1 ; ----------------------------------------------------------------------------
|
|
00E6F0 1
|
|
00E6F0 1 A4 08 ldy $08 ; $E6F0: A4 08
|
|
00E6F2 1 A6 09 ldx $09 ; $E6F2: A6 09
|
|
00E6F4 1
|
|
00E6F4 1 A5 D0 lda $D0 ; $E6F4: A5 D0
|
|
00E6F6 1 20 11 E6 jsr MultiplyByteBySignedWord
|
|
00E6F9 1 ; $E6F6: 20 11 E6
|
|
00E6F9 1
|
|
00E6F9 1 ; ----------------------------------------------------------------------------
|
|
00E6F9 1 ; Add transformed component $2F/$30.
|
|
00E6F9 1 ; ----------------------------------------------------------------------------
|
|
00E6F9 1
|
|
00E6F9 1 18 clc ; $E6F9: 18
|
|
00E6FA 1
|
|
00E6FA 1 98 tya ; $E6FA: 98
|
|
00E6FB 1 65 2F adc $2F ; $E6FB: 65 2F
|
|
00E6FD 1 A8 tay ; $E6FD: A8
|
|
00E6FE 1
|
|
00E6FE 1 8A txa ; $E6FE: 8A
|
|
00E6FF 1 65 30 adc $30 ; $E6FF: 65 30
|
|
00E701 1
|
|
00E701 1 ; ----------------------------------------------------------------------------
|
|
00E701 1 ; Normalize or divide the result through the arithmetic helper at $E63E.
|
|
00E701 1 ; ----------------------------------------------------------------------------
|
|
00E701 1
|
|
00E701 1 20 3E E6 jsr DivideOrNormalizeWord ; $E701: 20
|
|
00E704 1 ; ----------------------------------------------------------------------------
|
|
00E704 1 ; Reject a zero normalization result.
|
|
00E704 1 ; ----------------------------------------------------------------------------
|
|
00E704 1
|
|
00E704 1 F0 30 beq ProjectObjectCoordinates_Fail
|
|
00E706 1 ; $E704: F0 30
|
|
00E706 1
|
|
00E706 1 ; ----------------------------------------------------------------------------
|
|
00E706 1 ; Convert the returned vertical result into the projected display coordinate.
|
|
00E706 1 ; ----------------------------------------------------------------------------
|
|
00E706 1
|
|
00E706 1 E9 00 sbc #$00 ; $E706: E9 00
|
|
00E708 1 49 7F eor #$7F ; $E708: 49 7F
|
|
00E70A 1
|
|
00E70A 1 85 38 sta ObjectScreenY ; $E70A: 85 38
|
|
00E70C 1 86 39 stx ObjectScreenYHi ; $E70C: 86 39
|
|
00E70E 1
|
|
00E70E 1 ; ----------------------------------------------------------------------------
|
|
00E70E 1 ; Restore the source object offset and normalize its horizontal coordinate.
|
|
00E70E 1 ; ----------------------------------------------------------------------------
|
|
00E70E 1
|
|
00E70E 1 A6 06 ldx $06 ; $E70E: A6 06
|
|
00E710 1
|
|
00E710 1 BC 09 05 ldy $0509,x ; $E710: BC 09 05
|
|
00E713 1 BD 0A 05 lda $050A,x ; $E713: BD 0A 05
|
|
00E716 1
|
|
00E716 1 20 3E E6 jsr DivideOrNormalizeWord ; $E716: 20 3E E6
|
|
00E719 1
|
|
00E719 1 F0 1B beq ProjectObjectCoordinates_Fail
|
|
00E71B 1 ; $E719: F0 1B
|
|
00E71B 1
|
|
00E71B 1 ; ----------------------------------------------------------------------------
|
|
00E71B 1 ; Convert the returned horizontal result into the projected display coordinate.
|
|
00E71B 1 ; ----------------------------------------------------------------------------
|
|
00E71B 1
|
|
00E71B 1 69 80 adc #$80 ; $E71B: 69 80
|
|
00E71D 1
|
|
00E71D 1 85 36 sta ObjectScreenX ; $E71D: 85 36
|
|
00E71F 1 86 37 stx ObjectScreenXHi ; $E71F: 86 37
|
|
00E721 1
|
|
00E721 1 ; ----------------------------------------------------------------------------
|
|
00E721 1 ; Convert the source object offset to its display-array index.
|
|
00E721 1 ; ----------------------------------------------------------------------------
|
|
00E721 1
|
|
00E721 1 A6 06 ldx $06 ; $E721: A6 06
|
|
00E723 1
|
|
00E723 1 20 38 E7 jsr ConvertObjectOffsetToDisplayIndex
|
|
00E726 1 ; $E723: 20 38 E7
|
|
00E726 1
|
|
00E726 1 ; ----------------------------------------------------------------------------
|
|
00E726 1 ; Display indices $22 and above return without writing to the projection
|
|
00E726 1 ; arrays. Carry remains set from CPX #$22 in that case.
|
|
00E726 1 ; ----------------------------------------------------------------------------
|
|
00E726 1
|
|
00E726 1 E0 22 cpx #$22 ; $E726: E0 22
|
|
00E728 1 B0 0B bcs ProjectObjectCoordinates_Return
|
|
00E72A 1 ; $E728: B0 0B
|
|
00E72A 1
|
|
00E72A 1 ; ----------------------------------------------------------------------------
|
|
00E72A 1 ; Save the projected horizontal and vertical coordinates.
|
|
00E72A 1 ; ----------------------------------------------------------------------------
|
|
00E72A 1
|
|
00E72A 1 A5 36 lda ObjectScreenX ; $E72A: A5 36
|
|
00E72C 1 9D BC 03 sta $03BC,x ; $E72C: 9D BC 03
|
|
00E72F 1
|
|
00E72F 1 A5 38 lda ObjectScreenY ; $E72F: A5 38
|
|
00E731 1 9D DE 03 sta $03DE,x ; $E731: 9D DE 03
|
|
00E734 1
|
|
00E734 1 18 clc ; $E734: 18
|
|
00E735 1
|
|
00E735 1 ProjectObjectCoordinates_Return: ; $E735
|
|
00E735 1 60 rts ; $E735: 60
|
|
00E736 1
|
|
00E736 1 ; ----------------------------------------------------------------------------
|
|
00E736 1 ; A normalization failure returns carry set.
|
|
00E736 1 ; ----------------------------------------------------------------------------
|
|
00E736 1
|
|
00E736 1 ProjectObjectCoordinates_Fail: ; $E736
|
|
00E736 1 38 sec ; $E736: 38
|
|
00E737 1 60 rts ; $E737: 60
|
|
00E738 1
|
|
00E738 1 ; ============================================================================
|
|
00E738 1 ; $E738-$E740
|
|
00E738 1 ; Convert an object-array offset into a display-array index.
|
|
00E738 1 ;
|
|
00E738 1 ; Entry:
|
|
00E738 1 ; X = even object-array offset
|
|
00E738 1 ;
|
|
00E738 1 ; Calculation:
|
|
00E738 1 ; X = (X / 2) + $C9 + 1
|
|
00E738 1 ;
|
|
00E738 1 ; Exit:
|
|
00E738 1 ; X = converted display-array index
|
|
00E738 1 ; Flags reflect CPX #$16
|
|
00E738 1 ;
|
|
00E738 1 ; This helper does not branch on the final comparison. Callers inspect X or
|
|
00E738 1 ; the returned flags themselves.
|
|
00E738 1 ; ============================================================================
|
|
00E738 1
|
|
00E738 1 ; ----------------------------------------------------------------------------
|
|
00E738 1 ; Contract:
|
|
00E738 1 ; Description: Implements Convert Object Offset To Display Index.
|
|
00E738 1 ; Entry: Registers: A, X; Memory: spritesortbaseindex
|
|
00E738 1 ; Returns/products: Registers/clobbers: A, X; Flags: condition flags may carry result state
|
|
00E738 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E738 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E738 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E738 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E738 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00E738 1 ; ----------------------------------------------------------------------------
|
|
00E738 1 ConvertObjectOffsetToDisplayIndex: ; $E738
|
|
00E738 1 8A txa ; $E738: 8A
|
|
00E739 1 4A lsr ; $E739: 4A
|
|
00E73A 1 ; Divide the even object offset by two.
|
|
00E73A 1
|
|
00E73A 1 65 C9 adc SpriteSortBaseIndex ; $E73A: 65 C9
|
|
00E73C 1 ; Carry from LSR is normally clear for even
|
|
00E73C 1 ; object offsets.
|
|
00E73C 1
|
|
00E73C 1 AA tax ; $E73C: AA
|
|
00E73D 1 E8 inx ; $E73D: E8
|
|
00E73E 1
|
|
00E73E 1 E0 16 cpx #$16 ; $E73E: E0 16
|
|
00E740 1 60 rts ; $E740: 60
|
|
00E741 1
|
|
00E741 1 ; ============================================================================
|
|
00E741 1 ; $E741-$E760
|
|
00E741 1 ; Initialize rendering state and copy 13 bytes from RenderingStateTable.
|
|
00E741 1 ;
|
|
00E741 1 ; Two effective entry points exist:
|
|
00E741 1 ;
|
|
00E741 1 ; $E741:
|
|
00E741 1 ; Sets ObjectScreenY to $F0 and forces carry clear before selecting the table
|
|
00E741 1 ; range beginning at index $0C.
|
|
00E741 1 ;
|
|
00E741 1 ; $E746:
|
|
00E741 1 ; Uses incoming carry to choose between two table ranges:
|
|
00E741 1 ;
|
|
00E741 1 ; C=0 -> start at table index $0C
|
|
00E741 1 ; C=1 -> start at table index $19 and set bit 1 of $DD
|
|
00E741 1 ;
|
|
00E741 1 ; The selected 13 bytes are copied in reverse order into zero-page $C7-$D3.
|
|
00E741 1 ; ============================================================================
|
|
00E741 1
|
|
00E741 1 InitializeRenderingState: ; $E741
|
|
00E741 1 A9 F0 lda #$F0 ; $E741: A9 F0
|
|
00E743 1 85 38 sta ObjectScreenY ; $E743: 85 38
|
|
00E745 1 ; Default projected/display coordinate.
|
|
00E745 1
|
|
00E745 1 18 clc ; $E745: 18
|
|
00E746 1
|
|
00E746 1 ; ----------------------------------------------------------------------------
|
|
00E746 1 ; Alternate entry that preserves caller-supplied carry.
|
|
00E746 1 ; ----------------------------------------------------------------------------
|
|
00E746 1
|
|
00E746 1 ; ----------------------------------------------------------------------------
|
|
00E746 1 ; Contract:
|
|
00E746 1 ; Description: Initializes Rendering State From Carry.
|
|
00E746 1 ; Entry: Registers: A, X, Y; Memory: ppuctrlshadow, renderingstatetable
|
|
00E746 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E746 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E746 1 ; Memory effects: ppuctrlshadow, $c7
|
|
00E746 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E746 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E746 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E746 1 ; ----------------------------------------------------------------------------
|
|
00E746 1 InitializeRenderingStateFromCarry: ; $E746
|
|
00E746 1 A5 DD lda PpuCtrlShadow ; $E746: A5 DD
|
|
00E748 1 29 FD and #$FD ; $E748: 29 FD
|
|
00E74A 1 ; Clear bit 1 by default.
|
|
00E74A 1
|
|
00E74A 1 A0 0C ldy #$0C ; $E74A: A0 0C
|
|
00E74C 1 ; Default table range ends at index $0C.
|
|
00E74C 1
|
|
00E74C 1 90 04 bcc InitializeRenderingState_SaveFlags
|
|
00E74E 1 ; $E74C: 90 04
|
|
00E74E 1
|
|
00E74E 1 ; ----------------------------------------------------------------------------
|
|
00E74E 1 ; Carry-set path.
|
|
00E74E 1 ;
|
|
00E74E 1 ; Select the second 13-byte range and set bit 1 of $DD.
|
|
00E74E 1 ; ----------------------------------------------------------------------------
|
|
00E74E 1
|
|
00E74E 1 A0 19 ldy #$19 ; $E74E: A0 19
|
|
00E750 1 09 02 ora #$02 ; $E750: 09 02
|
|
00E752 1
|
|
00E752 1 InitializeRenderingState_SaveFlags: ; $E752
|
|
00E752 1 85 DD sta PpuCtrlShadow ; $E752: 85 DD
|
|
00E754 1
|
|
00E754 1 ; ----------------------------------------------------------------------------
|
|
00E754 1 ; Copy 13 bytes in reverse order.
|
|
00E754 1 ;
|
|
00E754 1 ; Source indices:
|
|
00E754 1 ;
|
|
00E754 1 ; C clear: $0C down to $00
|
|
00E754 1 ; C set: $19 down to $0D
|
|
00E754 1 ;
|
|
00E754 1 ; Destination:
|
|
00E754 1 ;
|
|
00E754 1 ; $D3 down to $C7
|
|
00E754 1 ; ----------------------------------------------------------------------------
|
|
00E754 1
|
|
00E754 1 A2 0C ldx #$0C ; $E754: A2 0C
|
|
00E756 1
|
|
00E756 1 InitializeRenderingState_CopyLoop: ; $E756
|
|
00E756 1 B9 61 E7 lda RenderingStateTable,y ; $E756: B9 61 E7
|
|
00E759 1 95 C7 sta ObjectListFlag,x ; $E759: 95 C7
|
|
00E75B 1
|
|
00E75B 1 88 dey ; $E75B: 88
|
|
00E75C 1 CA dex ; $E75C: CA
|
|
00E75D 1 10 F7 bpl InitializeRenderingState_CopyLoop
|
|
00E75F 1 ; $E75D: 10 F7
|
|
00E75F 1
|
|
00E75F 1 ; ----------------------------------------------------------------------------
|
|
00E75F 1 ; Return carry set.
|
|
00E75F 1 ; ----------------------------------------------------------------------------
|
|
00E75F 1
|
|
00E75F 1 38 sec ; $E75F: 38
|
|
00E760 1 60 rts ; $E760: 60
|
|
00E761 1
|
|
00E761 1 ; ============================================================================
|
|
00E761 1 ; $E761-$E77A
|
|
00E761 1 ; Rendering-state lookup data.
|
|
00E761 1 ;
|
|
00E761 1 ; The initialization routine copies one of two 13-byte ranges:
|
|
00E761 1 ;
|
|
00E761 1 ; Range 0:
|
|
00E761 1 ; indices $00-$0C
|
|
00E761 1 ;
|
|
00E761 1 ; Range 1:
|
|
00E761 1 ; indices $0D-$19
|
|
00E761 1 ;
|
|
00E761 1 ; Both ranges are copied backward into zero-page $C7-$D3.
|
|
00E761 1 ; ============================================================================
|
|
00E761 1
|
|
00E761 1 RenderingStateTable: ; $E761
|
|
00E761 1
|
|
00E761 1 ; First 13-byte state.
|
|
00E761 1 RenderingStateTable_Default: ; $E761, indices $00-$0C
|
|
00E761 1 00 15 00 14 .byte $00,$15,$00,$14,$00,$14,$2D
|
|
00E765 1 00 14 2D
|
|
00E768 1 58 3D 92 D2 .byte $58,$3D,$92,$D2,$FB,$F4
|
|
00E76C 1 FB F4
|
|
00E76E 1
|
|
00E76E 1 ; Second 13-byte state.
|
|
00E76E 1 RenderingStateTable_Alternate: ; $E76E, indices $0D-$19
|
|
00E76E 1 08 0D 15 21 .byte $08,$0D,$15,$21,$06,$42,$16
|
|
00E772 1 06 42 16
|
|
00E775 1 98 F7 DA 86 .byte $98,$F7,$DA,$86,$6F,$02
|
|
00E779 1 6F 02
|
|
00E77B 1
|
|
00E77B 1 ; ============================================================================
|
|
00E77B 1 ; $E77B-$E7BB
|
|
00E77B 1 ; Expand a sprite-record list into the OAM shadow buffer at $0200.
|
|
00E77B 1 ;
|
|
00E77B 1 ; Entry:
|
|
00E77B 1 ; A = index into the pointer table at $0400
|
|
00E77B 1 ;
|
|
00E77B 1 ; Pointer table:
|
|
00E77B 1 ; $0400/$0401 contains little-endian source pointers.
|
|
00E77B 1 ; A is doubled before indexing the pointer table.
|
|
00E77B 1 ;
|
|
00E77B 1 ; Source record format:
|
|
00E77B 1 ;
|
|
00E77B 1 ; byte 0:
|
|
00E77B 1 ; number of four-byte sprite records
|
|
00E77B 1 ;
|
|
00E77B 1 ; each sprite record:
|
|
00E77B 1 ; byte 0 = relative Y coordinate
|
|
00E77B 1 ; byte 1 = tile index
|
|
00E77B 1 ; byte 2 = sprite attributes
|
|
00E77B 1 ; byte 3 = relative X coordinate
|
|
00E77B 1 ;
|
|
00E77B 1 ; Destination:
|
|
00E77B 1 ; OAM shadow buffer at $0200
|
|
00E77B 1 ;
|
|
00E77B 1 ; Coordinate adjustments:
|
|
00E77B 1 ; destination Y = source Y + $38
|
|
00E77B 1 ; destination X = source X + $36
|
|
00E77B 1 ;
|
|
00E77B 1 ; Exit:
|
|
00E77B 1 ; $3F = updated OAM shadow write offset
|
|
00E77B 1 ; $20 incremented after a nonempty sprite list
|
|
00E77B 1 ; ============================================================================
|
|
00E77B 1
|
|
00E77B 1 ; ----------------------------------------------------------------------------
|
|
00E77B 1 ; Contract:
|
|
00E77B 1 ; Description: Implements Render Sprite Record List.
|
|
00E77B 1 ; Entry: Registers: A, X, Y; Memory: $0400, $0401, (indirectptrlo), oamwriteoffset, objectscreeny
|
|
00E77B 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E77B 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E77B 1 ; Memory effects: indirectptrlo, indirectptrhi, $04, $0200, oamwriteoffset
|
|
00E77B 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E77B 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E77B 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E77B 1 ; ----------------------------------------------------------------------------
|
|
00E77B 1 RenderSpriteRecordList: ; $E77B
|
|
00E77B 1 0A asl ; $E77B: 0A
|
|
00E77C 1 ; Convert pointer index to byte offset.
|
|
00E77C 1
|
|
00E77C 1 A8 tay ; $E77C: A8
|
|
00E77D 1
|
|
00E77D 1 ; ----------------------------------------------------------------------------
|
|
00E77D 1 ; Load the selected little-endian source pointer from $0400.
|
|
00E77D 1 ; ----------------------------------------------------------------------------
|
|
00E77D 1
|
|
00E77D 1 B9 00 04 lda $0400,y ; $E77D: B9 00 04
|
|
00E780 1 85 00 sta IndirectPtrLo ; $E780: 85 00
|
|
00E782 1
|
|
00E782 1 B9 01 04 lda $0401,y ; $E782: B9 01 04
|
|
00E785 1 85 01 sta IndirectPtrHi ; $E785: 85 01
|
|
00E787 1
|
|
00E787 1 ; ----------------------------------------------------------------------------
|
|
00E787 1 ; Read the sprite count.
|
|
00E787 1 ; ----------------------------------------------------------------------------
|
|
00E787 1
|
|
00E787 1 A0 00 ldy #$00 ; $E787: A0 00
|
|
00E789 1
|
|
00E789 1 B1 00 lda (IndirectPtrLo),y ; $E789: B1 00
|
|
00E78B 1 F0 2E beq RenderSpriteRecordList_Return
|
|
00E78D 1 ; $E78B: F0 2E
|
|
00E78D 1
|
|
00E78D 1 85 04 sta $04 ; $E78D: 85 04
|
|
00E78F 1 ; Number of four-byte sprite records.
|
|
00E78F 1
|
|
00E78F 1 ; ----------------------------------------------------------------------------
|
|
00E78F 1 ; Load the current OAM shadow write position.
|
|
00E78F 1 ; ----------------------------------------------------------------------------
|
|
00E78F 1
|
|
00E78F 1 A6 3F ldx OamWriteOffset ; $E78F: A6 3F
|
|
00E791 1
|
|
00E791 1 ; ----------------------------------------------------------------------------
|
|
00E791 1 ; Copy one sprite record.
|
|
00E791 1 ; ----------------------------------------------------------------------------
|
|
00E791 1
|
|
00E791 1 RenderSpriteRecordList_Loop: ; $E791
|
|
00E791 1 C8 iny ; $E791: C8
|
|
00E792 1
|
|
00E792 1 ; ----------------------------------------------------------------------------
|
|
00E792 1 ; OAM byte 0: Y coordinate.
|
|
00E792 1 ; ----------------------------------------------------------------------------
|
|
00E792 1
|
|
00E792 1 18 clc ; $E792: 18
|
|
00E793 1
|
|
00E793 1 B1 00 lda (IndirectPtrLo),y ; $E793: B1 00
|
|
00E795 1 65 38 adc ObjectScreenY ; $E795: 65 38
|
|
00E797 1 9D 00 02 sta $0200,x ; $E797: 9D 00 02
|
|
00E79A 1
|
|
00E79A 1 E8 inx ; $E79A: E8
|
|
00E79B 1 C8 iny ; $E79B: C8
|
|
00E79C 1
|
|
00E79C 1 ; ----------------------------------------------------------------------------
|
|
00E79C 1 ; OAM byte 1: tile index.
|
|
00E79C 1 ; ----------------------------------------------------------------------------
|
|
00E79C 1
|
|
00E79C 1 B1 00 lda (IndirectPtrLo),y ; $E79C: B1 00
|
|
00E79E 1 9D 00 02 sta $0200,x ; $E79E: 9D 00 02
|
|
00E7A1 1
|
|
00E7A1 1 E8 inx ; $E7A1: E8
|
|
00E7A2 1 C8 iny ; $E7A2: C8
|
|
00E7A3 1
|
|
00E7A3 1 ; ----------------------------------------------------------------------------
|
|
00E7A3 1 ; OAM byte 2: sprite attributes.
|
|
00E7A3 1 ; ----------------------------------------------------------------------------
|
|
00E7A3 1
|
|
00E7A3 1 B1 00 lda (IndirectPtrLo),y ; $E7A3: B1 00
|
|
00E7A5 1 9D 00 02 sta $0200,x ; $E7A5: 9D 00 02
|
|
00E7A8 1
|
|
00E7A8 1 E8 inx ; $E7A8: E8
|
|
00E7A9 1 C8 iny ; $E7A9: C8
|
|
00E7AA 1
|
|
00E7AA 1 ; ----------------------------------------------------------------------------
|
|
00E7AA 1 ; OAM byte 3: X coordinate.
|
|
00E7AA 1 ; ----------------------------------------------------------------------------
|
|
00E7AA 1
|
|
00E7AA 1 18 clc ; $E7AA: 18
|
|
00E7AB 1
|
|
00E7AB 1 B1 00 lda (IndirectPtrLo),y ; $E7AB: B1 00
|
|
00E7AD 1 65 36 adc ObjectScreenX ; $E7AD: 65 36
|
|
00E7AF 1 9D 00 02 sta $0200,x ; $E7AF: 9D 00 02
|
|
00E7B2 1
|
|
00E7B2 1 E8 inx ; $E7B2: E8
|
|
00E7B3 1
|
|
00E7B3 1 ; ----------------------------------------------------------------------------
|
|
00E7B3 1 ; Continue until all sprite records are copied.
|
|
00E7B3 1 ; ----------------------------------------------------------------------------
|
|
00E7B3 1
|
|
00E7B3 1 C6 04 dec $04 ; $E7B3: C6 04
|
|
00E7B5 1 D0 DA bne RenderSpriteRecordList_Loop
|
|
00E7B7 1 ; $E7B5: D0 DA
|
|
00E7B7 1
|
|
00E7B7 1 ; ----------------------------------------------------------------------------
|
|
00E7B7 1 ; Save the updated OAM write offset and mark that another sprite group was
|
|
00E7B7 1 ; emitted.
|
|
00E7B7 1 ; ----------------------------------------------------------------------------
|
|
00E7B7 1
|
|
00E7B7 1 86 3F stx OamWriteOffset ; $E7B7: 86 3F
|
|
00E7B9 1 E6 20 inc FrameState20 ; $E7B9: E6 20
|
|
00E7BB 1
|
|
00E7BB 1 RenderSpriteRecordList_Return: ; $E7BB
|
|
00E7BB 1 60 rts
|
|
00E7BC 1 ; ============================================================================
|
|
00E7BC 1 ; $E7BC-$E7CA
|
|
00E7BC 1 ; Hide a caller-selected number of sprites in the OAM shadow buffer.
|
|
00E7BC 1 ;
|
|
00E7BC 1 ; Entry:
|
|
00E7BC 1 ; Y = number of sprites to hide
|
|
00E7BC 1 ;
|
|
00E7BC 1 ; Operation:
|
|
00E7BC 1 ; Each OAM entry occupies four bytes:
|
|
00E7BC 1 ;
|
|
00E7BC 1 ; byte 0 = Y coordinate
|
|
00E7BC 1 ; byte 1 = tile
|
|
00E7BC 1 ; byte 2 = attributes
|
|
00E7BC 1 ; byte 3 = X coordinate
|
|
00E7BC 1 ;
|
|
00E7BC 1 ; This routine writes $F0 to each sprite's Y coordinate, placing it below
|
|
00E7BC 1 ; the visible screen, then advances X by four bytes to the next sprite.
|
|
00E7BC 1 ;
|
|
00E7BC 1 ; Note:
|
|
00E7BC 1 ; The OAM write offset in $3F is read but not updated.
|
|
00E7BC 1 ; ============================================================================
|
|
00E7BC 1
|
|
00E7BC 1 HideOamSprites: ; $E7BC
|
|
00E7BC 1 A6 3F ldx OamWriteOffset ; $E7BC: A6 3F
|
|
00E7BE 1 ; Start at the current OAM shadow offset.
|
|
00E7BE 1
|
|
00E7BE 1 A9 F0 lda #$F0 ; $E7BE: A9 F0
|
|
00E7C0 1 ; Off-screen Y coordinate.
|
|
00E7C0 1
|
|
00E7C0 1 HideOamSprites_Loop: ; $E7C0
|
|
00E7C0 1 9D 00 02 sta $0200,x ; $E7C0: 9D 00 02
|
|
00E7C3 1 ; Hide the current sprite.
|
|
00E7C3 1
|
|
00E7C3 1 E8 inx ; $E7C3: E8
|
|
00E7C4 1 E8 inx ; $E7C4: E8
|
|
00E7C5 1 E8 inx ; $E7C5: E8
|
|
00E7C6 1 E8 inx ; $E7C6: E8
|
|
00E7C7 1 ; Advance to the next sprite's Y byte.
|
|
00E7C7 1
|
|
00E7C7 1 88 dey ; $E7C7: 88
|
|
00E7C8 1 D0 F6 bne HideOamSprites_Loop ; $E7C8: D0 F6
|
|
00E7CA 1
|
|
00E7CA 1 60 rts ; $E7CA: 60
|
|
00E7CB 1
|
|
00E7CB 1 ; ============================================================================
|
|
00E7CB 1 ; $E7CB-$E7DA
|
|
00E7CB 1 ; Convert a signed 16-bit value in A:Y to its absolute magnitude.
|
|
00E7CB 1 ;
|
|
00E7CB 1 ; Entry:
|
|
00E7CB 1 ; A = signed high byte
|
|
00E7CB 1 ; Y = low byte
|
|
00E7CB 1 ;
|
|
00E7CB 1 ; Exit:
|
|
00E7CB 1 ; A:Y = absolute magnitude
|
|
00E7CB 1 ;
|
|
00E7CB 1 ; If A is nonnegative, the value is returned unchanged. Otherwise, the
|
|
00E7CB 1 ; complete 16-bit pair is negated using one's complement plus one.
|
|
00E7CB 1 ; ============================================================================
|
|
00E7CB 1
|
|
00E7CB 1 ; ----------------------------------------------------------------------------
|
|
00E7CB 1 ; Contract:
|
|
00E7CB 1 ; Description: Implements Absolute Value A Y.
|
|
00E7CB 1 ; Entry: Registers: A, Y
|
|
00E7CB 1 ; Returns/products: Registers/clobbers: A, Y; Flags: condition flags may carry result state
|
|
00E7CB 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E7CB 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E7CB 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E7CB 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E7CB 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 6.
|
|
00E7CB 1 ; ----------------------------------------------------------------------------
|
|
00E7CB 1 AbsoluteValueAY: ; $E7CB
|
|
00E7CB 1 10 0D bpl AbsoluteValueAY_Return ; $E7CB: 10 0D
|
|
00E7CD 1
|
|
00E7CD 1 ; ----------------------------------------------------------------------------
|
|
00E7CD 1 ; Negate the high byte and preserve it while processing the low byte.
|
|
00E7CD 1 ; ----------------------------------------------------------------------------
|
|
00E7CD 1
|
|
00E7CD 1 49 FF eor #$FF ; $E7CD: 49 FF
|
|
00E7CF 1 48 pha ; $E7CF: 48
|
|
00E7D0 1
|
|
00E7D0 1 ; ----------------------------------------------------------------------------
|
|
00E7D0 1 ; Negate the low byte.
|
|
00E7D0 1 ;
|
|
00E7D0 1 ; SEC followed by ADC #$00 adds one to the complemented byte.
|
|
00E7D0 1 ; ----------------------------------------------------------------------------
|
|
00E7D0 1
|
|
00E7D0 1 98 tya ; $E7D0: 98
|
|
00E7D1 1 49 FF eor #$FF ; $E7D1: 49 FF
|
|
00E7D3 1
|
|
00E7D3 1 38 sec ; $E7D3: 38
|
|
00E7D4 1 69 00 adc #$00 ; $E7D4: 69 00
|
|
00E7D6 1 A8 tay ; $E7D6: A8
|
|
00E7D7 1
|
|
00E7D7 1 ; ----------------------------------------------------------------------------
|
|
00E7D7 1 ; Restore the complemented high byte and propagate carry from the low-byte
|
|
00E7D7 1 ; negation.
|
|
00E7D7 1 ; ----------------------------------------------------------------------------
|
|
00E7D7 1
|
|
00E7D7 1 68 pla ; $E7D7: 68
|
|
00E7D8 1 69 00 adc #$00 ; $E7D8: 69 00
|
|
00E7DA 1
|
|
00E7DA 1 AbsoluteValueAY_Return: ; $E7DA
|
|
00E7DA 1 60 rts ; $E7DA: 60
|
|
00E7DB 1
|
|
00E7DB 1 ; ============================================================================
|
|
00E7DB 1 ; $E7DB-$E7F4
|
|
00E7DB 1 ; Calculate an eight-bit scaled product.
|
|
00E7DB 1 ;
|
|
00E7DB 1 ; Entry:
|
|
00E7DB 1 ; A = multiplicand/value
|
|
00E7DB 1 ; X = scale or shift count plus one
|
|
00E7DB 1 ;
|
|
00E7DB 1 ; Operation:
|
|
00E7DB 1 ; X is decremented once and saved in $2B. The routine then performs eight
|
|
00E7DB 1 ; shift-and-add rounds using $28 as the high/result byte.
|
|
00E7DB 1 ;
|
|
00E7DB 1 ; Exit:
|
|
00E7DB 1 ; A = result low byte
|
|
00E7DB 1 ; X = result high byte from $28
|
|
00E7DB 1 ; ============================================================================
|
|
00E7DB 1
|
|
00E7DB 1 ; ----------------------------------------------------------------------------
|
|
00E7DB 1 ; Contract:
|
|
00E7DB 1 ; Description: Calculates Scaled Product.
|
|
00E7DB 1 ; Entry: Registers: A, X; Memory: $2b, $28
|
|
00E7DB 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E7DB 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E7DB 1 ; Memory effects: $2b, $28
|
|
00E7DB 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E7DB 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E7DB 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E7DB 1 ; ----------------------------------------------------------------------------
|
|
00E7DB 1 CalculateScaledProduct: ; $E7DB
|
|
00E7DB 1 CA dex ; $E7DB: CA
|
|
00E7DC 1 86 2B stx $2B ; $E7DC: 86 2B
|
|
00E7DE 1
|
|
00E7DE 1 85 28 sta $28 ; $E7DE: 85 28
|
|
00E7E0 1
|
|
00E7E0 1 A9 00 lda #$00 ; $E7E0: A9 00
|
|
00E7E2 1 A2 08 ldx #$08 ; $E7E2: A2 08
|
|
00E7E4 1
|
|
00E7E4 1 ; ----------------------------------------------------------------------------
|
|
00E7E4 1 ; Shift the 16-bit A:$28 result left.
|
|
00E7E4 1 ;
|
|
00E7E4 1 ; Whenever carry is set after rotating $28, add the saved scale value from
|
|
00E7E4 1 ; $2B. Carry from that addition increments $28.
|
|
00E7E4 1 ; ----------------------------------------------------------------------------
|
|
00E7E4 1
|
|
00E7E4 1 CalculateScaledProduct_Loop: ; $E7E4
|
|
00E7E4 1 0A asl ; $E7E4: 0A
|
|
00E7E5 1 26 28 rol $28 ; $E7E5: 26 28
|
|
00E7E7 1
|
|
00E7E7 1 90 06 bcc CalculateScaledProduct_Next
|
|
00E7E9 1 ; $E7E7: 90 06
|
|
00E7E9 1
|
|
00E7E9 1 65 2B adc $2B ; $E7E9: 65 2B
|
|
00E7EB 1 90 02 bcc CalculateScaledProduct_Next
|
|
00E7ED 1 ; $E7EB: 90 02
|
|
00E7ED 1
|
|
00E7ED 1 E6 28 inc $28 ; $E7ED: E6 28
|
|
00E7EF 1
|
|
00E7EF 1 CalculateScaledProduct_Next: ; $E7EF
|
|
00E7EF 1 CA dex ; $E7EF: CA
|
|
00E7F0 1 D0 F2 bne CalculateScaledProduct_Loop
|
|
00E7F2 1 ; $E7F0: D0 F2
|
|
00E7F2 1
|
|
00E7F2 1 A6 28 ldx $28 ; $E7F2: A6 28
|
|
00E7F4 1 60 rts ; $E7F4: 60
|
|
00E7F5 1
|
|
00E7F5 1 ; ============================================================================
|
|
00E7F5 1 ; $E7F5-$E80A
|
|
00E7F5 1 ; Perform a nine-round restoring division.
|
|
00E7F5 1 ;
|
|
00E7F5 1 ; Entry:
|
|
00E7F5 1 ; A = dividend
|
|
00E7F5 1 ; Y = divisor
|
|
00E7F5 1 ; X = initial high or remainder byte
|
|
00E7F5 1 ;
|
|
00E7F5 1 ; Working storage:
|
|
00E7F5 1 ; $28 = quotient/result shift register
|
|
00E7F5 1 ; $2B = divisor
|
|
00E7F5 1 ;
|
|
00E7F5 1 ; Exit:
|
|
00E7F5 1 ; A = quotient/result byte from $28
|
|
00E7F5 1 ;
|
|
00E7F5 1 ; Each round conditionally subtracts the divisor, then rotates the result bit
|
|
00E7F5 1 ; into $28.
|
|
00E7F5 1 ; ============================================================================
|
|
00E7F5 1
|
|
00E7F5 1 ; ----------------------------------------------------------------------------
|
|
00E7F5 1 ; Contract:
|
|
00E7F5 1 ; Description: Implements Divide Unsigned Byte.
|
|
00E7F5 1 ; Entry: Registers: A, X, Y; Memory: $2b, $28
|
|
00E7F5 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E7F5 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E7F5 1 ; Memory effects: $28, $2b
|
|
00E7F5 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E7F5 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E7F5 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E7F5 1 ; ----------------------------------------------------------------------------
|
|
00E7F5 1 DivideUnsignedByte: ; $E7F5
|
|
00E7F5 1 85 28 sta $28 ; $E7F5: 85 28
|
|
00E7F7 1 84 2B sty $2B ; $E7F7: 84 2B
|
|
00E7F9 1
|
|
00E7F9 1 8A txa ; $E7F9: 8A
|
|
00E7FA 1
|
|
00E7FA 1 A2 09 ldx #$09 ; $E7FA: A2 09
|
|
00E7FC 1
|
|
00E7FC 1 DivideUnsignedByte_Loop: ; $E7FC
|
|
00E7FC 1 C5 2B cmp $2B ; $E7FC: C5 2B
|
|
00E7FE 1 90 02 bcc DivideUnsignedByte_Shift
|
|
00E800 1 ; $E7FE: 90 02
|
|
00E800 1
|
|
00E800 1 E5 2B sbc $2B ; $E800: E5 2B
|
|
00E802 1
|
|
00E802 1 DivideUnsignedByte_Shift: ; $E802
|
|
00E802 1 26 28 rol $28 ; $E802: 26 28
|
|
00E804 1 2A rol ; $E804: 2A
|
|
00E805 1
|
|
00E805 1 CA dex ; $E805: CA
|
|
00E806 1 D0 F4 bne DivideUnsignedByte_Loop ; $E806: D0 F4
|
|
00E808 1
|
|
00E808 1 A5 28 lda $28 ; $E808: A5 28
|
|
00E80A 1 60 rts ; $E80A: 60
|
|
00E80B 1
|
|
00E80B 1 ; ============================================================================
|
|
00E80B 1 ; $E80B-$E821
|
|
00E80B 1 ; Initialize an eight-round vector or magnitude calculation.
|
|
00E80B 1 ;
|
|
00E80B 1 ; Entry:
|
|
00E80B 1 ; X = signed horizontal input
|
|
00E80B 1 ; Y = vertical input
|
|
00E80B 1 ;
|
|
00E80B 1 ; Working state:
|
|
00E80B 1 ; $D4 = absolute or complemented horizontal input
|
|
00E80B 1 ; $D5 = vertical input
|
|
00E80B 1 ; $DB = round/shift state, initialized to $FF and then incremented to zero
|
|
00E80B 1 ;
|
|
00E80B 1 ; Exit:
|
|
00E80B 1 ; Result is returned by the state accumulated through $E8DA.
|
|
00E80B 1 ;
|
|
00E80B 1 ; The precise mathematical operation depends on the helper at $E8DA, but this
|
|
00E80B 1 ; routine clearly normalizes the sign of X and performs eight identical rounds.
|
|
00E80B 1 ; ============================================================================
|
|
00E80B 1
|
|
00E80B 1 ; ----------------------------------------------------------------------------
|
|
00E80B 1 ; Contract:
|
|
00E80B 1 ; Description: Calculates Vector Magnitude.
|
|
00E80B 1 ; Entry: Registers: A, X, Y
|
|
00E80B 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E80B 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E80B 1 ; Memory effects: $d4, $d5, $db
|
|
00E80B 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E80B 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E80B 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E80B 1 ; ----------------------------------------------------------------------------
|
|
00E80B 1 CalculateVectorMagnitude: ; $E80B
|
|
00E80B 1 8A txa ; $E80B: 8A
|
|
00E80C 1 10 02 bpl CalculateVectorMagnitude_SaveX
|
|
00E80E 1 ; $E80C: 10 02
|
|
00E80E 1
|
|
00E80E 1 ; ----------------------------------------------------------------------------
|
|
00E80E 1 ; Convert a negative X input using one's complement.
|
|
00E80E 1 ;
|
|
00E80E 1 ; Unlike a full absolute-value conversion, this does not add one here. The
|
|
00E80E 1 ; lower-level iterative helper accounts for the representation.
|
|
00E80E 1 ; ----------------------------------------------------------------------------
|
|
00E80E 1
|
|
00E80E 1 49 FF eor #$FF ; $E80E: 49 FF
|
|
00E810 1
|
|
00E810 1 CalculateVectorMagnitude_SaveX: ; $E810
|
|
00E810 1 85 D4 sta $D4 ; $E810: 85 D4
|
|
00E812 1 84 D5 sty $D5 ; $E812: 84 D5
|
|
00E814 1
|
|
00E814 1 ; ----------------------------------------------------------------------------
|
|
00E814 1 ; Initialize the round state.
|
|
00E814 1 ;
|
|
00E814 1 ; X is first set to $FF and stored in $DB, then incremented to zero before the
|
|
00E814 1 ; eight processing rounds begin.
|
|
00E814 1 ; ----------------------------------------------------------------------------
|
|
00E814 1
|
|
00E814 1 A2 FF ldx #$FF ; $E814: A2 FF
|
|
00E816 1 86 DB stx $DB ; $E816: 86 DB
|
|
00E818 1
|
|
00E818 1 E8 inx ; $E818: E8
|
|
00E819 1 ; X = $00.
|
|
00E819 1
|
|
00E819 1 A0 08 ldy #$08 ; $E819: A0 08
|
|
00E81B 1
|
|
00E81B 1 CalculateVectorMagnitude_Loop: ; $E81B
|
|
00E81B 1 20 DA E8 jsr UpdatePrimaryArithmeticPair ; $E81B: 20 DA E8
|
|
00E81E 1
|
|
00E81E 1 88 dey ; $E81E: 88
|
|
00E81F 1 D0 FA bne CalculateVectorMagnitude_Loop
|
|
00E821 1 ; $E81F: D0 FA
|
|
00E821 1
|
|
00E821 1 60 rts ; $E821: 60
|
|
00E822 1
|
|
00E822 1 ; ============================================================================
|
|
00E822 1 ; $E822-$E854
|
|
00E822 1 ; Initialize and run a signed two-component vector calculation.
|
|
00E822 1 ;
|
|
00E822 1 ; Entry:
|
|
00E822 1 ; A = first result or vector component
|
|
00E822 1 ; X = signed horizontal component
|
|
00E822 1 ; Y = vertical component
|
|
00E822 1 ;
|
|
00E822 1 ; Working state:
|
|
00E822 1 ; $D4/$D5 = normalized signed source pair
|
|
00E822 1 ; $D6/$D7 = result or secondary pair
|
|
00E822 1 ; $D9 = sign-extension byte, $00 or $FF
|
|
00E822 1 ; $DB = round/shift state
|
|
00E822 1 ;
|
|
00E822 1 ; Exit:
|
|
00E822 1 ; A = $D9 XOR $D6
|
|
00E822 1 ; Y = $D9 XOR $D7
|
|
00E822 1 ;
|
|
00E822 1 ; The routine performs eight rounds using both $E8DA and $E908, then applies
|
|
00E822 1 ; the original sign extension to the result pair.
|
|
00E822 1 ; ============================================================================
|
|
00E822 1
|
|
00E822 1 CalculateSignedVector: ; $E822
|
|
00E822 1 85 D6 sta $D6 ; $E822: 85 D6
|
|
00E824 1
|
|
00E824 1 A9 00 lda #$00 ; $E824: A9 00
|
|
00E826 1 85 D7 sta $D7 ; $E826: 85 D7
|
|
00E828 1
|
|
00E828 1 ; ----------------------------------------------------------------------------
|
|
00E828 1 ; Alternate entry used by callers that have already initialized $D6/$D7.
|
|
00E828 1 ;
|
|
00E828 1 ; Entry:
|
|
00E828 1 ; X = signed horizontal component
|
|
00E828 1 ; Y = vertical component
|
|
00E828 1 ; ----------------------------------------------------------------------------
|
|
00E828 1
|
|
00E828 1 CalculateSignedVectorFromResult: ; $E828
|
|
00E828 1 84 D5 sty $D5 ; $E828: 84 D5
|
|
00E82A 1
|
|
00E82A 1 A0 00 ldy #$00 ; $E82A: A0 00
|
|
00E82C 1 ; Default sign-extension byte.
|
|
00E82C 1
|
|
00E82C 1 8A txa ; $E82C: 8A
|
|
00E82D 1 10 03 bpl CalculateSignedVector_SaveSign
|
|
00E82F 1 ; $E82D: 10 03
|
|
00E82F 1
|
|
00E82F 1 ; ----------------------------------------------------------------------------
|
|
00E82F 1 ; Normalize a negative X component using one's complement and set the sign
|
|
00E82F 1 ; extension byte to $FF.
|
|
00E82F 1 ; ----------------------------------------------------------------------------
|
|
00E82F 1
|
|
00E82F 1 49 FF eor #$FF ; $E82F: 49 FF
|
|
00E831 1 88 dey ; $E831: 88
|
|
00E832 1 ; Y = $FF.
|
|
00E832 1
|
|
00E832 1 CalculateSignedVector_SaveSign: ; $E832
|
|
00E832 1 84 D9 sty $D9 ; $E832: 84 D9
|
|
00E834 1 85 D4 sta $D4 ; $E834: 85 D4
|
|
00E836 1
|
|
00E836 1 ; ----------------------------------------------------------------------------
|
|
00E836 1 ; Apply the sign extension to the vertical source component.
|
|
00E836 1 ; ----------------------------------------------------------------------------
|
|
00E836 1
|
|
00E836 1 98 tya ; $E836: 98
|
|
00E837 1 45 D5 eor $D5 ; $E837: 45 D5
|
|
00E839 1 85 D5 sta $D5 ; $E839: 85 D5
|
|
00E83B 1
|
|
00E83B 1 ; ----------------------------------------------------------------------------
|
|
00E83B 1 ; Initialize the round state.
|
|
00E83B 1 ; ----------------------------------------------------------------------------
|
|
00E83B 1
|
|
00E83B 1 A2 FF ldx #$FF ; $E83B: A2 FF
|
|
00E83D 1 86 DB stx $DB ; $E83D: 86 DB
|
|
00E83F 1
|
|
00E83F 1 E8 inx ; $E83F: E8
|
|
00E840 1 ; X = $00.
|
|
00E840 1
|
|
00E840 1 A0 08 ldy #$08 ; $E840: A0 08
|
|
00E842 1
|
|
00E842 1 ; ----------------------------------------------------------------------------
|
|
00E842 1 ; Run eight rounds. Each round performs the common step at $E8DA followed by
|
|
00E842 1 ; the signed-result accumulation step at $E908.
|
|
00E842 1 ; ----------------------------------------------------------------------------
|
|
00E842 1
|
|
00E842 1 CalculateSignedVector_Loop: ; $E842
|
|
00E842 1 20 DA E8 jsr UpdatePrimaryArithmeticPair ; $E842: 20 DA E8
|
|
00E845 1 20 08 E9 jsr UpdateSecondaryArithmeticPair ; $E845: 20 08 E9
|
|
00E848 1
|
|
00E848 1 88 dey ; $E848: 88
|
|
00E849 1 D0 F7 bne CalculateSignedVector_Loop
|
|
00E84B 1 ; $E849: D0 F7
|
|
00E84B 1
|
|
00E84B 1 ; ----------------------------------------------------------------------------
|
|
00E84B 1 ; Apply the original sign extension to the resulting pair.
|
|
00E84B 1 ; ----------------------------------------------------------------------------
|
|
00E84B 1
|
|
00E84B 1 A5 D9 lda $D9 ; $E84B: A5 D9
|
|
00E84D 1 45 D7 eor $D7 ; $E84D: 45 D7
|
|
00E84F 1 A8 tay ; $E84F: A8
|
|
00E850 1
|
|
00E850 1 A5 D9 lda $D9 ; $E850: A5 D9
|
|
00E852 1 45 D6 eor $D6 ; $E852: 45 D6
|
|
00E854 1
|
|
00E854 1 60 rts ; $E854: 60
|
|
00E855 1
|
|
00E855 1 ; ============================================================================
|
|
00E855 1 ; $E855-$E876
|
|
00E855 1 ; Run an eight-round signed vector calculation using a caller-supplied result
|
|
00E855 1 ; pair in X:Y.
|
|
00E855 1 ;
|
|
00E855 1 ; Entry:
|
|
00E855 1 ; A = signed/control input, transformed by XOR #$80
|
|
00E855 1 ; X = first result component
|
|
00E855 1 ; Y = second result component
|
|
00E855 1 ;
|
|
00E855 1 ; Working state:
|
|
00E855 1 ; $D8 = transformed input shift register
|
|
00E855 1 ; $D6 = saved X component
|
|
00E855 1 ; $D7 = saved Y component
|
|
00E855 1 ; $DA = per-round sign or mask byte
|
|
00E855 1 ; $DB = round index, progressing from $00 through $07
|
|
00E855 1 ;
|
|
00E855 1 ; Exit:
|
|
00E855 1 ; A = value left by the final $E908 call
|
|
00E855 1 ; Y = original input Y component
|
|
00E855 1 ; ============================================================================
|
|
00E855 1
|
|
00E855 1 ; ----------------------------------------------------------------------------
|
|
00E855 1 ; Contract:
|
|
00E855 1 ; Description: Calculates Vector From Rotated Mask.
|
|
00E855 1 ; Entry: Registers: A, X, Y; Memory: $d7
|
|
00E855 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E855 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E855 1 ; Memory effects: $d8, $d6, $d7, $db, $da
|
|
00E855 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E855 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E855 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00E855 1 ; ----------------------------------------------------------------------------
|
|
00E855 1 CalculateVectorFromRotatedMask: ; $E855
|
|
00E855 1 49 80 eor #$80 ; $E855: 49 80
|
|
00E857 1 85 D8 sta $D8 ; $E857: 85 D8
|
|
00E859 1
|
|
00E859 1 86 D6 stx $D6 ; $E859: 86 D6
|
|
00E85B 1 84 D7 sty $D7 ; $E85B: 84 D7
|
|
00E85D 1
|
|
00E85D 1 ; ----------------------------------------------------------------------------
|
|
00E85D 1 ; Initialize the round index to $FF. It is incremented at the start of each
|
|
00E85D 1 ; round, producing indices $00-$07.
|
|
00E85D 1 ; ----------------------------------------------------------------------------
|
|
00E85D 1
|
|
00E85D 1 A9 FF lda #$FF ; $E85D: A9 FF
|
|
00E85F 1 85 DB sta $DB ; $E85F: 85 DB
|
|
00E861 1
|
|
00E861 1 A0 08 ldy #$08 ; $E861: A0 08
|
|
00E863 1
|
|
00E863 1 CalculateVectorFromRotatedMask_Loop: ; $E863
|
|
00E863 1 E6 DB inc $DB ; $E863: E6 DB
|
|
00E865 1
|
|
00E865 1 ; ----------------------------------------------------------------------------
|
|
00E865 1 ; Shift the next bit from $D8 into carry.
|
|
00E865 1 ;
|
|
00E865 1 ; X becomes:
|
|
00E865 1 ; $00 when carry is clear
|
|
00E865 1 ; $FF when carry is set
|
|
00E865 1 ;
|
|
00E865 1 ; This creates a sign-extension or conditional-mask byte in $DA.
|
|
00E865 1 ; ----------------------------------------------------------------------------
|
|
00E865 1
|
|
00E865 1 A2 00 ldx #$00 ; $E865: A2 00
|
|
00E867 1
|
|
00E867 1 26 D8 rol $D8 ; $E867: 26 D8
|
|
00E869 1 90 01 bcc CalculateVectorFromRotatedMask_SaveMask
|
|
00E86B 1 ; $E869: 90 01
|
|
00E86B 1
|
|
00E86B 1 CA dex ; $E86B: CA
|
|
00E86C 1 ; X = $FF.
|
|
00E86C 1
|
|
00E86C 1 CalculateVectorFromRotatedMask_SaveMask: ; $E86C
|
|
00E86C 1 86 DA stx $DA ; $E86C: 86 DA
|
|
00E86E 1
|
|
00E86E 1 ; ----------------------------------------------------------------------------
|
|
00E86E 1 ; Apply the per-round result update.
|
|
00E86E 1 ; ----------------------------------------------------------------------------
|
|
00E86E 1
|
|
00E86E 1 20 08 E9 jsr UpdateSecondaryArithmeticPair ; $E86E: 20 08 E9
|
|
00E871 1
|
|
00E871 1 88 dey ; $E871: 88
|
|
00E872 1 D0 EF bne CalculateVectorFromRotatedMask_Loop
|
|
00E874 1 ; $E872: D0 EF
|
|
00E874 1
|
|
00E874 1 ; ----------------------------------------------------------------------------
|
|
00E874 1 ; Restore the original Y component before returning.
|
|
00E874 1 ; ----------------------------------------------------------------------------
|
|
00E874 1
|
|
00E874 1 A4 D7 ldy $D7 ; $E874: A4 D7
|
|
00E876 1 60 rts ; $E876: 60
|
|
00E877 1
|
|
00E877 1 ; ============================================================================
|
|
00E877 1 ; $E877-$E8A4
|
|
00E877 1 ; Run an eight-round signed-vector normalization using source values in
|
|
00E877 1 ; $D4-$D7.
|
|
00E877 1 ;
|
|
00E877 1 ; Entry:
|
|
00E877 1 ; $D4 = signed primary source component
|
|
00E877 1 ; $D5 = secondary source component
|
|
00E877 1 ; $D6/$D7 = result or destination pair
|
|
00E877 1 ;
|
|
00E877 1 ; Working state:
|
|
00E877 1 ; $D9 = sign-extension byte derived from $D4
|
|
00E877 1 ; $DA = per-round working mask/result
|
|
00E877 1 ; $DB = shift/round state, initialized to $FF
|
|
00E877 1 ;
|
|
00E877 1 ; Exit:
|
|
00E877 1 ; A = normalized first result component
|
|
00E877 1 ; X = complemented sign-extension byte
|
|
00E877 1 ; Y = normalized second result component
|
|
00E877 1 ; ============================================================================
|
|
00E877 1
|
|
00E877 1 ; ----------------------------------------------------------------------------
|
|
00E877 1 ; Contract:
|
|
00E877 1 ; Description: Implements Normalize Signed Vector.
|
|
00E877 1 ; Entry: Registers: A, X, Y; Memory: $d4, $da, $d9, $d7, $d6
|
|
00E877 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E877 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E877 1 ; Memory effects: $db, $d9, $d4, $da
|
|
00E877 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E877 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E877 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E877 1 ; ----------------------------------------------------------------------------
|
|
00E877 1 NormalizeSignedVector: ; $E877
|
|
00E877 1 A0 FF ldy #$FF ; $E877: A0 FF
|
|
00E879 1 84 DB sty $DB ; $E879: 84 DB
|
|
00E87B 1
|
|
00E87B 1 ; ----------------------------------------------------------------------------
|
|
00E87B 1 ; Normalize the signed source byte at $D4.
|
|
00E87B 1 ;
|
|
00E87B 1 ; For a nonnegative value:
|
|
00E87B 1 ; $D9 = $FF
|
|
00E87B 1 ; $D4 remains unchanged
|
|
00E87B 1 ;
|
|
00E87B 1 ; For a negative value:
|
|
00E87B 1 ; $D9 = $00
|
|
00E87B 1 ; $D4 is one's-complemented
|
|
00E87B 1 ; ----------------------------------------------------------------------------
|
|
00E87B 1
|
|
00E87B 1 A5 D4 lda $D4 ; $E87B: A5 D4
|
|
00E87D 1 10 03 bpl NormalizeSignedVector_SaveSign
|
|
00E87F 1 ; $E87D: 10 03
|
|
00E87F 1
|
|
00E87F 1 C8 iny ; $E87F: C8
|
|
00E880 1 ; Y changes from $FF to $00.
|
|
00E880 1
|
|
00E880 1 49 FF eor #$FF ; $E880: 49 FF
|
|
00E882 1
|
|
00E882 1 NormalizeSignedVector_SaveSign: ; $E882
|
|
00E882 1 84 D9 sty $D9 ; $E882: 84 D9
|
|
00E884 1 85 D4 sta $D4 ; $E884: 85 D4
|
|
00E886 1
|
|
00E886 1 ; ----------------------------------------------------------------------------
|
|
00E886 1 ; Initialize X to zero and perform eight processing rounds.
|
|
00E886 1 ; ----------------------------------------------------------------------------
|
|
00E886 1
|
|
00E886 1 A2 00 ldx #$00 ; $E886: A2 00
|
|
00E888 1 A0 08 ldy #$08 ; $E888: A0 08
|
|
00E88A 1
|
|
00E88A 1 NormalizeSignedVector_Loop: ; $E88A
|
|
00E88A 1 20 DA E8 jsr UpdatePrimaryArithmeticPair ; $E88A: 20 DA E8
|
|
00E88D 1
|
|
00E88D 1 ; ----------------------------------------------------------------------------
|
|
00E88D 1 ; Apply the saved sign extension to $DA before updating the result pair.
|
|
00E88D 1 ; ----------------------------------------------------------------------------
|
|
00E88D 1
|
|
00E88D 1 A5 DA lda $DA ; $E88D: A5 DA
|
|
00E88F 1 45 D9 eor $D9 ; $E88F: 45 D9
|
|
00E891 1 85 DA sta $DA ; $E891: 85 DA
|
|
00E893 1
|
|
00E893 1 20 08 E9 jsr UpdateSecondaryArithmeticPair ; $E893: 20 08 E9
|
|
00E896 1
|
|
00E896 1 88 dey ; $E896: 88
|
|
00E897 1 D0 F1 bne NormalizeSignedVector_Loop
|
|
00E899 1 ; $E897: D0 F1
|
|
00E899 1
|
|
00E899 1 ; ----------------------------------------------------------------------------
|
|
00E899 1 ; Apply the final sign correction to the output pair.
|
|
00E899 1 ; ----------------------------------------------------------------------------
|
|
00E899 1
|
|
00E899 1 A5 D9 lda $D9 ; $E899: A5 D9
|
|
00E89B 1 49 FF eor #$FF ; $E89B: 49 FF
|
|
00E89D 1 AA tax ; $E89D: AA
|
|
00E89E 1 ; X = complement of sign-extension byte.
|
|
00E89E 1
|
|
00E89E 1 45 D7 eor $D7 ; $E89E: 45 D7
|
|
00E8A0 1 A8 tay ; $E8A0: A8
|
|
00E8A1 1
|
|
00E8A1 1 8A txa ; $E8A1: 8A
|
|
00E8A2 1 45 D6 eor $D6 ; $E8A2: 45 D6
|
|
00E8A4 1
|
|
00E8A4 1 60 rts ; $E8A4: 60
|
|
00E8A5 1
|
|
00E8A5 1 ; ============================================================================
|
|
00E8A5 1 ; $E8A5-$E8B6
|
|
00E8A5 1 ; Run an eight-round arithmetic transformation using the input pair X:Y.
|
|
00E8A5 1 ;
|
|
00E8A5 1 ; Entry:
|
|
00E8A5 1 ; X = first input component
|
|
00E8A5 1 ; Y = second input component
|
|
00E8A5 1 ;
|
|
00E8A5 1 ; Working state:
|
|
00E8A5 1 ; $D4 = saved X component
|
|
00E8A5 1 ; $D5 = saved Y component
|
|
00E8A5 1 ; $DB = round state, initialized to $FF
|
|
00E8A5 1 ;
|
|
00E8A5 1 ; Exit:
|
|
00E8A5 1 ; Result is returned in the state/registers produced by the final call to
|
|
00E8A5 1 ; $E931.
|
|
00E8A5 1 ;
|
|
00E8A5 1 ; The exact mathematical role depends on the shared helper at $E931, but this
|
|
00E8A5 1 ; routine is clearly an eight-round wrapper around that operation.
|
|
00E8A5 1 ; ============================================================================
|
|
00E8A5 1
|
|
00E8A5 1 ; ----------------------------------------------------------------------------
|
|
00E8A5 1 ; Contract:
|
|
00E8A5 1 ; Description: Runs Eight Round Transform.
|
|
00E8A5 1 ; Entry: Registers: X, Y
|
|
00E8A5 1 ; Returns/products: Registers/clobbers: X, Y
|
|
00E8A5 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E8A5 1 ; Memory effects: $d4, $d5, $db
|
|
00E8A5 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E8A5 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E8A5 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E8A5 1 ; ----------------------------------------------------------------------------
|
|
00E8A5 1 RunEightRoundTransform: ; $E8A5
|
|
00E8A5 1 86 D4 stx $D4 ; $E8A5: 86 D4
|
|
00E8A7 1 84 D5 sty $D5 ; $E8A7: 84 D5
|
|
00E8A9 1
|
|
00E8A9 1 ; ----------------------------------------------------------------------------
|
|
00E8A9 1 ; Initialize the round state.
|
|
00E8A9 1 ;
|
|
00E8A9 1 ; X is first set to $FF and stored in $DB, then incremented to zero.
|
|
00E8A9 1 ; ----------------------------------------------------------------------------
|
|
00E8A9 1
|
|
00E8A9 1 A2 FF ldx #$FF ; $E8A9: A2 FF
|
|
00E8AB 1 86 DB stx $DB ; $E8AB: 86 DB
|
|
00E8AD 1
|
|
00E8AD 1 E8 inx ; $E8AD: E8
|
|
00E8AE 1 ; X = $00.
|
|
00E8AE 1
|
|
00E8AE 1 A0 08 ldy #$08 ; $E8AE: A0 08
|
|
00E8B0 1
|
|
00E8B0 1 RunEightRoundTransform_Loop: ; $E8B0
|
|
00E8B0 1 20 31 E9 jsr UpdatePrimaryArithmeticPairAlternate ; $E8B0: 20 31 E9
|
|
00E8B3 1
|
|
00E8B3 1 88 dey ; $E8B3: 88
|
|
00E8B4 1 D0 FA bne RunEightRoundTransform_Loop
|
|
00E8B6 1 ; $E8B4: D0 FA
|
|
00E8B6 1
|
|
00E8B6 1 60 rts ; $E8B6: 60
|
|
00E8B7 1
|
|
00E8B7 1 ; ============================================================================
|
|
00E8B7 1 ; $E8B7-$E8D9
|
|
00E8B7 1 ; Convert the A:Y input pair to component magnitudes, perform eight common
|
|
00E8B7 1 ; arithmetic rounds, and return a transformed high/result byte.
|
|
00E8B7 1 ;
|
|
00E8B7 1 ; Entry:
|
|
00E8B7 1 ; A = first signed component
|
|
00E8B7 1 ; Y = second signed component
|
|
00E8B7 1 ;
|
|
00E8B7 1 ; Normalization:
|
|
00E8B7 1 ; Negative components are one's-complemented.
|
|
00E8B7 1 ;
|
|
00E8B7 1 ; Working state:
|
|
00E8B7 1 ; $D4 = normalized first component
|
|
00E8B7 1 ; $D5 = normalized second component
|
|
00E8B7 1 ; $D9/$DA = common round result pair
|
|
00E8B7 1 ; $DB = round state, initialized to $FF
|
|
00E8B7 1 ;
|
|
00E8B7 1 ; Exit:
|
|
00E8B7 1 ; A = $D9 XOR $7F
|
|
00E8B7 1 ;
|
|
00E8B7 1 ; This is not a standard two's-complement absolute-value conversion because no
|
|
00E8B7 1 ; one is added after the complement. The shared round helper accounts for the
|
|
00E8B7 1 ; representation.
|
|
00E8B7 1 ; ============================================================================
|
|
00E8B7 1
|
|
00E8B7 1 TransformSignedComponentPair: ; $E8B7
|
|
00E8B7 1 10 02 bpl TransformSignedComponentPair_SaveA
|
|
00E8B9 1 ; $E8B7: 10 02
|
|
00E8B9 1
|
|
00E8B9 1 49 FF eor #$FF ; $E8B9: 49 FF
|
|
00E8BB 1
|
|
00E8BB 1 TransformSignedComponentPair_SaveA: ; $E8BB
|
|
00E8BB 1 85 D4 sta $D4 ; $E8BB: 85 D4
|
|
00E8BD 1
|
|
00E8BD 1 ; ----------------------------------------------------------------------------
|
|
00E8BD 1 ; Normalize the Y component.
|
|
00E8BD 1 ; ----------------------------------------------------------------------------
|
|
00E8BD 1
|
|
00E8BD 1 98 tya ; $E8BD: 98
|
|
00E8BE 1 10 02 bpl TransformSignedComponentPair_SaveY
|
|
00E8C0 1 ; $E8BE: 10 02
|
|
00E8C0 1
|
|
00E8C0 1 49 FF eor #$FF ; $E8C0: 49 FF
|
|
00E8C2 1
|
|
00E8C2 1 TransformSignedComponentPair_SaveY: ; $E8C2
|
|
00E8C2 1 85 D5 sta $D5 ; $E8C2: 85 D5
|
|
00E8C4 1
|
|
00E8C4 1 ; ----------------------------------------------------------------------------
|
|
00E8C4 1 ; Initialize the round state.
|
|
00E8C4 1 ; ----------------------------------------------------------------------------
|
|
00E8C4 1
|
|
00E8C4 1 A2 FF ldx #$FF ; $E8C4: A2 FF
|
|
00E8C6 1 86 DB stx $DB ; $E8C6: 86 DB
|
|
00E8C8 1
|
|
00E8C8 1 E8 inx ; $E8C8: E8
|
|
00E8C9 1 ; X = $00.
|
|
00E8C9 1
|
|
00E8C9 1 A0 08 ldy #$08 ; $E8C9: A0 08
|
|
00E8CB 1
|
|
00E8CB 1 ; ----------------------------------------------------------------------------
|
|
00E8CB 1 ; Run eight common arithmetic rounds.
|
|
00E8CB 1 ;
|
|
00E8CB 1 ; After each round:
|
|
00E8CB 1 ; $DA is shifted left.
|
|
00E8CB 1 ; Carry is rotated into $D9.
|
|
00E8CB 1 ; ----------------------------------------------------------------------------
|
|
00E8CB 1
|
|
00E8CB 1 TransformSignedComponentPair_Loop: ; $E8CB
|
|
00E8CB 1 20 DA E8 jsr UpdatePrimaryArithmeticPair ; $E8CB: 20 DA E8
|
|
00E8CE 1
|
|
00E8CE 1 06 DA asl $DA ; $E8CE: 06 DA
|
|
00E8D0 1 26 D9 rol $D9 ; $E8D0: 26 D9
|
|
00E8D2 1
|
|
00E8D2 1 88 dey ; $E8D2: 88
|
|
00E8D3 1 D0 F6 bne TransformSignedComponentPair_Loop
|
|
00E8D5 1 ; $E8D3: D0 F6
|
|
00E8D5 1
|
|
00E8D5 1 ; ----------------------------------------------------------------------------
|
|
00E8D5 1 ; Return the transformed result.
|
|
00E8D5 1 ; ----------------------------------------------------------------------------
|
|
00E8D5 1
|
|
00E8D5 1 A5 D9 lda $D9 ; $E8D5: A5 D9
|
|
00E8D7 1 49 7F eor #$7F ; $E8D7: 49 7F
|
|
00E8D9 1
|
|
00E8D9 1 60 rts ; $E8D9: 60
|
|
00E8DA 1
|
|
00E8DA 1 ; ============================================================================
|
|
00E8DA 1 ; $E8DA-$E907
|
|
00E8DA 1 ; Shared per-round arithmetic update for source pair $D4/$D5.
|
|
00E8DA 1 ;
|
|
00E8DA 1 ; Working state:
|
|
00E8DA 1 ; $D4/$D5 = signed or fixed-point accumulator
|
|
00E8DA 1 ; $DA = per-round sign/mask byte
|
|
00E8DA 1 ; $DB = shift count, incremented at the start of the round
|
|
00E8DA 1 ;
|
|
00E8DA 1 ; Operation:
|
|
00E8DA 1 ; 1. Increment the shift count.
|
|
00E8DA 1 ; 2. Derive $DA from the sign of $D5.
|
|
00E8DA 1 ; 3. Shift and add $D4 into itself.
|
|
00E8DA 1 ; 4. Shift a sign-corrected form of $D4.
|
|
00E8DA 1 ; 5. Add the result into $D5.
|
|
00E8DA 1 ;
|
|
00E8DA 1 ; Exit:
|
|
00E8DA 1 ; $D4/$D5 updated in place
|
|
00E8DA 1 ; ============================================================================
|
|
00E8DA 1
|
|
00E8DA 1 ; ----------------------------------------------------------------------------
|
|
00E8DA 1 ; Contract:
|
|
00E8DA 1 ; Description: Updates Primary Arithmetic Pair.
|
|
00E8DA 1 ; Entry: Registers: A, X; Memory: $d5, $db, $d4, $da
|
|
00E8DA 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E8DA 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E8DA 1 ; Memory effects: $da, $d5, $d4
|
|
00E8DA 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E8DA 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E8DA 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 4.
|
|
00E8DA 1 ; ----------------------------------------------------------------------------
|
|
00E8DA 1 UpdatePrimaryArithmeticPair: ; $E8DA
|
|
00E8DA 1 E6 DB inc $DB ; $E8DA: E6 DB
|
|
00E8DC 1 ; Advance the per-round shift count.
|
|
00E8DC 1
|
|
00E8DC 1 A5 D5 lda $D5 ; $E8DC: A5 D5
|
|
00E8DE 1 10 03 bpl UpdatePrimaryArithmeticPair_SaveMask
|
|
00E8E0 1 ; $E8DE: 10 03
|
|
00E8E0 1
|
|
00E8E0 1 ; ----------------------------------------------------------------------------
|
|
00E8E0 1 ; Negative high/source byte:
|
|
00E8E0 1 ;
|
|
00E8E0 1 ; X is decremented from the caller's current value.
|
|
00E8E0 1 ; A is one's-complemented.
|
|
00E8E0 1 ; ----------------------------------------------------------------------------
|
|
00E8E0 1
|
|
00E8E0 1 CA dex ; $E8E0: CA
|
|
00E8E1 1 49 FF eor #$FF ; $E8E1: 49 FF
|
|
00E8E3 1
|
|
00E8E3 1 UpdatePrimaryArithmeticPair_SaveMask: ; $E8E3
|
|
00E8E3 1 86 DA stx $DA ; $E8E3: 86 DA
|
|
00E8E5 1
|
|
00E8E5 1 ; ----------------------------------------------------------------------------
|
|
00E8E5 1 ; Shift A right by the current count in $DB.
|
|
00E8E5 1 ;
|
|
00E8E5 1 ; When $DB is zero, no shift is performed.
|
|
00E8E5 1 ; ----------------------------------------------------------------------------
|
|
00E8E5 1
|
|
00E8E5 1 A6 DB ldx $DB ; $E8E5: A6 DB
|
|
00E8E7 1 F0 04 beq UpdatePrimaryArithmeticPair_AddLow
|
|
00E8E9 1 ; $E8E7: F0 04
|
|
00E8E9 1
|
|
00E8E9 1 UpdatePrimaryArithmeticPair_ShiftLow: ; $E8E9
|
|
00E8E9 1 4A lsr ; $E8E9: 4A
|
|
00E8EA 1 CA dex ; $E8EA: CA
|
|
00E8EB 1 D0 FC bne UpdatePrimaryArithmeticPair_ShiftLow
|
|
00E8ED 1 ; $E8EB: D0 FC
|
|
00E8ED 1
|
|
00E8ED 1 ; ----------------------------------------------------------------------------
|
|
00E8ED 1 ; Add the shifted value to $D4.
|
|
00E8ED 1 ;
|
|
00E8ED 1 ; Carry intentionally comes from the final LSR or from the preceding sign
|
|
00E8ED 1 ; setup when no shift occurred.
|
|
00E8ED 1 ; ----------------------------------------------------------------------------
|
|
00E8ED 1
|
|
00E8ED 1 UpdatePrimaryArithmeticPair_AddLow: ; $E8ED
|
|
00E8ED 1 65 D4 adc $D4 ; $E8ED: 65 D4
|
|
00E8EF 1 48 pha ; $E8EF: 48
|
|
00E8F0 1 ; Preserve the new low/result byte.
|
|
00E8F0 1
|
|
00E8F0 1 ; ----------------------------------------------------------------------------
|
|
00E8F0 1 ; Build the high/source contribution:
|
|
00E8F0 1 ;
|
|
00E8F0 1 ; A = ($DA XOR $FF XOR $D4)
|
|
00E8F0 1 ;
|
|
00E8F0 1 ; Then arithmetically shift it right by $DB.
|
|
00E8F0 1 ; ----------------------------------------------------------------------------
|
|
00E8F0 1
|
|
00E8F0 1 A5 DA lda $DA ; $E8F0: A5 DA
|
|
00E8F2 1 49 FF eor #$FF ; $E8F2: 49 FF
|
|
00E8F4 1 45 D4 eor $D4 ; $E8F4: 45 D4
|
|
00E8F6 1
|
|
00E8F6 1 A6 DB ldx $DB ; $E8F6: A6 DB
|
|
00E8F8 1 F0 06 beq UpdatePrimaryArithmeticPair_AddHigh
|
|
00E8FA 1 ; $E8F8: F0 06
|
|
00E8FA 1
|
|
00E8FA 1 UpdatePrimaryArithmeticPair_ShiftHigh: ; $E8FA
|
|
00E8FA 1 C9 80 cmp #$80 ; $E8FA: C9 80
|
|
00E8FC 1 ; Copy the sign bit into carry.
|
|
00E8FC 1
|
|
00E8FC 1 6A ror ; $E8FC: 6A
|
|
00E8FD 1 ; Arithmetic right shift.
|
|
00E8FD 1
|
|
00E8FD 1 CA dex ; $E8FD: CA
|
|
00E8FE 1 D0 FA bne UpdatePrimaryArithmeticPair_ShiftHigh
|
|
00E900 1 ; $E8FE: D0 FA
|
|
00E900 1
|
|
00E900 1 ; ----------------------------------------------------------------------------
|
|
00E900 1 ; Add the shifted high/source result to $D5.
|
|
00E900 1 ; ----------------------------------------------------------------------------
|
|
00E900 1
|
|
00E900 1 UpdatePrimaryArithmeticPair_AddHigh: ; $E900
|
|
00E900 1 65 D5 adc $D5 ; $E900: 65 D5
|
|
00E902 1 85 D5 sta $D5 ; $E902: 85 D5
|
|
00E904 1
|
|
00E904 1 ; ----------------------------------------------------------------------------
|
|
00E904 1 ; Restore and save the low/result byte.
|
|
00E904 1 ; ----------------------------------------------------------------------------
|
|
00E904 1
|
|
00E904 1 68 pla ; $E904: 68
|
|
00E905 1 85 D4 sta $D4 ; $E905: 85 D4
|
|
00E907 1
|
|
00E907 1 60 rts ; $E907: 60
|
|
00E908 1
|
|
00E908 1 ; ============================================================================
|
|
00E908 1 ; $E908-$E930
|
|
00E908 1 ; Apply the current per-round mask and shift state to result pair $D6/$D7.
|
|
00E908 1 ;
|
|
00E908 1 ; Working state:
|
|
00E908 1 ; $D6/$D7 = secondary accumulator/result pair
|
|
00E908 1 ; $DA = sign/mask byte
|
|
00E908 1 ; $DB = shift count
|
|
00E908 1 ;
|
|
00E908 1 ; Exit:
|
|
00E908 1 ; $D6/$D7 updated in place
|
|
00E908 1 ;
|
|
00E908 1 ; This routine is paired with UpdatePrimaryArithmeticPair and is called after
|
|
00E908 1 ; each common arithmetic round by multiple vector helpers.
|
|
00E908 1 ; ============================================================================
|
|
00E908 1
|
|
00E908 1 ; ----------------------------------------------------------------------------
|
|
00E908 1 ; Contract:
|
|
00E908 1 ; Description: Updates Secondary Arithmetic Pair.
|
|
00E908 1 ; Entry: Registers: A, X; Memory: $da, $d7, $db, $d6
|
|
00E908 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E908 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E908 1 ; Memory effects: $d7, $d6
|
|
00E908 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E908 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E908 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00E908 1 ; ----------------------------------------------------------------------------
|
|
00E908 1 UpdateSecondaryArithmeticPair: ; $E908
|
|
00E908 1 A5 DA lda $DA ; $E908: A5 DA
|
|
00E90A 1 49 FF eor #$FF ; $E90A: 49 FF
|
|
00E90C 1 45 D7 eor $D7 ; $E90C: 45 D7
|
|
00E90E 1
|
|
00E90E 1 ; ----------------------------------------------------------------------------
|
|
00E90E 1 ; Arithmetically shift the sign-corrected high contribution by $DB.
|
|
00E90E 1 ; ----------------------------------------------------------------------------
|
|
00E90E 1
|
|
00E90E 1 A6 DB ldx $DB ; $E90E: A6 DB
|
|
00E910 1 F0 06 beq UpdateSecondaryArithmeticPair_AddLow
|
|
00E912 1 ; $E910: F0 06
|
|
00E912 1
|
|
00E912 1 UpdateSecondaryArithmeticPair_ShiftLow: ; $E912
|
|
00E912 1 C9 80 cmp #$80 ; $E912: C9 80
|
|
00E914 1 6A ror ; $E914: 6A
|
|
00E915 1
|
|
00E915 1 CA dex ; $E915: CA
|
|
00E916 1 D0 FA bne UpdateSecondaryArithmeticPair_ShiftLow
|
|
00E918 1 ; $E916: D0 FA
|
|
00E918 1
|
|
00E918 1 ; ----------------------------------------------------------------------------
|
|
00E918 1 ; Add the shifted contribution to $D6.
|
|
00E918 1 ; ----------------------------------------------------------------------------
|
|
00E918 1
|
|
00E918 1 UpdateSecondaryArithmeticPair_AddLow: ; $E918
|
|
00E918 1 65 D6 adc $D6 ; $E918: 65 D6
|
|
00E91A 1 48 pha ; $E91A: 48
|
|
00E91B 1 ; Preserve the new low/result byte.
|
|
00E91B 1
|
|
00E91B 1 ; ----------------------------------------------------------------------------
|
|
00E91B 1 ; Build and shift the contribution for $D7.
|
|
00E91B 1 ; ----------------------------------------------------------------------------
|
|
00E91B 1
|
|
00E91B 1 A5 DA lda $DA ; $E91B: A5 DA
|
|
00E91D 1 45 D6 eor $D6 ; $E91D: 45 D6
|
|
00E91F 1
|
|
00E91F 1 A6 DB ldx $DB ; $E91F: A6 DB
|
|
00E921 1 F0 06 beq UpdateSecondaryArithmeticPair_AddHigh
|
|
00E923 1 ; $E921: F0 06
|
|
00E923 1
|
|
00E923 1 UpdateSecondaryArithmeticPair_ShiftHigh: ; $E923
|
|
00E923 1 C9 80 cmp #$80 ; $E923: C9 80
|
|
00E925 1 6A ror ; $E925: 6A
|
|
00E926 1
|
|
00E926 1 CA dex ; $E926: CA
|
|
00E927 1 D0 FA bne UpdateSecondaryArithmeticPair_ShiftHigh
|
|
00E929 1 ; $E927: D0 FA
|
|
00E929 1
|
|
00E929 1 ; ----------------------------------------------------------------------------
|
|
00E929 1 ; Add the shifted contribution to $D7.
|
|
00E929 1 ; ----------------------------------------------------------------------------
|
|
00E929 1
|
|
00E929 1 UpdateSecondaryArithmeticPair_AddHigh: ; $E929
|
|
00E929 1 65 D7 adc $D7 ; $E929: 65 D7
|
|
00E92B 1 85 D7 sta $D7 ; $E92B: 85 D7
|
|
00E92D 1
|
|
00E92D 1 ; ----------------------------------------------------------------------------
|
|
00E92D 1 ; Restore and save the low/result byte.
|
|
00E92D 1 ; ----------------------------------------------------------------------------
|
|
00E92D 1
|
|
00E92D 1 68 pla ; $E92D: 68
|
|
00E92E 1 85 D6 sta $D6 ; $E92E: 85 D6
|
|
00E930 1
|
|
00E930 1 60 rts ; $E930: 60
|
|
00E931 1
|
|
00E931 1 ; ============================================================================
|
|
00E931 1 ; $E931-$E964
|
|
00E931 1 ; Alternate per-round update for source pair $D4/$D5.
|
|
00E931 1 ;
|
|
00E931 1 ; This helper differs from the $E8DA version in two ways:
|
|
00E931 1 ;
|
|
00E931 1 ; 1. It derives $DA from the opposite sign condition.
|
|
00E931 1 ; 2. Shift counts below four are increased by one.
|
|
00E931 1 ;
|
|
00E931 1 ; Working state:
|
|
00E931 1 ; $D4/$D5 = signed or fixed-point accumulator
|
|
00E931 1 ; $DA = per-round sign/mask byte
|
|
00E931 1 ; $DB = shift count, incremented at the start of the round
|
|
00E931 1 ;
|
|
00E931 1 ; Exit:
|
|
00E931 1 ; $D4/$D5 updated in place
|
|
00E931 1 ; ============================================================================
|
|
00E931 1
|
|
00E931 1 ; ----------------------------------------------------------------------------
|
|
00E931 1 ; Contract:
|
|
00E931 1 ; Description: Updates Primary Arithmetic Pair Alternate.
|
|
00E931 1 ; Entry: Registers: A, X; Memory: $d5, $db, $d4, $da
|
|
00E931 1 ; Returns/products: Registers/clobbers: A, X
|
|
00E931 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E931 1 ; Memory effects: $da, $d5, $d4
|
|
00E931 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E931 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E931 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E931 1 ; ----------------------------------------------------------------------------
|
|
00E931 1 UpdatePrimaryArithmeticPairAlternate: ; $E931
|
|
00E931 1 E6 DB inc $DB ; $E931: E6 DB
|
|
00E933 1
|
|
00E933 1 A5 D5 lda $D5 ; $E933: A5 D5
|
|
00E935 1 30 03 bmi UpdatePrimaryArithmeticPairAlternate_SaveMask
|
|
00E937 1 ; $E935: 30 03
|
|
00E937 1
|
|
00E937 1 ; ----------------------------------------------------------------------------
|
|
00E937 1 ; Nonnegative high/source byte:
|
|
00E937 1 ;
|
|
00E937 1 ; A is one's-complemented.
|
|
00E937 1 ; X is decremented.
|
|
00E937 1 ; ----------------------------------------------------------------------------
|
|
00E937 1
|
|
00E937 1 49 FF eor #$FF ; $E937: 49 FF
|
|
00E939 1 CA dex ; $E939: CA
|
|
00E93A 1
|
|
00E93A 1 UpdatePrimaryArithmeticPairAlternate_SaveMask: ; $E93A
|
|
00E93A 1 86 DA stx $DA ; $E93A: 86 DA
|
|
00E93C 1
|
|
00E93C 1 ; ----------------------------------------------------------------------------
|
|
00E93C 1 ; Load the shift count.
|
|
00E93C 1 ;
|
|
00E93C 1 ; Counts below four are increased by one.
|
|
00E93C 1 ; ----------------------------------------------------------------------------
|
|
00E93C 1
|
|
00E93C 1 A6 DB ldx $DB ; $E93C: A6 DB
|
|
00E93E 1 E0 04 cpx #$04 ; $E93E: E0 04
|
|
00E940 1 B0 01 bcs UpdatePrimaryArithmeticPairAlternate_ShiftLow
|
|
00E942 1 ; $E940: B0 01
|
|
00E942 1
|
|
00E942 1 E8 inx ; $E942: E8
|
|
00E943 1
|
|
00E943 1 ; ----------------------------------------------------------------------------
|
|
00E943 1 ; Arithmetically shift A right by the adjusted count.
|
|
00E943 1 ; ----------------------------------------------------------------------------
|
|
00E943 1
|
|
00E943 1 UpdatePrimaryArithmeticPairAlternate_ShiftLow: ; $E943
|
|
00E943 1 C9 80 cmp #$80 ; $E943: C9 80
|
|
00E945 1 6A ror ; $E945: 6A
|
|
00E946 1
|
|
00E946 1 CA dex ; $E946: CA
|
|
00E947 1 D0 FA bne UpdatePrimaryArithmeticPairAlternate_ShiftLow
|
|
00E949 1 ; $E947: D0 FA
|
|
00E949 1
|
|
00E949 1 ; ----------------------------------------------------------------------------
|
|
00E949 1 ; Add the shifted result to $D4.
|
|
00E949 1 ; ----------------------------------------------------------------------------
|
|
00E949 1
|
|
00E949 1 65 D4 adc $D4 ; $E949: 65 D4
|
|
00E94B 1 48 pha ; $E94B: 48
|
|
00E94C 1
|
|
00E94C 1 ; ----------------------------------------------------------------------------
|
|
00E94C 1 ; Build the contribution for $D5.
|
|
00E94C 1 ; ----------------------------------------------------------------------------
|
|
00E94C 1
|
|
00E94C 1 A5 DA lda $DA ; $E94C: A5 DA
|
|
00E94E 1 45 D4 eor $D4 ; $E94E: 45 D4
|
|
00E950 1
|
|
00E950 1 ; ----------------------------------------------------------------------------
|
|
00E950 1 ; Apply the same adjusted shift-count rule.
|
|
00E950 1 ; ----------------------------------------------------------------------------
|
|
00E950 1
|
|
00E950 1 A6 DB ldx $DB ; $E950: A6 DB
|
|
00E952 1 E0 04 cpx #$04 ; $E952: E0 04
|
|
00E954 1 B0 01 bcs UpdatePrimaryArithmeticPairAlternate_ShiftHigh
|
|
00E956 1 ; $E954: B0 01
|
|
00E956 1
|
|
00E956 1 E8 inx ; $E956: E8
|
|
00E957 1
|
|
00E957 1 UpdatePrimaryArithmeticPairAlternate_ShiftHigh: ; $E957
|
|
00E957 1 C9 80 cmp #$80 ; $E957: C9 80
|
|
00E959 1 6A ror ; $E959: 6A
|
|
00E95A 1
|
|
00E95A 1 CA dex ; $E95A: CA
|
|
00E95B 1 D0 FA bne UpdatePrimaryArithmeticPairAlternate_ShiftHigh
|
|
00E95D 1 ; $E95B: D0 FA
|
|
00E95D 1
|
|
00E95D 1 ; ----------------------------------------------------------------------------
|
|
00E95D 1 ; Add the shifted contribution to $D5.
|
|
00E95D 1 ; ----------------------------------------------------------------------------
|
|
00E95D 1
|
|
00E95D 1 65 D5 adc $D5 ; $E95D: 65 D5
|
|
00E95F 1 85 D5 sta $D5 ; $E95F: 85 D5
|
|
00E961 1
|
|
00E961 1 ; ----------------------------------------------------------------------------
|
|
00E961 1 ; Restore and save the updated low/result byte.
|
|
00E961 1 ; ----------------------------------------------------------------------------
|
|
00E961 1
|
|
00E961 1 68 pla ; $E961: 68
|
|
00E962 1 85 D4 sta $D4 ; $E962: 85 D4
|
|
00E964 1
|
|
00E964 1 60 rts ; $E964: 60
|
|
00E965 1
|
|
00E965 1 ; ============================================================================
|
|
00E965 1 ; $E965-$E96B
|
|
00E965 1 ; Calculate a scaled ratio by chaining the multiplication and division helpers.
|
|
00E965 1 ;
|
|
00E965 1 ; Entry and exit registers depend on the callers:
|
|
00E965 1 ;
|
|
00E965 1 ; CalculateScaledProduct = $E7DB
|
|
00E965 1 ; DivideUnsignedByte = $E7F5
|
|
00E965 1 ; ============================================================================
|
|
00E965 1
|
|
00E965 1 ; ----------------------------------------------------------------------------
|
|
00E965 1 ; Contract:
|
|
00E965 1 ; Description: Calculates Scaled Ratio.
|
|
00E965 1 ; Entry: No register input inferred
|
|
00E965 1 ; Returns/products: No direct product inferred
|
|
00E965 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E965 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E965 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E965 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E965 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E965 1 ; ----------------------------------------------------------------------------
|
|
00E965 1 CalculateScaledRatio: ; $E965
|
|
00E965 1 20 DB E7 jsr CalculateScaledProduct ; $E965: 20 DB E7
|
|
00E968 1 20 F5 E7 jsr DivideUnsignedByte ; $E968: 20 F5 E7
|
|
00E96B 1 60 rts ; $E96B: 60
|
|
00E96C 1
|
|
00E96C 1 ; ============================================================================
|
|
00E96C 1 ; $E96C-$E977
|
|
00E96C 1 ; Disable PPU rendering and read PPUSTATUS.
|
|
00E96C 1 ;
|
|
00E96C 1 ; Exit:
|
|
00E96C 1 ; Rendering is disabled.
|
|
00E96C 1 ; A contains the value read from PPUSTATUS.
|
|
00E96C 1 ; ============================================================================
|
|
00E96C 1
|
|
00E96C 1 ; ----------------------------------------------------------------------------
|
|
00E96C 1 ; Contract:
|
|
00E96C 1 ; Description: Implements Disable Ppu Rendering.
|
|
00E96C 1 ; Entry: Registers: A; Memory: $2002
|
|
00E96C 1 ; Returns/products: Registers/clobbers: A
|
|
00E96C 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E96C 1 ; Memory effects: $2000, $2001
|
|
00E96C 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E96C 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E96C 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 4.
|
|
00E96C 1 ; ----------------------------------------------------------------------------
|
|
00E96C 1 DisablePpuRendering: ; $E96C
|
|
00E96C 1 A9 00 lda #$00 ; $E96C: A9 00
|
|
00E96E 1
|
|
00E96E 1 8D 00 20 sta $2000 ; $E96E: 8D 00 20
|
|
00E971 1 ; Disable NMI and reset PPUCTRL state.
|
|
00E971 1
|
|
00E971 1 8D 01 20 sta $2001 ; $E971: 8D 01 20
|
|
00E974 1 ; Disable background and sprite rendering.
|
|
00E974 1
|
|
00E974 1 AD 02 20 lda $2002 ; $E974: AD 02 20
|
|
00E977 1 ; Read PPUSTATUS and reset the address latch.
|
|
00E977 1
|
|
00E977 1 60 rts ; $E977: 60
|
|
00E978 1
|
|
00E978 1 ; ============================================================================
|
|
00E978 1 ; $E978-$E982
|
|
00E978 1 ; Reset the PPU address latch, enable NMI, and jump to the frame-wait helper.
|
|
00E978 1 ; ============================================================================
|
|
00E978 1
|
|
00E978 1 ; ----------------------------------------------------------------------------
|
|
00E978 1 ; Contract:
|
|
00E978 1 ; Description: Implements Enable Nmi And Wait For Frame.
|
|
00E978 1 ; Entry: Registers: A; Memory: $2002
|
|
00E978 1 ; Returns/products: Registers/clobbers: A
|
|
00E978 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E978 1 ; Memory effects: $2000
|
|
00E978 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E978 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E978 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00E978 1 ; ----------------------------------------------------------------------------
|
|
00E978 1 EnableNmiAndWaitForFrame: ; $E978
|
|
00E978 1 AD 02 20 lda $2002 ; $E978: AD 02 20
|
|
00E97B 1 ; Reset the PPU address latch.
|
|
00E97B 1
|
|
00E97B 1 A9 80 lda #$80 ; $E97B: A9 80
|
|
00E97D 1 8D 00 20 sta $2000 ; $E97D: 8D 00 20
|
|
00E980 1 ; Enable NMI.
|
|
00E980 1
|
|
00E980 1 4C 48 EB jmp SelectObjectEventBank1 ; $E980: 4C 48 EB
|
|
00E983 1
|
|
00E983 1 ; ============================================================================
|
|
00E983 1 ; $E983-$E999
|
|
00E983 1 ; Fill $1000 bytes of PPU memory with tile/value $26.
|
|
00E983 1 ;
|
|
00E983 1 ; The helper at $E9DB consumes the two inline bytes following its JSR:
|
|
00E983 1 ;
|
|
00E983 1 ; $00,$20
|
|
00E983 1 ;
|
|
00E983 1 ; These bytes appear to specify PPU address $2000 in little-endian order.
|
|
00E983 1 ; Execution resumes at the PLA instruction at $E98B.
|
|
00E983 1 ;
|
|
00E983 1 ; Operation:
|
|
00E983 1 ; 1. Preserve fill value $26 on the stack.
|
|
00E983 1 ; 2. Set the PPU destination address to $2000.
|
|
00E983 1 ; 3. Restore fill value $26.
|
|
00E983 1 ; 4. Write $26 to PPUDATA $1000 times.
|
|
00E983 1 ;
|
|
00E983 1 ; Total writes:
|
|
00E983 1 ; $10 outer iterations * $100 inner iterations = $1000 bytes.
|
|
00E983 1 ; ============================================================================
|
|
00E983 1
|
|
00E983 1 ; ----------------------------------------------------------------------------
|
|
00E983 1 ; Contract:
|
|
00E983 1 ; Description: Implements Fill Ppu Memory With 2 6.
|
|
00E983 1 ; Entry: Registers: A, X, Y
|
|
00E983 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E983 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E983 1 ; Memory effects: $2007
|
|
00E983 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E983 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E983 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E983 1 ; ----------------------------------------------------------------------------
|
|
00E983 1 FillPpuMemoryWith26: ; $E983
|
|
00E983 1 A9 26 lda #$26 ; $E983: A9 26
|
|
00E985 1 ; Tile or fill value.
|
|
00E985 1
|
|
00E985 1 ; ----------------------------------------------------------------------------
|
|
00E985 1 ; Contract:
|
|
00E985 1 ; Description: Internal PPU-fill entry after the fill value has been pushed.
|
|
00E985 1 ; Entry: Stack top = fill value.
|
|
00E985 1 ; Returns/products: PPU region filled; A/X/Y clobbered.
|
|
00E985 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E985 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E985 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E985 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E985 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00E985 1 ; ----------------------------------------------------------------------------
|
|
00E985 1 FillPpuMemoryAfterValueSaved:
|
|
00E985 1 48 pha ; $E985: 48
|
|
00E986 1 ; Preserve the fill value while the inline
|
|
00E986 1 ; PPU-address helper runs.
|
|
00E986 1
|
|
00E986 1 ; ----------------------------------------------------------------------------
|
|
00E986 1 ; Set the PPU destination address using the inline address record.
|
|
00E986 1 ;
|
|
00E986 1 ; The JSR return-address logic in $E9DB advances execution past the two inline
|
|
00E986 1 ; bytes, so execution resumes at $E98B.
|
|
00E986 1 ; ----------------------------------------------------------------------------
|
|
00E986 1
|
|
00E986 1 20 DB E9 jsr SetPpuAddressFromInlineRecord ; $E986: 20 DB E9
|
|
00E989 1
|
|
00E989 1 00 20 .byte $00,$20 ; $E989-$E98A
|
|
00E98B 1 ; Inline PPU address: $2000.
|
|
00E98B 1
|
|
00E98B 1 ; ----------------------------------------------------------------------------
|
|
00E98B 1 ; Restore the fill value.
|
|
00E98B 1 ; ----------------------------------------------------------------------------
|
|
00E98B 1
|
|
00E98B 1 68 pla ; $E98B: 68
|
|
00E98C 1 ; A = $26.
|
|
00E98C 1
|
|
00E98C 1 ; ----------------------------------------------------------------------------
|
|
00E98C 1 ; Initialize the outer and inner loop counters.
|
|
00E98C 1 ;
|
|
00E98C 1 ; X = $10 outer blocks.
|
|
00E98C 1 ; Y = $00, which produces 256 iterations because DEY wraps to $FF.
|
|
00E98C 1 ; ----------------------------------------------------------------------------
|
|
00E98C 1
|
|
00E98C 1 A2 10 ldx #$10 ; $E98C: A2 10
|
|
00E98E 1 A0 00 ldy #$00 ; $E98E: A0 00
|
|
00E990 1
|
|
00E990 1 ; ----------------------------------------------------------------------------
|
|
00E990 1 ; Write one byte to PPUDATA.
|
|
00E990 1 ;
|
|
00E990 1 ; The PPU automatically increments its internal VRAM address after the write.
|
|
00E990 1 ; ----------------------------------------------------------------------------
|
|
00E990 1
|
|
00E990 1 FillPpuMemoryWith26_Loop: ; $E990
|
|
00E990 1 8D 07 20 sta $2007 ; $E990: 8D 07 20
|
|
00E993 1
|
|
00E993 1 ; ----------------------------------------------------------------------------
|
|
00E993 1 ; Process 256 bytes in the current outer block.
|
|
00E993 1 ;
|
|
00E993 1 ; Starting from Y=$00:
|
|
00E993 1 ;
|
|
00E993 1 ; first DEY -> $FF
|
|
00E993 1 ; ...
|
|
00E993 1 ; final DEY -> $00
|
|
00E993 1 ; ----------------------------------------------------------------------------
|
|
00E993 1
|
|
00E993 1 88 dey ; $E993: 88
|
|
00E994 1 D0 FA bne FillPpuMemoryWith26_Loop
|
|
00E996 1 ; $E994: D0 FA
|
|
00E996 1
|
|
00E996 1 ; ----------------------------------------------------------------------------
|
|
00E996 1 ; Process sixteen 256-byte blocks.
|
|
00E996 1 ;
|
|
00E996 1 ; The branch returns directly to the PPUDATA write at $E990. Y is already zero
|
|
00E996 1 ; after each completed inner iteration, so the next block again runs 256 times.
|
|
00E996 1 ; ----------------------------------------------------------------------------
|
|
00E996 1
|
|
00E996 1 CA dex ; $E996: CA
|
|
00E997 1 D0 F7 bne FillPpuMemoryWith26_Loop
|
|
00E999 1 ; $E997: D0 F7
|
|
00E999 1
|
|
00E999 1 60 rts ; $E999: 60
|
|
00E99A 1
|
|
00E99A 1 ; ============================================================================
|
|
00E99A 1 ; $E99A-$E9B3
|
|
00E99A 1 ; Decode inline parameters following a caller's JSR instruction.
|
|
00E99A 1 ;
|
|
00E99A 1 ; This routine manipulates two return addresses:
|
|
00E99A 1 ;
|
|
00E99A 1 ; 1. The return address from JSR $E99A.
|
|
00E99A 1 ; 2. The return address belonging to the helper that called $E99A.
|
|
00E99A 1 ;
|
|
00E99A 1 ; It reads two inline parameter bytes through ReadInlineWord, advances the
|
|
00E99A 1 ; outer return address past the inline record, and jumps to that continuation.
|
|
00E99A 1 ;
|
|
00E99A 1 ; ReadInlineWord restores the immediate caller's return address to the stack,
|
|
00E99A 1 ; allowing that helper to return normally after processing the parameters.
|
|
00E99A 1 ; ============================================================================
|
|
00E99A 1
|
|
00E99A 1 ; ----------------------------------------------------------------------------
|
|
00E99A 1 ; Contract:
|
|
00E99A 1 ; Description: Implements Decode Inline Parameters.
|
|
00E99A 1 ; Entry: Registers: A, Y; Memory: $00
|
|
00E99A 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E99A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E99A 1 ; Memory effects: $00, $01
|
|
00E99A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E99A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E99A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 10.
|
|
00E99A 1 ; ----------------------------------------------------------------------------
|
|
00E99A 1 DecodeInlineParameters: ; $E99A
|
|
00E99A 1 68 pla ; $E99A: 68
|
|
00E99B 1 AA tax ; $E99B: AA
|
|
00E99C 1 ; X = low byte of the immediate return address.
|
|
00E99C 1
|
|
00E99C 1 68 pla ; $E99C: 68
|
|
00E99D 1 A8 tay ; $E99D: A8
|
|
00E99E 1 ; Y = high byte of the immediate return address.
|
|
00E99E 1
|
|
00E99E 1 ; ----------------------------------------------------------------------------
|
|
00E99E 1 ; Remove the outer caller's return address and store it as a pointer.
|
|
00E99E 1 ; ----------------------------------------------------------------------------
|
|
00E99E 1
|
|
00E99E 1 68 pla ; $E99E: 68
|
|
00E99F 1 85 00 sta $00 ; $E99F: 85 00
|
|
00E9A1 1
|
|
00E9A1 1 68 pla ; $E9A1: 68
|
|
00E9A2 1 85 01 sta $01 ; $E9A2: 85 01
|
|
00E9A4 1
|
|
00E9A4 1 ; ----------------------------------------------------------------------------
|
|
00E9A4 1 ; Restore the immediate return address and read two bytes following the outer
|
|
00E9A4 1 ; caller's JSR.
|
|
00E9A4 1 ;
|
|
00E9A4 1 ; Exit from ReadInlineWord:
|
|
00E9A4 1 ; X = first inline byte
|
|
00E9A4 1 ; A = second inline byte
|
|
00E9A4 1 ; Y = $03
|
|
00E9A4 1 ; ----------------------------------------------------------------------------
|
|
00E9A4 1
|
|
00E9A4 1 20 B4 E9 jsr ReadInlineWord ; $E9A4: 20 B4 E9
|
|
00E9A7 1
|
|
00E9A7 1 ; ----------------------------------------------------------------------------
|
|
00E9A7 1 ; Advance the outer return pointer by three:
|
|
00E9A7 1 ;
|
|
00E9A7 1 ; one byte for the JSR return-address convention
|
|
00E9A7 1 ; two bytes for the inline parameter record
|
|
00E9A7 1 ; ----------------------------------------------------------------------------
|
|
00E9A7 1
|
|
00E9A7 1 18 clc ; $E9A7: 18
|
|
00E9A8 1
|
|
00E9A8 1 98 tya ; $E9A8: 98
|
|
00E9A9 1 65 00 adc $00 ; $E9A9: 65 00
|
|
00E9AB 1 85 00 sta $00 ; $E9AB: 85 00
|
|
00E9AD 1
|
|
00E9AD 1 90 02 bcc DecodeInlineParameters_Jump
|
|
00E9AF 1 ; $E9AD: 90 02
|
|
00E9AF 1
|
|
00E9AF 1 E6 01 inc $01 ; $E9AF: E6 01
|
|
00E9B1 1
|
|
00E9B1 1 ; ----------------------------------------------------------------------------
|
|
00E9B1 1 ; Continue execution immediately after the inline record.
|
|
00E9B1 1 ; ----------------------------------------------------------------------------
|
|
00E9B1 1
|
|
00E9B1 1 DecodeInlineParameters_Jump: ; $E9B1
|
|
00E9B1 1 6C 00 00 jmp ($0000) ; $E9B1: 6C 00 00
|
|
00E9B4 1
|
|
00E9B4 1 ; ============================================================================
|
|
00E9B4 1 ; $E9B4-$E9C1
|
|
00E9B4 1 ; Restore an immediate caller return address and read a two-byte inline word.
|
|
00E9B4 1 ;
|
|
00E9B4 1 ; Entry:
|
|
00E9B4 1 ; X/Y = low/high bytes of the immediate caller's return address
|
|
00E9B4 1 ; $00/$01 = pointer to the outer caller's return address
|
|
00E9B4 1 ;
|
|
00E9B4 1 ; Exit:
|
|
00E9B4 1 ; X = first byte following the outer caller's JSR
|
|
00E9B4 1 ; A = second byte following the outer caller's JSR
|
|
00E9B4 1 ; Y = $03
|
|
00E9B4 1 ;
|
|
00E9B4 1 ; The initial TYA/PHA and TXA/PHA restore the immediate return address to the
|
|
00E9B4 1 ; stack in the order required by RTS.
|
|
00E9B4 1 ; ============================================================================
|
|
00E9B4 1
|
|
00E9B4 1 ; ----------------------------------------------------------------------------
|
|
00E9B4 1 ; Contract:
|
|
00E9B4 1 ; Description: Implements Read Inline Word.
|
|
00E9B4 1 ; Entry: Registers: A, X, Y; Memory: ($00)
|
|
00E9B4 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E9B4 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E9B4 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00E9B4 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E9B4 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E9B4 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E9B4 1 ; ----------------------------------------------------------------------------
|
|
00E9B4 1 ReadInlineWord: ; $E9B4
|
|
00E9B4 1 98 tya ; $E9B4: 98
|
|
00E9B5 1 48 pha ; $E9B5: 48
|
|
00E9B6 1 ; Restore return-address high byte.
|
|
00E9B6 1
|
|
00E9B6 1 8A txa ; $E9B6: 8A
|
|
00E9B7 1 48 pha ; $E9B7: 48
|
|
00E9B8 1 ; Restore return-address low byte.
|
|
00E9B8 1
|
|
00E9B8 1 A0 01 ldy #$01 ; $E9B8: A0 01
|
|
00E9BA 1
|
|
00E9BA 1 B1 00 lda ($00),y ; $E9BA: B1 00
|
|
00E9BC 1 AA tax ; $E9BC: AA
|
|
00E9BD 1 ; X = first inline parameter.
|
|
00E9BD 1
|
|
00E9BD 1 C8 iny ; $E9BD: C8
|
|
00E9BE 1
|
|
00E9BE 1 B1 00 lda ($00),y ; $E9BE: B1 00
|
|
00E9C0 1 ; A = second inline parameter.
|
|
00E9C0 1
|
|
00E9C0 1 C8 iny ; $E9C0: C8
|
|
00E9C1 1 ; Y = $03.
|
|
00E9C1 1
|
|
00E9C1 1 60 rts ; $E9C1: 60
|
|
00E9C2 1
|
|
00E9C2 1 ; ============================================================================
|
|
00E9C2 1 ; $E9C2-$E9D1
|
|
00E9C2 1 ; Copy a counted inline byte sequence into zero page.
|
|
00E9C2 1 ;
|
|
00E9C2 1 ; Inline record:
|
|
00E9C2 1 ; byte 0 = destination zero-page address
|
|
00E9C2 1 ; byte 1 = byte count
|
|
00E9C2 1 ; remaining bytes = data to copy
|
|
00E9C2 1 ;
|
|
00E9C2 1 ; DecodeInlineParameters returns:
|
|
00E9C2 1 ; X = destination zero-page address
|
|
00E9C2 1 ; A = byte count
|
|
00E9C2 1 ; Y = index of the first data byte
|
|
00E9C2 1 ;
|
|
00E9C2 1 ; Exit:
|
|
00E9C2 1 ; X points immediately after the destination range.
|
|
00E9C2 1 ; ============================================================================
|
|
00E9C2 1
|
|
00E9C2 1 CopyInlineBytesToZeroPage: ; $E9C2
|
|
00E9C2 1 20 9A E9 jsr DecodeInlineParameters ; $E9C2: 20 9A E9
|
|
00E9C5 1
|
|
00E9C5 1 85 04 sta $04 ; $E9C5: 85 04
|
|
00E9C7 1 ; Save byte count.
|
|
00E9C7 1
|
|
00E9C7 1 CopyInlineBytesToZeroPage_Loop: ; $E9C7
|
|
00E9C7 1 B1 00 lda ($00),y ; $E9C7: B1 00
|
|
00E9C9 1 95 00 sta $00,x ; $E9C9: 95 00
|
|
00E9CB 1
|
|
00E9CB 1 C8 iny ; $E9CB: C8
|
|
00E9CC 1 E8 inx ; $E9CC: E8
|
|
00E9CD 1
|
|
00E9CD 1 C6 04 dec $04 ; $E9CD: C6 04
|
|
00E9CF 1 D0 F6 bne CopyInlineBytesToZeroPage_Loop
|
|
00E9D1 1 ; $E9CF: D0 F6
|
|
00E9D1 1
|
|
00E9D1 1 60 rts ; $E9D1: 60
|
|
00E9D2 1
|
|
00E9D2 1 ; ============================================================================
|
|
00E9D2 1 ; $E9D2-$E9DA
|
|
00E9D2 1 ; Set PPUCTRL according to the incoming carry flag.
|
|
00E9D2 1 ;
|
|
00E9D2 1 ; Entry:
|
|
00E9D2 1 ; C = clear -> write $00 to PPUCTRL
|
|
00E9D2 1 ; C = set -> write $04 to PPUCTRL
|
|
00E9D2 1 ;
|
|
00E9D2 1 ; LDA #$00 preserves carry. Three ROL instructions move the incoming carry
|
|
00E9D2 1 ; into bit two of A.
|
|
00E9D2 1 ; ============================================================================
|
|
00E9D2 1
|
|
00E9D2 1 WritePpuControlFromCarry: ; $E9D2
|
|
00E9D2 1 A9 00 lda #$00 ; $E9D2: A9 00
|
|
00E9D4 1
|
|
00E9D4 1 2A rol ; $E9D4: 2A
|
|
00E9D5 1 2A rol ; $E9D5: 2A
|
|
00E9D6 1 2A rol ; $E9D6: 2A
|
|
00E9D7 1
|
|
00E9D7 1 8D 00 20 sta $2000 ; $E9D7: 8D 00 20
|
|
00E9DA 1
|
|
00E9DA 1 60 rts ; $E9DA: 60
|
|
00E9DB 1
|
|
00E9DB 1 ; ============================================================================
|
|
00E9DB 1 ; $E9DB-$E9FB
|
|
00E9DB 1 ; Decode an inline PPU address, update the address shadow in $23/$24, and write
|
|
00E9DB 1 ; the resulting address to PPUADDR.
|
|
00E9DB 1 ;
|
|
00E9DB 1 ; Inline record:
|
|
00E9DB 1 ; byte 0 = low address byte or signed relative offset
|
|
00E9DB 1 ; byte 1 = high address byte
|
|
00E9DB 1 ;
|
|
00E9DB 1 ; Modes:
|
|
00E9DB 1 ;
|
|
00E9DB 1 ; High byte nonzero:
|
|
00E9DB 1 ; Use the decoded X:A pair as an absolute PPU address.
|
|
00E9DB 1 ;
|
|
00E9DB 1 ; High byte zero:
|
|
00E9DB 1 ; Treat the decoded low byte in X as a signed offset and add it to the
|
|
00E9DB 1 ; current shadow PPU address in $23/$24.
|
|
00E9DB 1 ;
|
|
00E9DB 1 ; Exit:
|
|
00E9DB 1 ; $23/$24 = selected PPU address
|
|
00E9DB 1 ; PPUADDR = selected PPU address
|
|
00E9DB 1 ; X restored from $05
|
|
00E9DB 1 ; ============================================================================
|
|
00E9DB 1
|
|
00E9DB 1 ; ----------------------------------------------------------------------------
|
|
00E9DB 1 ; Contract:
|
|
00E9DB 1 ; Description: Implements Set Ppu Address From Inline Record.
|
|
00E9DB 1 ; Entry: Registers: A, X, Y; Memory: $23, $24, mathtemp05
|
|
00E9DB 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00E9DB 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00E9DB 1 ; Memory effects: $05, $24, ppuaddr, $23
|
|
00E9DB 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00E9DB 1 ; comparison, load, or store path and are not a stable API product.
|
|
00E9DB 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00E9DB 1 ; ----------------------------------------------------------------------------
|
|
00E9DB 1 SetPpuAddressFromInlineRecord: ; $E9DB
|
|
00E9DB 1 20 9A E9 jsr DecodeInlineParameters ; $E9DB: 20 9A E9
|
|
00E9DE 1 ; X = first inline byte
|
|
00E9DE 1 ; A = second inline byte
|
|
00E9DE 1
|
|
00E9DE 1 ; ----------------------------------------------------------------------------
|
|
00E9DE 1 ; A nonzero high byte selects the absolute-address path.
|
|
00E9DE 1 ;
|
|
00E9DE 1 ; The decoded values remain:
|
|
00E9DE 1 ; A = address high byte
|
|
00E9DE 1 ; X = address low byte
|
|
00E9DE 1 ; ----------------------------------------------------------------------------
|
|
00E9DE 1
|
|
00E9DE 1 D0 0F bne SetPpuAddress_Write ; $E9DE: D0 0F
|
|
00E9E0 1
|
|
00E9E0 1 ; ----------------------------------------------------------------------------
|
|
00E9E0 1 ; A is zero, so interpret X as a signed relative offset.
|
|
00E9E0 1 ;
|
|
00E9E0 1 ; Preserve the decoded low byte in $05 because X is used during the signed
|
|
00E9E0 1 ; addition.
|
|
00E9E0 1 ; ----------------------------------------------------------------------------
|
|
00E9E0 1 SetRelativePpuAddressFromInlineRecord:
|
|
00E9E0 1 86 05 stx $05 ; $E9E0: 86 05
|
|
00E9E2 1
|
|
00E9E2 1 A0 00 ldy #$00 ; $E9E2: A0 00
|
|
00E9E4 1 ; Default sign-extension byte.
|
|
00E9E4 1
|
|
00E9E4 1 AA tax ; $E9E4: AA
|
|
00E9E5 1 ; A is zero, so X becomes zero.
|
|
00E9E5 1
|
|
00E9E5 1 ; ----------------------------------------------------------------------------
|
|
00E9E5 1 ; Test the sign of the decoded relative offset.
|
|
00E9E5 1 ;
|
|
00E9E5 1 ; DecodeInlineParameters left the low parameter in X before TAX. The flags used
|
|
00E9E5 1 ; by BPL are preserved from TAX, which loaded zero here. Preserve the original
|
|
00E9E5 1 ; instruction sequence byte-for-byte because callers may depend on the helper's
|
|
00E9E5 1 ; exact inline-data convention.
|
|
00E9E5 1 ; ----------------------------------------------------------------------------
|
|
00E9E5 1
|
|
00E9E5 1 10 01 bpl SetPpuAddress_AddOffset ; $E9E5: 10 01
|
|
00E9E7 1
|
|
00E9E7 1 88 dey ; $E9E7: 88
|
|
00E9E8 1 ; Sign extension $FF for a negative offset.
|
|
00E9E8 1
|
|
00E9E8 1 ; ----------------------------------------------------------------------------
|
|
00E9E8 1 ; Add the signed offset to the current PPU address shadow.
|
|
00E9E8 1 ; ----------------------------------------------------------------------------
|
|
00E9E8 1
|
|
00E9E8 1 SetPpuAddress_AddOffset: ; $E9E8
|
|
00E9E8 1 18 clc ; $E9E8: 18
|
|
00E9E9 1
|
|
00E9E9 1 65 23 adc $23 ; $E9E9: 65 23
|
|
00E9EB 1 AA tax ; $E9EB: AA
|
|
00E9EC 1 ; X = resulting low address byte.
|
|
00E9EC 1
|
|
00E9EC 1 98 tya ; $E9EC: 98
|
|
00E9ED 1 65 24 adc $24 ; $E9ED: 65 24
|
|
00E9EF 1 ; A = resulting high address byte.
|
|
00E9EF 1
|
|
00E9EF 1 ; ----------------------------------------------------------------------------
|
|
00E9EF 1 ; Store and write the high address byte first.
|
|
00E9EF 1 ; ----------------------------------------------------------------------------
|
|
00E9EF 1
|
|
00E9EF 1 SetPpuAddress_Write: ; $E9EF
|
|
00E9EF 1 85 24 sta $24 ; $E9EF: 85 24
|
|
00E9F1 1 8D 06 20 sta PPUADDR ; $E9F1: 8D 06 20
|
|
00E9F4 1
|
|
00E9F4 1 ; ----------------------------------------------------------------------------
|
|
00E9F4 1 ; Store and write the low address byte.
|
|
00E9F4 1 ; ----------------------------------------------------------------------------
|
|
00E9F4 1
|
|
00E9F4 1 86 23 stx $23 ; $E9F4: 86 23
|
|
00E9F6 1 8E 06 20 stx PPUADDR ; $E9F6: 8E 06 20
|
|
00E9F9 1
|
|
00E9F9 1 ; ----------------------------------------------------------------------------
|
|
00E9F9 1 ; Restore X from the scratch value at $05.
|
|
00E9F9 1 ; ----------------------------------------------------------------------------
|
|
00E9F9 1
|
|
00E9F9 1 A6 05 ldx MathTemp05 ; $E9F9: A6 05
|
|
00E9FB 1
|
|
00E9FB 1 60 rts ; $E9FB: 60
|
|
00E9FC 1
|
|
00E9FC 1 ; ============================================================================
|
|
00E9FC 1 ; $E9FC-$EA01
|
|
00E9FC 1 ; Write the pending PPU data byte from $25 to PPUDATA.
|
|
00E9FC 1 ;
|
|
00E9FC 1 ; Entry:
|
|
00E9FC 1 ; $25 = byte to write
|
|
00E9FC 1 ;
|
|
00E9FC 1 ; Exit:
|
|
00E9FC 1 ; A = value written
|
|
00E9FC 1 ; ============================================================================
|
|
00E9FC 1
|
|
00E9FC 1 WritePendingPpuByte: ; $E9FC
|
|
00E9FC 1 A5 25 lda $25 ; $E9FC: A5 25
|
|
00E9FE 1 8D 07 20 sta PPUDATA ; $E9FE: 8D 07 20
|
|
00EA01 1 60 rts ; $EA01: 60
|
|
00EA02 1
|
|
00EA02 1 ; ============================================================================
|
|
00EA02 1 ; $EA02-$EA16
|
|
00EA02 1 ; Set a PPU address from inline data, then write a counted inline byte sequence
|
|
00EA02 1 ; to PPUDATA.
|
|
00EA02 1 ;
|
|
00EA02 1 ; Inline record structure:
|
|
00EA02 1 ;
|
|
00EA02 1 ; bytes 0-1:
|
|
00EA02 1 ; PPU address record consumed by SetPpuAddressFromInlineRecord
|
|
00EA02 1 ;
|
|
00EA02 1 ; byte 2:
|
|
00EA02 1 ; transfer count returned in X by DecodeInlineParameters
|
|
00EA02 1 ;
|
|
00EA02 1 ; byte 3 onward:
|
|
00EA02 1 ; data bytes written to PPUDATA
|
|
00EA02 1 ;
|
|
00EA02 1 ; Entry:
|
|
00EA02 1 ; X may contain caller state that must be restored before return.
|
|
00EA02 1 ;
|
|
00EA02 1 ; Exit:
|
|
00EA02 1 ; X restored from $05
|
|
00EA02 1 ; Y points back to the final byte consumed from the inline record
|
|
00EA02 1 ; ============================================================================
|
|
00EA02 1
|
|
00EA02 1 WriteInlinePpuBlock: ; $EA02
|
|
00EA02 1 20 E0 E9 jsr SetRelativePpuAddressFromInlineRecord
|
|
00EA05 1 ; $EA02: 20 E0 E9
|
|
00EA05 1
|
|
00EA05 1 ; ----------------------------------------------------------------------------
|
|
00EA05 1 ; Preserve X while the inline record is decoded.
|
|
00EA05 1 ; ----------------------------------------------------------------------------
|
|
00EA05 1
|
|
00EA05 1 ; ----------------------------------------------------------------------------
|
|
00EA05 1 ; Contract:
|
|
00EA05 1 ; Description: Internal PPU block writer after PPUADDR has already been set.
|
|
00EA05 1 ; Entry: X = caller state; inline transfer record follows caller.
|
|
00EA05 1 ; Returns/products: PPUDATA written; X restored from scratch state.
|
|
00EA05 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EA05 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00EA05 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EA05 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EA05 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00EA05 1 ; ----------------------------------------------------------------------------
|
|
00EA05 1 WriteInlinePpuBlockAfterAddress:
|
|
00EA05 1 86 05 stx MathTemp05 ; $EA05: 86 05
|
|
00EA07 1
|
|
00EA07 1 ; ----------------------------------------------------------------------------
|
|
00EA07 1 ; Decode the following inline parameter record.
|
|
00EA07 1 ;
|
|
00EA07 1 ; DecodeInlineParameters returns:
|
|
00EA07 1 ; X = transfer count
|
|
00EA07 1 ; A = first data byte
|
|
00EA07 1 ; Y = index into the remaining inline data
|
|
00EA07 1 ; ----------------------------------------------------------------------------
|
|
00EA07 1
|
|
00EA07 1 20 9A E9 jsr DecodeInlineParameters ; $EA07: 20 9A E9
|
|
00EA0A 1
|
|
00EA0A 1 ; ----------------------------------------------------------------------------
|
|
00EA0A 1 ; Write the first data byte returned directly in A.
|
|
00EA0A 1 ; ----------------------------------------------------------------------------
|
|
00EA0A 1
|
|
00EA0A 1 WriteInlinePpuBlock_Loop: ; $EA0A
|
|
00EA0A 1 8D 07 20 sta PPUDATA ; $EA0A: 8D 07 20
|
|
00EA0D 1
|
|
00EA0D 1 ; ----------------------------------------------------------------------------
|
|
00EA0D 1 ; Load the next inline byte, advance the source index, and count down the
|
|
00EA0D 1 ; number of bytes remaining.
|
|
00EA0D 1 ;
|
|
00EA0D 1 ; On the final iteration, the loaded byte is not written because X reaches
|
|
00EA0D 1 ; zero immediately after the load. DEY then restores Y to the last byte that
|
|
00EA0D 1 ; was actually consumed.
|
|
00EA0D 1 ; ----------------------------------------------------------------------------
|
|
00EA0D 1
|
|
00EA0D 1 B1 00 lda ($00),y ; $EA0D: B1 00
|
|
00EA0F 1 C8 iny ; $EA0F: C8
|
|
00EA10 1
|
|
00EA10 1 CA dex ; $EA10: CA
|
|
00EA11 1 D0 F7 bne WriteInlinePpuBlock_Loop
|
|
00EA13 1 ; $EA11: D0 F7
|
|
00EA13 1
|
|
00EA13 1 ; ----------------------------------------------------------------------------
|
|
00EA13 1 ; Restore Y and X to the state expected by the inline dispatcher.
|
|
00EA13 1 ; ----------------------------------------------------------------------------
|
|
00EA13 1
|
|
00EA13 1 88 dey ; $EA13: 88
|
|
00EA14 1
|
|
00EA14 1 A6 05 ldx MathTemp05 ; $EA14: A6 05
|
|
00EA16 1
|
|
00EA16 1 60 rts ; $EA16: 60
|
|
00EA17 1
|
|
00EA17 1 ; ============================================================================
|
|
00EA17 1 ; $EA17-$EA3D
|
|
00EA17 1 ; Copy a counted inline record into the display buffer at $0300,X.
|
|
00EA17 1 ;
|
|
00EA17 1 ; The routine first calls $EA3E to reserve or initialize a display-buffer
|
|
00EA17 1 ; record. It then removes its caller's return address from the stack and uses
|
|
00EA17 1 ; that address as a pointer to inline data.
|
|
00EA17 1 ;
|
|
00EA17 1 ; Inline record:
|
|
00EA17 1 ; byte 0 = number of data bytes
|
|
00EA17 1 ; byte 1...N = bytes copied into $0300,X
|
|
00EA17 1 ;
|
|
00EA17 1 ; After copying the record, the routine rebuilds the return address so RTS
|
|
00EA17 1 ; resumes execution immediately after the inline data.
|
|
00EA17 1 ;
|
|
00EA17 1 ; Entry:
|
|
00EA17 1 ; A, X, Y and carry contain parameters consumed by $EA3E.
|
|
00EA17 1 ;
|
|
00EA17 1 ; Exit:
|
|
00EA17 1 ; X points immediately after the copied display-buffer bytes.
|
|
00EA17 1 ; ============================================================================
|
|
00EA17 1 PPUWriteString:
|
|
00EA17 1 ; ----------------------------------------------------------------------------
|
|
00EA17 1 ; Contract:
|
|
00EA17 1 ; Description: Copies Inline Display Record.
|
|
00EA17 1 ; Entry: Registers: A, X, Y; Memory: ($26), $26, $04, $27
|
|
00EA17 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00EA17 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EA17 1 ; Memory effects: $26, $27, $04, $0300
|
|
00EA17 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EA17 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EA17 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 12.
|
|
00EA17 1 ; ----------------------------------------------------------------------------
|
|
00EA17 1 CopyInlineDisplayRecord: ; $EA17
|
|
00EA17 1 20 3E EA jsr AllocateDisplayBufferRecord ; $EA17: 20 3E EA
|
|
00EA1A 1 ; Reserve or initialize the destination record.
|
|
00EA1A 1 ; Returns the destination offset in X.
|
|
00EA1A 1
|
|
00EA1A 1 ; ----------------------------------------------------------------------------
|
|
00EA1A 1 ; Remove the caller's return address from the stack.
|
|
00EA1A 1 ;
|
|
00EA1A 1 ; JSR stores the address of the final JSR operand byte. Therefore, inline byte
|
|
00EA1A 1 ; zero is found at offset one from the saved address.
|
|
00EA1A 1 ; ----------------------------------------------------------------------------
|
|
00EA1A 1
|
|
00EA1A 1 68 pla ; $EA1A: 68
|
|
00EA1B 1 85 26 sta $26 ; $EA1B: 85 26
|
|
00EA1D 1 ; Saved return-address low byte.
|
|
00EA1D 1
|
|
00EA1D 1 68 pla ; $EA1D: 68
|
|
00EA1E 1 85 27 sta $27 ; $EA1E: 85 27
|
|
00EA20 1 ; Saved return-address high byte.
|
|
00EA20 1
|
|
00EA20 1 ; ----------------------------------------------------------------------------
|
|
00EA20 1 ; Read the inline byte count.
|
|
00EA20 1 ; ----------------------------------------------------------------------------
|
|
00EA20 1
|
|
00EA20 1 A0 01 ldy #$01 ; $EA20: A0 01
|
|
00EA22 1
|
|
00EA22 1 B1 26 lda ($26),y ; $EA22: B1 26
|
|
00EA24 1 85 04 sta $04 ; $EA24: 85 04
|
|
00EA26 1 ; Number of data bytes to copy.
|
|
00EA26 1
|
|
00EA26 1 ; ----------------------------------------------------------------------------
|
|
00EA26 1 ; Copy the inline data into the display buffer at $0300,X.
|
|
00EA26 1 ; ----------------------------------------------------------------------------
|
|
00EA26 1
|
|
00EA26 1 CopyInlineDisplayRecord_Loop: ; $EA26
|
|
00EA26 1 C8 iny ; $EA26: C8
|
|
00EA27 1 ; Advance to the next inline data byte.
|
|
00EA27 1
|
|
00EA27 1 B1 26 lda ($26),y ; $EA27: B1 26
|
|
00EA29 1 9D 00 03 sta $0300,x ; $EA29: 9D 00 03
|
|
00EA2C 1
|
|
00EA2C 1 E8 inx ; $EA2C: E8
|
|
00EA2D 1 ; Advance the destination offset.
|
|
00EA2D 1
|
|
00EA2D 1 C6 04 dec $04 ; $EA2D: C6 04
|
|
00EA2F 1 D0 F5 bne CopyInlineDisplayRecord_Loop
|
|
00EA31 1 ; $EA2F: D0 F5
|
|
00EA31 1
|
|
00EA31 1 ; ----------------------------------------------------------------------------
|
|
00EA31 1 ; Advance the saved return address past the complete inline record.
|
|
00EA31 1 ;
|
|
00EA31 1 ; Y now equals:
|
|
00EA31 1 ;
|
|
00EA31 1 ; byte count + 1
|
|
00EA31 1 ;
|
|
00EA31 1 ; Adding Y to the original return address produces the address of the final
|
|
00EA31 1 ; inline byte. RTS will increment that address and resume at the instruction
|
|
00EA31 1 ; immediately following the inline record.
|
|
00EA31 1 ; ----------------------------------------------------------------------------
|
|
00EA31 1
|
|
00EA31 1 18 clc ; $EA31: 18
|
|
00EA32 1
|
|
00EA32 1 98 tya ; $EA32: 98
|
|
00EA33 1 65 26 adc $26 ; $EA33: 65 26
|
|
00EA35 1 A8 tay ; $EA35: A8
|
|
00EA36 1 ; Y = adjusted return-address low byte.
|
|
00EA36 1
|
|
00EA36 1 ; ----------------------------------------------------------------------------
|
|
00EA36 1 ; $04 is zero after the copy loop. ADC therefore propagates only carry into
|
|
00EA36 1 ; the saved return-address high byte.
|
|
00EA36 1 ; ----------------------------------------------------------------------------
|
|
00EA36 1
|
|
00EA36 1 A5 04 lda $04 ; $EA36: A5 04
|
|
00EA38 1 ; A = $00.
|
|
00EA38 1
|
|
00EA38 1 65 27 adc $27 ; $EA38: 65 27
|
|
00EA3A 1 ; A = adjusted return-address high byte.
|
|
00EA3A 1
|
|
00EA3A 1 ; ----------------------------------------------------------------------------
|
|
00EA3A 1 ; Rebuild the adjusted return address on the stack.
|
|
00EA3A 1 ;
|
|
00EA3A 1 ; RTS pulls low byte first, then high byte, so the high byte is pushed first.
|
|
00EA3A 1 ; ----------------------------------------------------------------------------
|
|
00EA3A 1
|
|
00EA3A 1 48 pha ; $EA3A: 48
|
|
00EA3B 1 ; Push adjusted high byte.
|
|
00EA3B 1
|
|
00EA3B 1 98 tya ; $EA3B: 98
|
|
00EA3C 1 48 pha ; $EA3C: 48
|
|
00EA3D 1 ; Push adjusted low byte.
|
|
00EA3D 1
|
|
00EA3D 1 60 rts ; $EA3D: 60
|
|
00EA3E 1 ; Resume after the inline record.
|
|
00EA3E 1
|
|
00EA3E 1 ; ============================================================================
|
|
00EA3E 1 ; $EA3E-$EA62
|
|
00EA3E 1 ; Allocate and initialize a variable-length record in the display buffer.
|
|
00EA3E 1 ;
|
|
00EA3E 1 ; Entry:
|
|
00EA3E 1 ; A = record parameter stored at offset +1
|
|
00EA3E 1 ; X = record parameter stored at offset +2
|
|
00EA3E 1 ; Y = payload length
|
|
00EA3E 1 ; C = Boolean flag encoded at offset +3
|
|
00EA3E 1 ; $3E = current display-buffer write offset
|
|
00EA3E 1 ;
|
|
00EA3E 1 ; Record layout:
|
|
00EA3E 1 ;
|
|
00EA3E 1 ; +0 = payload length
|
|
00EA3E 1 ; +1 = incoming A
|
|
00EA3E 1 ; +2 = incoming X
|
|
00EA3E 1 ; +3 = incoming carry encoded as $00 or $04
|
|
00EA3E 1 ; +4 = beginning of payload
|
|
00EA3E 1 ;
|
|
00EA3E 1 ; Exit:
|
|
00EA3E 1 ; X = payload destination offset
|
|
00EA3E 1 ; $3E = next free record offset
|
|
00EA3E 1 ; ============================================================================
|
|
00EA3E 1
|
|
00EA3E 1 ; ----------------------------------------------------------------------------
|
|
00EA3E 1 ; Contract:
|
|
00EA3E 1 ; Description: Implements Allocate Display Buffer Record.
|
|
00EA3E 1 ; Entry: Registers: A, X, Y; Memory: $3e, $06, $05
|
|
00EA3E 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00EA3E 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EA3E 1 ; Memory effects: $05, $06, $0301, $0302, $0303, $0300, $3e
|
|
00EA3E 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EA3E 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EA3E 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 11.
|
|
00EA3E 1 ; ----------------------------------------------------------------------------
|
|
00EA3E 1 AllocateDisplayBufferRecord: ; $EA3E
|
|
00EA3E 1 84 05 sty $05 ; $EA3E: 84 05
|
|
00EA40 1 ; Save payload length.
|
|
00EA40 1
|
|
00EA40 1 A0 00 ldy #$00 ; $EA40: A0 00
|
|
00EA42 1 84 06 sty $06 ; $EA42: 84 06
|
|
00EA44 1 ; Clear flag accumulator without changing C.
|
|
00EA44 1
|
|
00EA44 1 A4 3E ldy PpuQueueOffset ; $EA44: A4 3E
|
|
00EA46 1 ; Y = current record offset.
|
|
00EA46 1
|
|
00EA46 1 ; ----------------------------------------------------------------------------
|
|
00EA46 1 ; Store the caller parameters.
|
|
00EA46 1 ; ----------------------------------------------------------------------------
|
|
00EA46 1
|
|
00EA46 1 99 01 03 sta $0301,y ; $EA46: 99 01 03
|
|
00EA49 1 ; Record byte +1 = incoming A.
|
|
00EA49 1
|
|
00EA49 1 8A txa ; $EA49: 8A
|
|
00EA4A 1 99 02 03 sta $0302,y ; $EA4A: 99 02 03
|
|
00EA4D 1 ; Record byte +2 = incoming X.
|
|
00EA4D 1
|
|
00EA4D 1 ; ----------------------------------------------------------------------------
|
|
00EA4D 1 ; Encode incoming carry as bit two:
|
|
00EA4D 1 ;
|
|
00EA4D 1 ; C clear -> $00
|
|
00EA4D 1 ; C set -> $04
|
|
00EA4D 1 ;
|
|
00EA4D 1 ; LDA preserves carry. Starting from zero, three ROL instructions move the
|
|
00EA4D 1 ; incoming carry into bit two.
|
|
00EA4D 1 ; ----------------------------------------------------------------------------
|
|
00EA4D 1
|
|
00EA4D 1 A5 06 lda $06 ; $EA4D: A5 06
|
|
00EA4F 1 2A rol ; $EA4F: 2A
|
|
00EA50 1 2A rol ; $EA50: 2A
|
|
00EA51 1 2A rol ; $EA51: 2A
|
|
00EA52 1
|
|
00EA52 1 99 03 03 sta $0303,y ; $EA52: 99 03 03
|
|
00EA55 1 ; Record byte +3 = encoded flag.
|
|
00EA55 1
|
|
00EA55 1 ; ----------------------------------------------------------------------------
|
|
00EA55 1 ; Store the payload length as record byte zero.
|
|
00EA55 1 ; ----------------------------------------------------------------------------
|
|
00EA55 1
|
|
00EA55 1 A5 05 lda $05 ; $EA55: A5 05
|
|
00EA57 1 99 00 03 sta $0300,y ; $EA57: 99 00 03
|
|
00EA5A 1
|
|
00EA5A 1 ; ----------------------------------------------------------------------------
|
|
00EA5A 1 ; Calculate the payload destination:
|
|
00EA5A 1 ;
|
|
00EA5A 1 ; X = record offset + 4
|
|
00EA5A 1 ; ----------------------------------------------------------------------------
|
|
00EA5A 1
|
|
00EA5A 1 98 tya ; $EA5A: 98
|
|
00EA5B 1 69 04 adc #$04 ; $EA5B: 69 04
|
|
00EA5D 1 AA tax ; $EA5D: AA
|
|
00EA5E 1 ; X points to the payload area.
|
|
00EA5E 1 ;
|
|
00EA5E 1 ; Carry is normally clear after the third ROL:
|
|
00EA5E 1 ; the original carry has moved into bit two.
|
|
00EA5E 1
|
|
00EA5E 1 ; ----------------------------------------------------------------------------
|
|
00EA5E 1 ; Calculate the next free record offset:
|
|
00EA5E 1 ;
|
|
00EA5E 1 ; $3E = payload offset + payload length
|
|
00EA5E 1 ; ----------------------------------------------------------------------------
|
|
00EA5E 1
|
|
00EA5E 1 65 05 adc $05 ; $EA5E: 65 05
|
|
00EA60 1 85 3E sta PpuQueueOffset ; $EA60: 85 3E
|
|
00EA62 1
|
|
00EA62 1 60 rts ; $EA62: 60
|
|
00EA63 1
|
|
00EA63 1 ; ============================================================================
|
|
00EA63 1 ; $EA63-$EAAE
|
|
00EA63 1 ; Decode and render an inline stream of PPU transfer records.
|
|
00EA63 1 ;
|
|
00EA63 1 ; The routine obtains an inline pointer through DecodeInlineParameters and
|
|
00EA63 1 ; processes records until a zero terminator is encountered.
|
|
00EA63 1 ;
|
|
00EA63 1 ; Initial decoded values:
|
|
00EA63 1 ; X = stream pointer low byte
|
|
00EA63 1 ; A = stream pointer high byte
|
|
00EA63 1 ;
|
|
00EA63 1 ; Stream record format:
|
|
00EA63 1 ;
|
|
00EA63 1 ; byte 0:
|
|
00EA63 1 ; PPU address high byte
|
|
00EA63 1 ;
|
|
00EA63 1 ; byte 1:
|
|
00EA63 1 ; PPU address low byte
|
|
00EA63 1 ;
|
|
00EA63 1 ; byte 2:
|
|
00EA63 1 ; control byte
|
|
00EA63 1 ;
|
|
00EA63 1 ; remaining bytes:
|
|
00EA63 1 ; one literal byte or one repeated byte, according to the control byte
|
|
00EA63 1 ;
|
|
00EA63 1 ; A zero byte at the start of the next record terminates the stream.
|
|
00EA63 1 ; ============================================================================
|
|
00EA63 1
|
|
00EA63 1 ; ----------------------------------------------------------------------------
|
|
00EA63 1 ; Contract:
|
|
00EA63 1 ; Description: Processes Inline Ppu Stream.
|
|
00EA63 1 ; Entry: Registers: A, X, Y; Memory: ($08), $08, $09, $2002
|
|
00EA63 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00EA63 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EA63 1 ; Memory effects: $09, $08, $2006, $2000, $2007
|
|
00EA63 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EA63 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EA63 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00EA63 1 ; ----------------------------------------------------------------------------
|
|
00EA63 1 ProcessInlinePpuStream: ; $EA63
|
|
00EA63 1 20 9A E9 jsr DecodeInlineParameters ; $EA63: 20 9A E9
|
|
00EA66 1 ; X = stream-pointer low byte
|
|
00EA66 1 ; A = stream-pointer high byte
|
|
00EA66 1
|
|
00EA66 1 85 09 sta $09 ; $EA66: 85 09
|
|
00EA68 1 ; Save stream-pointer high byte.
|
|
00EA68 1
|
|
00EA68 1 86 08 stx $08 ; $EA68: 86 08
|
|
00EA6A 1 ; Save stream-pointer low byte.
|
|
00EA6A 1
|
|
00EA6A 1 ; ----------------------------------------------------------------------------
|
|
00EA6A 1 ; A nonzero high byte skips directly to the initial terminator check.
|
|
00EA6A 1 ;
|
|
00EA6A 1 ; A zero high byte falls through and processes the first record using A as the
|
|
00EA6A 1 ; first PPU address byte. This dual entry behavior is intentional.
|
|
00EA6A 1 ; ----------------------------------------------------------------------------
|
|
00EA6A 1
|
|
00EA6A 1 D0 37 bne ProcessInlinePpuStream_CheckRecord
|
|
00EA6C 1 ; $EA6A: D0 37
|
|
00EA6C 1
|
|
00EA6C 1 ; ============================================================================
|
|
00EA6C 1 ; $EA6C
|
|
00EA6C 1 ; Process one PPU transfer record.
|
|
00EA6C 1 ; ============================================================================
|
|
00EA6C 1
|
|
00EA6C 1 ProcessInlinePpuStream_Record: ; $EA6C
|
|
00EA6C 1 8D 06 20 sta $2006 ; $EA6C: 8D 06 20
|
|
00EA6F 1 ; Write PPU address high byte.
|
|
00EA6F 1
|
|
00EA6F 1 C8 iny ; $EA6F: C8
|
|
00EA70 1
|
|
00EA70 1 B1 08 lda ($08),y ; $EA70: B1 08
|
|
00EA72 1 8D 06 20 sta $2006 ; $EA72: 8D 06 20
|
|
00EA75 1 ; Write PPU address low byte.
|
|
00EA75 1
|
|
00EA75 1 ; ----------------------------------------------------------------------------
|
|
00EA75 1 ; Read and preserve the record control byte.
|
|
00EA75 1 ; ----------------------------------------------------------------------------
|
|
00EA75 1
|
|
00EA75 1 C8 iny ; $EA75: C8
|
|
00EA76 1
|
|
00EA76 1 B1 08 lda ($08),y ; $EA76: B1 08
|
|
00EA78 1 0A asl ; $EA78: 0A
|
|
00EA79 1 48 pha ; $EA79: 48
|
|
00EA7A 1 ; Preserve shifted control byte.
|
|
00EA7A 1
|
|
00EA7A 1 ; ----------------------------------------------------------------------------
|
|
00EA7A 1 ; Derive PPUCTRL bit two from the original control-byte high bit.
|
|
00EA7A 1 ;
|
|
00EA7A 1 ; After ASL, the original bit seven is in carry. Beginning with zero, three
|
|
00EA7A 1 ; ROL instructions move that carry into bit two.
|
|
00EA7A 1 ; ----------------------------------------------------------------------------
|
|
00EA7A 1
|
|
00EA7A 1 A9 00 lda #$00 ; $EA7A: A9 00
|
|
00EA7C 1 2A rol ; $EA7C: 2A
|
|
00EA7D 1 2A rol ; $EA7D: 2A
|
|
00EA7E 1 2A rol ; $EA7E: 2A
|
|
00EA7F 1
|
|
00EA7F 1 8D 00 20 sta $2000 ; $EA7F: 8D 00 20
|
|
00EA82 1 ; Select PPU address increment mode.
|
|
00EA82 1
|
|
00EA82 1 ; ----------------------------------------------------------------------------
|
|
00EA82 1 ; Restore and further decode the shifted control byte.
|
|
00EA82 1 ; ----------------------------------------------------------------------------
|
|
00EA82 1
|
|
00EA82 1 68 pla ; $EA82: 68
|
|
00EA83 1 0A asl ; $EA83: 0A
|
|
00EA84 1 ; Carry receives the next control flag.
|
|
00EA84 1
|
|
00EA84 1 90 03 bcc ProcessInlinePpuStream_DecodeCount
|
|
00EA86 1 ; $EA84: 90 03
|
|
00EA86 1
|
|
00EA86 1 ; ----------------------------------------------------------------------------
|
|
00EA86 1 ; Repeated-value mode.
|
|
00EA86 1 ;
|
|
00EA86 1 ; Set bit one in the working control byte and advance Y so the same source byte
|
|
00EA86 1 ; can be written repeatedly.
|
|
00EA86 1 ; ----------------------------------------------------------------------------
|
|
00EA86 1
|
|
00EA86 1 09 02 ora #$02 ; $EA86: 09 02
|
|
00EA88 1 C8 iny ; $EA88: C8
|
|
00EA89 1
|
|
00EA89 1 ; ----------------------------------------------------------------------------
|
|
00EA89 1 ; Divide the working control byte by four.
|
|
00EA89 1 ;
|
|
00EA89 1 ; Exit:
|
|
00EA89 1 ; X = transfer count
|
|
00EA89 1 ; Carry = literal/repeated source-advance flag
|
|
00EA89 1 ; ----------------------------------------------------------------------------
|
|
00EA89 1
|
|
00EA89 1 ProcessInlinePpuStream_DecodeCount: ; $EA89
|
|
00EA89 1 4A lsr ; $EA89: 4A
|
|
00EA8A 1 4A lsr ; $EA8A: 4A
|
|
00EA8B 1 AA tax ; $EA8B: AA
|
|
00EA8C 1
|
|
00EA8C 1 ; ============================================================================
|
|
00EA8C 1 ; $EA8C
|
|
00EA8C 1 ; Write the current record's payload to PPUDATA.
|
|
00EA8C 1 ;
|
|
00EA8C 1 ; Carry controls whether the source pointer advances for each output byte:
|
|
00EA8C 1 ;
|
|
00EA8C 1 ; C clear -> increment Y before reading
|
|
00EA8C 1 ; C set -> reuse the same source byte
|
|
00EA8C 1 ; ============================================================================
|
|
00EA8C 1
|
|
00EA8C 1 ProcessInlinePpuStream_WriteLoop: ; $EA8C
|
|
00EA8C 1 B0 01 bcs ProcessInlinePpuStream_Write
|
|
00EA8E 1 ; $EA8C: B0 01
|
|
00EA8E 1
|
|
00EA8E 1 C8 iny ; $EA8E: C8
|
|
00EA8F 1
|
|
00EA8F 1 ProcessInlinePpuStream_Write: ; $EA8F
|
|
00EA8F 1 B1 08 lda ($08),y ; $EA8F: B1 08
|
|
00EA91 1 8D 07 20 sta $2007 ; $EA91: 8D 07 20
|
|
00EA94 1
|
|
00EA94 1 CA dex ; $EA94: CA
|
|
00EA95 1 D0 F5 bne ProcessInlinePpuStream_WriteLoop
|
|
00EA97 1 ; $EA95: D0 F5
|
|
00EA97 1
|
|
00EA97 1 ; ----------------------------------------------------------------------------
|
|
00EA97 1 ; Advance the stream pointer past the record just processed.
|
|
00EA97 1 ;
|
|
00EA97 1 ; Y is the final source index consumed. Increment it, then add it to $08/$09.
|
|
00EA97 1 ; ----------------------------------------------------------------------------
|
|
00EA97 1
|
|
00EA97 1 C8 iny ; $EA97: C8
|
|
00EA98 1
|
|
00EA98 1 18 clc ; $EA98: 18
|
|
00EA99 1
|
|
00EA99 1 98 tya ; $EA99: 98
|
|
00EA9A 1 65 08 adc $08 ; $EA9A: 65 08
|
|
00EA9C 1 85 08 sta $08 ; $EA9C: 85 08
|
|
00EA9E 1
|
|
00EA9E 1 8A txa ; $EA9E: 8A
|
|
00EA9F 1 ; X is zero after the transfer loop.
|
|
00EA9F 1
|
|
00EA9F 1 65 09 adc $09 ; $EA9F: 65 09
|
|
00EAA1 1 85 09 sta $09 ; $EAA1: 85 09
|
|
00EAA3 1
|
|
00EAA3 1 ; ============================================================================
|
|
00EAA3 1 ; $EAA3
|
|
00EAA3 1 ; Check the next record for the zero terminator.
|
|
00EAA3 1 ; ============================================================================
|
|
00EAA3 1
|
|
00EAA3 1 ProcessInlinePpuStream_CheckRecord: ; $EAA3
|
|
00EAA3 1 AE 02 20 ldx $2002 ; $EAA3: AE 02 20
|
|
00EAA6 1 ; Reset PPU address latch.
|
|
00EAA6 1 ; The status value itself is unused.
|
|
00EAA6 1
|
|
00EAA6 1 A0 00 ldy #$00 ; $EAA6: A0 00
|
|
00EAA8 1
|
|
00EAA8 1 B1 08 lda ($08),y ; $EAA8: B1 08
|
|
00EAAA 1 D0 C0 bne ProcessInlinePpuStream_Record
|
|
00EAAC 1 ; $EAAA: D0 C0
|
|
00EAAC 1
|
|
00EAAC 1 ; ----------------------------------------------------------------------------
|
|
00EAAC 1 ; End of stream.
|
|
00EAAC 1 ;
|
|
00EAAC 1 ; Return Y=$03, matching the inline-record convention used by nearby helpers.
|
|
00EAAC 1 ; ----------------------------------------------------------------------------
|
|
00EAAC 1
|
|
00EAAC 1 A0 03 ldy #$03 ; $EAAC: A0 03
|
|
00EAAE 1 60 rts ; $EAAE: 60
|
|
00EAAF 1
|
|
00EAAF 1 ; ============================================================================
|
|
00EAAF 1 ; $EAAF-$EAF4
|
|
00EAAF 1 ; Run a complete display or screen transition.
|
|
00EAAF 1 ;
|
|
00EAAF 1 ; Entry:
|
|
00EAAF 1 ; Y = $03
|
|
00EAAF 1 ;
|
|
00EAAF 1 ; The preceding PPU stream routine returns with Y set to $03. This routine
|
|
00EAAF 1 ; saves that value in $E4 and uses it during the transition.
|
|
00EAAF 1 ; ============================================================================
|
|
00EAAF 1
|
|
00EAAF 1 RunDisplayTransition: ; $EAAF
|
|
00EAAF 1 84 E4 sty $E4 ; $EAAF: 84 E4
|
|
00EAB1 1
|
|
00EAB1 1 20 66 EB jsr DispatchNextQueuedEvent ; $EAB1: 20 66 EB
|
|
00EAB4 1 20 4C EB jsr SelectObjectEventBank0 ; $EAB4: 20 4C EB
|
|
00EAB7 1 20 9D EB jsr InitializeQueuedEventSystem ; $EAB7: 20 9D EB
|
|
00EABA 1
|
|
00EABA 1 20 6C E9 jsr DisablePpuRendering ; $EABA: 20 6C E9
|
|
00EABD 1
|
|
00EABD 1 ; ----------------------------------------------------------------------------
|
|
00EABD 1 ; Set PPU address $2324.
|
|
00EABD 1 ; ----------------------------------------------------------------------------
|
|
00EABD 1
|
|
00EABD 1 20 DB E9 jsr SetPpuAddressFromInlineRecord
|
|
00EAC0 1 ; $EABD: 20 DB E9
|
|
00EAC0 1
|
|
00EAC0 1 24 23 .byte $24,$23 ; $EAC0-$EAC1
|
|
00EAC2 1
|
|
00EAC2 1 A5 E4 lda $E4 ; $EAC2: A5 E4
|
|
00EAC4 1 20 00 EB jsr WriteGeneratedPpuWord ; $EAC4: 20 00 EB
|
|
00EAC7 1
|
|
00EAC7 1 ; ----------------------------------------------------------------------------
|
|
00EAC7 1 ; Set PPU address $2B24.
|
|
00EAC7 1 ; ----------------------------------------------------------------------------
|
|
00EAC7 1
|
|
00EAC7 1 20 DB E9 jsr SetPpuAddressFromInlineRecord
|
|
00EACA 1 ; $EAC7: 20 DB E9
|
|
00EACA 1
|
|
00EACA 1 24 2B .byte $24,$2B ; $EACA-$EACB
|
|
00EACC 1
|
|
00EACC 1 A5 E4 lda $E4 ; $EACC: A5 E4
|
|
00EACE 1 20 00 EB jsr WriteGeneratedPpuWord ; $EACE: 20 00 EB
|
|
00EAD1 1
|
|
00EAD1 1 ; ----------------------------------------------------------------------------
|
|
00EAD1 1 ; Set PPU address $2337.
|
|
00EAD1 1 ; ----------------------------------------------------------------------------
|
|
00EAD1 1
|
|
00EAD1 1 20 DB E9 jsr SetPpuAddressFromInlineRecord
|
|
00EAD4 1 ; $EAD1: 20 DB E9
|
|
00EAD4 1
|
|
00EAD4 1 37 23 .byte $37,$23 ; $EAD4-$EAD5
|
|
00EAD6 1
|
|
00EAD6 1 20 F5 EA jsr WriteFixedPpuSequence ; $EAD6: 20 F5 EA
|
|
00EAD9 1
|
|
00EAD9 1 ; ----------------------------------------------------------------------------
|
|
00EAD9 1 ; Set PPU address $2B37.
|
|
00EAD9 1 ; ----------------------------------------------------------------------------
|
|
00EAD9 1
|
|
00EAD9 1 20 DB E9 jsr SetPpuAddressFromInlineRecord
|
|
00EADC 1 ; $EAD9: 20 DB E9
|
|
00EADC 1
|
|
00EADC 1 37 2B .byte $37,$2B ; $EADC-$EADD
|
|
00EADE 1
|
|
00EADE 1 20 F5 EA jsr WriteFixedPpuSequence ; $EADE: 20 F5 EA
|
|
00EAE1 1
|
|
00EAE1 1 ; ----------------------------------------------------------------------------
|
|
00EAE1 1 ; Initialize the next transition phase.
|
|
00EAE1 1 ; ----------------------------------------------------------------------------
|
|
00EAE1 1
|
|
00EAE1 1 A9 0A lda #$0A ; $EAE1: A9 0A
|
|
00EAE3 1 85 DE sta PpuMaskShadow ; $EAE3: 85 DE
|
|
00EAE5 1
|
|
00EAE5 1 ; ----------------------------------------------------------------------------
|
|
00EAE5 1 ; Reset the PPU address latch, enable NMI, and wait for a frame.
|
|
00EAE5 1 ; ----------------------------------------------------------------------------
|
|
00EAE5 1
|
|
00EAE5 1 20 78 E9 jsr EnableNmiAndWaitForFrame
|
|
00EAE8 1 ; $EAE5: 20 78 E9
|
|
00EAE8 1
|
|
00EAE8 1 ; ----------------------------------------------------------------------------
|
|
00EAE8 1 ; Perform two waits using delay value $FF.
|
|
00EAE8 1 ; ----------------------------------------------------------------------------
|
|
00EAE8 1
|
|
00EAE8 1 A9 FF lda #$FF ; $EAE8: A9 FF
|
|
00EAEA 1 20 41 EB jsr StoreObjectEventBankValue ; $EAEA: 20 41 EB
|
|
00EAED 1
|
|
00EAED 1 A9 FF lda #$FF ; $EAED: A9 FF
|
|
00EAEF 1 20 41 EB jsr StoreObjectEventBankValue ; $EAEF: 20 41 EB
|
|
00EAF2 1
|
|
00EAF2 1 ; ----------------------------------------------------------------------------
|
|
00EAF2 1 ; Transfer to the common display-transition continuation.
|
|
00EAF2 1 ; ----------------------------------------------------------------------------
|
|
00EAF2 1
|
|
00EAF2 1 4C 0B C4 jmp Reset ; $EAF2: 4C 0B C4
|
|
00EAF5 1
|
|
00EAF5 1 ; ============================================================================
|
|
00EAF5 1 ; $EAF5-$EAFF
|
|
00EAF5 1 ; Write a fixed six-byte sequence to PPUDATA.
|
|
00EAF5 1 ;
|
|
00EAF5 1 ; Entry:
|
|
00EAF5 1 ; The caller has already selected the destination PPU address through
|
|
00EAF5 1 ; SetPpuAddressFromInlineRecord.
|
|
00EAF5 1 ;
|
|
00EAF5 1 ; This routine enters WriteInlinePpuBlock at its internal $EA05 entry,
|
|
00EAF5 1 ; skipping the PPU-address setup call at $EA02.
|
|
00EAF5 1 ;
|
|
00EAF5 1 ; Inline record:
|
|
00EAF5 1 ;
|
|
00EAF5 1 ; byte 0 = transfer count, $06
|
|
00EAF5 1 ; bytes 1-6 = PPU data:
|
|
00EAF5 1 ; $0C,$0A,$15,$15,$0E,$0D
|
|
00EAF5 1 ;
|
|
00EAF5 1 ; WriteInlinePpuBlock adjusts the return address past the inline data, so
|
|
00EAF5 1 ; execution resumes at the RTS at $EAFF.
|
|
00EAF5 1 ; ============================================================================
|
|
00EAF5 1
|
|
00EAF5 1 ; ----------------------------------------------------------------------------
|
|
00EAF5 1 ; Contract:
|
|
00EAF5 1 ; Description: Writes Fixed Ppu Sequence.
|
|
00EAF5 1 ; Entry: No register input inferred
|
|
00EAF5 1 ; Returns/products: No direct product inferred
|
|
00EAF5 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EAF5 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00EAF5 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EAF5 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EAF5 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00EAF5 1 ; ----------------------------------------------------------------------------
|
|
00EAF5 1 WriteFixedPpuSequence: ; $EAF5
|
|
00EAF5 1 20 05 EA jsr WriteInlinePpuBlockAfterAddress ; $EAF5: 20 05 EA
|
|
00EAF8 1 ; Internal entry in WriteInlinePpuBlock.
|
|
00EAF8 1 ;
|
|
00EAF8 1 ; $EA05: STX $05
|
|
00EAF8 1 ; $EA07: JSR DecodeInlineParameters
|
|
00EAF8 1
|
|
00EAF8 1 ; ----------------------------------------------------------------------------
|
|
00EAF8 1 ; Inline transfer record consumed by the helper at $EA05.
|
|
00EAF8 1 ; ----------------------------------------------------------------------------
|
|
00EAF8 1
|
|
00EAF8 1 06 .byte $06 ; $EAF8
|
|
00EAF9 1 ; Number of bytes to write.
|
|
00EAF9 1
|
|
00EAF9 1 0C 0A 15 .byte $0C,$0A,$15 ; $EAF9-$EAFB
|
|
00EAFC 1 15 0E 0D .byte $15,$0E,$0D ; $EAFC-$EAFE
|
|
00EAFF 1
|
|
00EAFF 1 ; ----------------------------------------------------------------------------
|
|
00EAFF 1 ; Execution resumes here after the inline record has been consumed.
|
|
00EAFF 1 ; ----------------------------------------------------------------------------
|
|
00EAFF 1
|
|
00EAFF 1 60 rts ; $EAFF: 60
|
|
00EB00 1
|
|
00EB00 1 ; ============================================================================
|
|
00EB00 1 ; $EB00-$EB0A
|
|
00EB00 1 ; Generate a two-byte value through $D01D and write both bytes to PPUDATA.
|
|
00EB00 1 ;
|
|
00EB00 1 ; The helper at $D01D returns:
|
|
00EB00 1 ;
|
|
00EB00 1 ; Y = first byte
|
|
00EB00 1 ; A = second byte
|
|
00EB00 1 ;
|
|
00EB00 1 ; Both values are written consecutively to the current PPU address.
|
|
00EB00 1 ; ============================================================================
|
|
00EB00 1
|
|
00EB00 1 ; ----------------------------------------------------------------------------
|
|
00EB00 1 ; Contract:
|
|
00EB00 1 ; Description: Writes Generated Ppu Word.
|
|
00EB00 1 ; Entry: Registers: A, Y
|
|
00EB00 1 ; Returns/products: Primary products are committed to memory.
|
|
00EB00 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB00 1 ; Memory effects: ppudata
|
|
00EB00 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB00 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB00 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00EB00 1 ; ----------------------------------------------------------------------------
|
|
00EB00 1 WriteGeneratedPpuWord: ; $EB00
|
|
00EB00 1 20 1D D0 jsr DivideABy10 ; $EB00: 20 1D D0
|
|
00EB03 1 ; Generate or retrieve a two-byte value.
|
|
00EB03 1 ;
|
|
00EB03 1 ; Return:
|
|
00EB03 1 ; Y = first byte
|
|
00EB03 1 ; A = second byte
|
|
00EB03 1
|
|
00EB03 1 ; ----------------------------------------------------------------------------
|
|
00EB03 1 ; Write the first byte returned in Y.
|
|
00EB03 1 ; ----------------------------------------------------------------------------
|
|
00EB03 1
|
|
00EB03 1 8C 07 20 sty PPUDATA ; $EB03: 8C 07 20
|
|
00EB06 1
|
|
00EB06 1 ; ----------------------------------------------------------------------------
|
|
00EB06 1 ; Write the second byte returned in A.
|
|
00EB06 1 ; ----------------------------------------------------------------------------
|
|
00EB06 1
|
|
00EB06 1 8D 07 20 sta PPUDATA ; $EB06: 8D 07 20
|
|
00EB09 1
|
|
00EB09 1 60 rts ; $EB09: 60
|
|
00EB0A 1
|
|
00EB0A 1 ; ============================================================================
|
|
00EB0A 1 ; $EB0A-$EB29
|
|
00EB0A 1 ; Decode an inline event record, update the event arrays for object X, and
|
|
00EB0A 1 ; either start the display transition immediately or enqueue the object.
|
|
00EB0A 1 ;
|
|
00EB0A 1 ; Entry:
|
|
00EB0A 1 ; X = object/event index
|
|
00EB0A 1 ;
|
|
00EB0A 1 ; Inline record:
|
|
00EB0A 1 ; byte 0 = value stored in $069F,X
|
|
00EB0A 1 ; byte 1 = value stored in $06CF,X
|
|
00EB0A 1 ;
|
|
00EB0A 1 ; DecodeInlineParameters returns:
|
|
00EB0A 1 ; X = first inline byte
|
|
00EB0A 1 ; A = second inline byte
|
|
00EB0A 1 ; Y = index into the caller's inline record
|
|
00EB0A 1 ;
|
|
00EB0A 1 ; Important:
|
|
00EB0A 1 ; This routine is also entered internally at $EB0D by the helper at $E29B.
|
|
00EB0A 1 ; That entry skips DecodeInlineParameters because $E99A was already called.
|
|
00EB0A 1 ; ============================================================================
|
|
00EB0A 1
|
|
00EB0A 1 ; ----------------------------------------------------------------------------
|
|
00EB0A 1 ; Contract:
|
|
00EB0A 1 ; Description: Queues Inline Object Event.
|
|
00EB0A 1 ; Entry: Registers: A, X, Y; Memory: ($00), $06ff, $e2
|
|
00EB0A 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00EB0A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB0A 1 ; Memory effects: $069f, $06cf, $06ff, $0670
|
|
00EB0A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB0A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB0A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 45.
|
|
00EB0A 1 ; ----------------------------------------------------------------------------
|
|
00EB0A 1 QueueInlineObjectEvent: ; $EB0A
|
|
00EB0A 1 20 9A E9 jsr DecodeInlineParameters ; $EB0A: 20 9A E9
|
|
00EB0D 1
|
|
00EB0D 1 ; ============================================================================
|
|
00EB0D 1 ; $EB0D
|
|
00EB0D 1 ; Internal entry used by DispatchInlineObjectCommand at $E29B.
|
|
00EB0D 1 ;
|
|
00EB0D 1 ; Entry:
|
|
00EB0D 1 ; X = object/event index restored by $E29B
|
|
00EB0D 1 ; A = second decoded inline byte
|
|
00EB0D 1 ; Y = inline source index established by DecodeInlineParameters
|
|
00EB0D 1 ; $00/$01 = pointer to the inline record
|
|
00EB0D 1 ; ============================================================================
|
|
00EB0D 1
|
|
00EB0D 1 QueueDecodedObjectEvent: ; $EB0D
|
|
00EB0D 1 9D 9F 06 sta $069F,x ; $EB0D: 9D 9F 06
|
|
00EB10 1 ; Save the second inline parameter.
|
|
00EB10 1
|
|
00EB10 1 B1 00 lda ($00),y ; $EB10: B1 00
|
|
00EB12 1 ; Load the next inline byte.
|
|
00EB12 1
|
|
00EB12 1 9D CF 06 sta $06CF,x ; $EB12: 9D CF 06
|
|
00EB15 1 ; Save it in the parallel event array.
|
|
00EB15 1
|
|
00EB15 1 ; ----------------------------------------------------------------------------
|
|
00EB15 1 ; Use the object/event index as an index into the active-event array.
|
|
00EB15 1 ; ----------------------------------------------------------------------------
|
|
00EB15 1
|
|
00EB15 1 ; ----------------------------------------------------------------------------
|
|
00EB15 1 ; Contract:
|
|
00EB15 1 ; Description: Internal event-queue entry after inline values have been stored.
|
|
00EB15 1 ; Entry: X = object/event index.
|
|
00EB15 1 ; Returns/products: Queues or dispatches event context.
|
|
00EB15 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB15 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00EB15 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB15 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB15 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00EB15 1 ; ----------------------------------------------------------------------------
|
|
00EB15 1 QueueDecodedObjectEventSelectIndex:
|
|
00EB15 1 8A txa ; $EB15: 8A
|
|
00EB16 1 ; ----------------------------------------------------------------------------
|
|
00EB16 1 ; Contract:
|
|
00EB16 1 ; Description: Internal event-queue entry with object index transferred to Y.
|
|
00EB16 1 ; Entry: X/Y identify object/event entry.
|
|
00EB16 1 ; Returns/products: Queues or dispatches event context.
|
|
00EB16 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB16 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00EB16 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB16 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB16 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00EB16 1 ; ----------------------------------------------------------------------------
|
|
00EB16 1 QueueDecodedObjectEventCheckActive:
|
|
00EB16 1 A8 tay ; $EB16: A8
|
|
00EB17 1
|
|
00EB17 1 B9 FF 06 lda $06FF,y ; $EB17: B9 FF 06
|
|
00EB1A 1 D0 93 bne RunDisplayTransition ; $EB1A: D0 93
|
|
00EB1C 1 ; Target $EAAF.
|
|
00EB1C 1 ;
|
|
00EB1C 1 ; If the object already has a nonzero active
|
|
00EB1C 1 ; entry, immediately run the display transition.
|
|
00EB1C 1
|
|
00EB1C 1 ; ----------------------------------------------------------------------------
|
|
00EB1C 1 ; Mark this object/event entry active.
|
|
00EB1C 1 ;
|
|
00EB1C 1 ; A is zero here because the preceding BNE was not taken. TYA restores the
|
|
00EB1C 1 ; object index, which is stored in the active-event array.
|
|
00EB1C 1 ; ----------------------------------------------------------------------------
|
|
00EB1C 1
|
|
00EB1C 1 98 tya ; $EB1C: 98
|
|
00EB1D 1 99 FF 06 sta $06FF,y ; $EB1D: 99 FF 06
|
|
00EB20 1
|
|
00EB20 1 ; ----------------------------------------------------------------------------
|
|
00EB20 1 ; Append the object/event index to the queue at $0670.
|
|
00EB20 1 ;
|
|
00EB20 1 ; $E2 is the current queue length or next free queue slot.
|
|
00EB20 1 ; ----------------------------------------------------------------------------
|
|
00EB20 1
|
|
00EB20 1 A4 E2 ldy $E2 ; $EB20: A4 E2
|
|
00EB22 1 E6 E2 inc $E2 ; $EB22: E6 E2
|
|
00EB24 1
|
|
00EB24 1 99 70 06 sta $0670,y ; $EB24: 99 70 06
|
|
00EB27 1
|
|
00EB27 1 ; ----------------------------------------------------------------------------
|
|
00EB27 1 ; Return Y=$04. Nearby inline-data and event helpers use this value as their
|
|
00EB27 1 ; resume/index convention.
|
|
00EB27 1 ; ----------------------------------------------------------------------------
|
|
00EB27 1
|
|
00EB27 1 A0 04 ldy #$04 ; $EB27: A0 04
|
|
00EB29 1 60 rts ; $EB29: 60
|
|
00EB2A 1
|
|
00EB2A 1 ; ============================================================================
|
|
00EB2A 1 ; $EB2A-$EB3A
|
|
00EB2A 1 ; Process an active queued-event entry until its event-state byte becomes zero.
|
|
00EB2A 1 ;
|
|
00EB2A 1 ; Entry:
|
|
00EB2A 1 ; X = object/event index
|
|
00EB2A 1 ;
|
|
00EB2A 1 ; Event arrays:
|
|
00EB2A 1 ; $0600,X = active event identifier or state
|
|
00EB2A 1 ; $060F,Y = event-state table inspected after processing
|
|
00EB2A 1 ;
|
|
00EB2A 1 ; Behavior:
|
|
00EB2A 1 ; If $0600,X is already zero, return immediately.
|
|
00EB2A 1 ;
|
|
00EB2A 1 ; Otherwise:
|
|
00EB2A 1 ; 1. Call the event-processing entry at $EB16.
|
|
00EB2A 1 ; 2. Use the returned value in A as an index into $060F.
|
|
00EB2A 1 ; 3. Repeat while the indexed event-state byte remains nonzero.
|
|
00EB2A 1 ; 4. Clear $0600,X when processing completes.
|
|
00EB2A 1 ; ============================================================================
|
|
00EB2A 1
|
|
00EB2A 1 ; ----------------------------------------------------------------------------
|
|
00EB2A 1 ; Contract:
|
|
00EB2A 1 ; Description: Processes Queued Object Event.
|
|
00EB2A 1 ; Entry: Registers: A; Memory: $0600, $060f
|
|
00EB2A 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00EB2A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB2A 1 ; Memory effects: $0600
|
|
00EB2A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB2A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB2A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 5.
|
|
00EB2A 1 ; ----------------------------------------------------------------------------
|
|
00EB2A 1 ProcessQueuedObjectEvent: ; $EB2A
|
|
00EB2A 1 BD 00 06 lda $0600,x ; $EB2A: BD 00 06
|
|
00EB2D 1 F0 0C beq ProcessQueuedObjectEvent_Return
|
|
00EB2F 1 ; $EB2D: F0 0C
|
|
00EB2F 1
|
|
00EB2F 1 ProcessQueuedObjectEvent_Loop: ; $EB2F
|
|
00EB2F 1 20 16 EB jsr QueueDecodedObjectEventCheckActive ; $EB2F: 20 16 EB
|
|
00EB32 1
|
|
00EB32 1 A8 tay ; $EB32: A8
|
|
00EB33 1
|
|
00EB33 1 B9 0F 06 lda $060F,y ; $EB33: B9 0F 06
|
|
00EB36 1 D0 F7 bne ProcessQueuedObjectEvent_Loop
|
|
00EB38 1 ; $EB36: D0 F7
|
|
00EB38 1
|
|
00EB38 1 9D 00 06 sta $0600,x ; $EB38: 9D 00 06
|
|
00EB3B 1 ; Clear the entry with A=$00.
|
|
00EB3B 1
|
|
00EB3B 1 ProcessQueuedObjectEvent_Return: ; $EB3B
|
|
00EB3B 1 60 rts ; $EB3B: 60
|
|
00EB3C 1 ; ============================================================================
|
|
00EB3C 1 ; $EB3C-$EB64
|
|
00EB3C 1 ; Update the current object's queue-bank selection and restore two saved event
|
|
00EB3C 1 ; values from the stack.
|
|
00EB3C 1 ;
|
|
00EB3C 1 ; Entry:
|
|
00EB3C 1 ; A = value used to derive an index relative to $E3
|
|
00EB3C 1 ; C = significant input to SBC
|
|
00EB3C 1 ; $E1 = current object/event index
|
|
00EB3C 1 ;
|
|
00EB3C 1 ; The routine:
|
|
00EB3C 1 ; 1. Calculates a three-bit value and stores it in $063F,Y.
|
|
00EB3C 1 ; 2. Selects queue bank zero or one.
|
|
00EB3C 1 ; 3. Exchanges the current object's $060F entry with the selected bank's
|
|
00EB3C 1 ; $0600 entry.
|
|
00EB3C 1 ; 4. Restores values from the stack into $069F,Y and $06CF,Y.
|
|
00EB3C 1 ; 5. Branches to the common engine exit at $EB6A.
|
|
00EB3C 1 ; ============================================================================
|
|
00EB3C 1
|
|
00EB3C 1 UpdateObjectEventBank: ; $EB3C
|
|
00EB3C 1 38 sec ; $EB3C: 38
|
|
00EB3D 1
|
|
00EB3D 1 E5 E3 sbc FrameCounter ; $EB3D: E5 E3
|
|
00EB3F 1 ; Calculate a value relative to the current
|
|
00EB3F 1 ; event/queue state.
|
|
00EB3F 1
|
|
00EB3F 1 29 07 and #$07 ; $EB3F: 29 07
|
|
00EB41 1 ; Limit the result to three bits.
|
|
00EB41 1
|
|
00EB41 1 ; ----------------------------------------------------------------------------
|
|
00EB41 1 ; Contract:
|
|
00EB41 1 ; Description: Internal event-bank entry after the three-bit value is prepared in A.
|
|
00EB41 1 ; Entry: A = event-bank value; current object index set.
|
|
00EB41 1 ; Returns/products: $063F,Y updated; may continue into bank exchange.
|
|
00EB41 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB41 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00EB41 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB41 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB41 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00EB41 1 ; ----------------------------------------------------------------------------
|
|
00EB41 1 StoreObjectEventBankValue:
|
|
00EB41 1 A4 E1 ldy CurrentObjectIndex ; $EB41: A4 E1
|
|
00EB43 1
|
|
00EB43 1 99 3F 06 sta $063F,y ; $EB43: 99 3F 06
|
|
00EB46 1 ; Save the calculated three-bit value.
|
|
00EB46 1
|
|
00EB46 1 ; ----------------------------------------------------------------------------
|
|
00EB46 1 ; A nonzero calculated value skips the queue-bank exchange and proceeds
|
|
00EB46 1 ; directly to the stack-restoration path.
|
|
00EB46 1 ; ----------------------------------------------------------------------------
|
|
00EB46 1
|
|
00EB46 1 D0 12 bne UpdateObjectEventBank_Restore
|
|
00EB48 1 ; $EB46: D0 12
|
|
00EB48 1
|
|
00EB48 1 ; ============================================================================
|
|
00EB48 1 ; $EB48
|
|
00EB48 1 ; Select queue bank one.
|
|
00EB48 1 ;
|
|
00EB48 1 ; This address is also called directly throughout the ROM as a frame/event
|
|
00EB48 1 ; synchronization helper. The direct-entry behavior begins by selecting bank
|
|
00EB48 1 ; one and continues through the exchange below.
|
|
00EB48 1 ; ============================================================================
|
|
00EB48 1
|
|
00EB48 1 ; ----------------------------------------------------------------------------
|
|
00EB48 1 ; Contract:
|
|
00EB48 1 ; Description: Implements Select Object Event Bank 1.
|
|
00EB48 1 ; Entry: Registers: A, Y; Memory: currentobjectindex, $0600
|
|
00EB48 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00EB48 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB48 1 ; Memory effects: $060f, $0600, $069f, $06cf
|
|
00EB48 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB48 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB48 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 42.
|
|
00EB48 1 ; ----------------------------------------------------------------------------
|
|
00EB48 1 SelectObjectEventBank1: ; $EB48
|
|
00EB48 1 A2 01 ldx #$01 ; $EB48: A2 01
|
|
00EB4A 1
|
|
00EB4A 1 D0 02 bne UpdateObjectEventBank_Exchange
|
|
00EB4C 1 ; $EB4A: D0 02
|
|
00EB4C 1 ; Always taken because X is nonzero.
|
|
00EB4C 1
|
|
00EB4C 1 ; ============================================================================
|
|
00EB4C 1 ; $EB4C
|
|
00EB4C 1 ; Select queue bank zero.
|
|
00EB4C 1 ;
|
|
00EB4C 1 ; This is another direct entry used elsewhere in the ROM.
|
|
00EB4C 1 ; ============================================================================
|
|
00EB4C 1
|
|
00EB4C 1 ; ----------------------------------------------------------------------------
|
|
00EB4C 1 ; Contract:
|
|
00EB4C 1 ; Description: Implements Select Object Event Bank 0.
|
|
00EB4C 1 ; Entry: Registers: A, Y; Memory: currentobjectindex, $0600
|
|
00EB4C 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00EB4C 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB4C 1 ; Memory effects: $060f, $0600, $069f, $06cf
|
|
00EB4C 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB4C 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB4C 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 7.
|
|
00EB4C 1 ; ----------------------------------------------------------------------------
|
|
00EB4C 1 SelectObjectEventBank0: ; $EB4C
|
|
00EB4C 1 A2 00 ldx #$00 ; $EB4C: A2 00
|
|
00EB4E 1
|
|
00EB4E 1 ; ----------------------------------------------------------------------------
|
|
00EB4E 1 ; Exchange the current object's $060F entry with the selected bank's $0600
|
|
00EB4E 1 ; entry.
|
|
00EB4E 1 ;
|
|
00EB4E 1 ; Before:
|
|
00EB4E 1 ; A = $0600,X
|
|
00EB4E 1 ; Y = CurrentObjectIndex
|
|
00EB4E 1 ;
|
|
00EB4E 1 ; After:
|
|
00EB4E 1 ; $060F,Y = old $0600,X
|
|
00EB4E 1 ; $0600,X = CurrentObjectIndex
|
|
00EB4E 1 ; ----------------------------------------------------------------------------
|
|
00EB4E 1
|
|
00EB4E 1 ; ----------------------------------------------------------------------------
|
|
00EB4E 1 ; Contract:
|
|
00EB4E 1 ; Description: Updates Object Event Bank Exchange.
|
|
00EB4E 1 ; Entry: Registers: A, Y; Memory: currentobjectindex, $0600
|
|
00EB4E 1 ; Returns/products: Registers/clobbers: A, Y
|
|
00EB4E 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB4E 1 ; Memory effects: $060f, $0600, $069f, $06cf
|
|
00EB4E 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB4E 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB4E 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 3.
|
|
00EB4E 1 ; ----------------------------------------------------------------------------
|
|
00EB4E 1 UpdateObjectEventBank_Exchange: ; $EB4E
|
|
00EB4E 1 A4 E1 ldy CurrentObjectIndex ; $EB4E: A4 E1
|
|
00EB50 1
|
|
00EB50 1 BD 00 06 lda $0600,x ; $EB50: BD 00 06
|
|
00EB53 1 99 0F 06 sta $060F,y ; $EB53: 99 0F 06
|
|
00EB56 1
|
|
00EB56 1 98 tya ; $EB56: 98
|
|
00EB57 1 9D 00 06 sta $0600,x ; $EB57: 9D 00 06
|
|
00EB5A 1
|
|
00EB5A 1 ; ============================================================================
|
|
00EB5A 1 ; $EB5A
|
|
00EB5A 1 ; Restore two saved event values from the stack.
|
|
00EB5A 1 ;
|
|
00EB5A 1 ; Entry paths:
|
|
00EB5A 1 ; From $EB46:
|
|
00EB5A 1 ; Y was loaded from CurrentObjectIndex at $EB41.
|
|
00EB5A 1 ;
|
|
00EB5A 1 ; From $EB48/$EB4C:
|
|
00EB5A 1 ; Y was reloaded from CurrentObjectIndex at $EB4E.
|
|
00EB5A 1 ; ============================================================================
|
|
00EB5A 1
|
|
00EB5A 1 UpdateObjectEventBank_Restore: ; $EB5A
|
|
00EB5A 1 18 clc ; $EB5A: 18
|
|
00EB5B 1 ; Establish carry clear for the final BCC.
|
|
00EB5B 1
|
|
00EB5B 1 ; ----------------------------------------------------------------------------
|
|
00EB5B 1 ; Contract:
|
|
00EB5B 1 ; Description: Internal event-context restoration entry.
|
|
00EB5B 1 ; Entry: Y = object/event index; stack contains two saved context bytes; carry controls final branch.
|
|
00EB5B 1 ; Returns/products: Context arrays restored; stack consumed.
|
|
00EB5B 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB5B 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00EB5B 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB5B 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB5B 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00EB5B 1 ; ----------------------------------------------------------------------------
|
|
00EB5B 1 RestoreObjectEventContext:
|
|
00EB5B 1 68 pla ; $EB5B: 68
|
|
00EB5C 1 99 9F 06 sta $069F,y ; $EB5C: 99 9F 06
|
|
00EB5F 1
|
|
00EB5F 1 68 pla ; $EB5F: 68
|
|
00EB60 1 99 CF 06 sta $06CF,y ; $EB60: 99 CF 06
|
|
00EB63 1
|
|
00EB63 1 ; ----------------------------------------------------------------------------
|
|
00EB63 1 ; Transfer to the common exit at $EB6A.
|
|
00EB63 1 ;
|
|
00EB63 1 ; CLC makes this branch unconditional.
|
|
00EB63 1 ; ----------------------------------------------------------------------------
|
|
00EB63 1
|
|
00EB63 1 90 05 bcc CommonEngineExit ; $EB63: 90 05
|
|
00EB65 1 ; Target $EB6A.
|
|
00EB65 1
|
|
00EB65 1 ; ============================================================================
|
|
00EB65 1 ; The supplied dump ends at $EB64.
|
|
00EB65 1 ;
|
|
00EB65 1 ; Leave $EB65 onward untouched until its bytes are verified. The branch above
|
|
00EB65 1 ; targets the already-known common engine exit at $EB6A.
|
|
00EB65 1 ; ============================================================================
|
|
00EB65 1
|
|
00EB65 1 ; ============================================================================
|
|
00EB65 1 ; $EB65
|
|
00EB65 1 ; Standalone return entry.
|
|
00EB65 1 ;
|
|
00EB65 1 ; The preceding code at $EB63 branches over this byte to the common exit at
|
|
00EB65 1 ; $EB6A. Other callers may use $EB65 as an immediate no-operation return.
|
|
00EB65 1 ; ============================================================================
|
|
00EB65 1
|
|
00EB65 1 Return_EB65: ; $EB65
|
|
00EB65 1 60 rts ; $EB65: 60
|
|
00EB66 1
|
|
00EB66 1 ; ============================================================================
|
|
00EB66 1 ; $EB66-$EB9C
|
|
00EB66 1 ; Finish the current event, then restore and dispatch the newest queued event.
|
|
00EB66 1 ;
|
|
00EB66 1 ; Entry:
|
|
00EB66 1 ; Y = object/event index used by the shared stack-restoration path
|
|
00EB66 1 ;
|
|
00EB66 1 ; Operation:
|
|
00EB66 1 ; 1. Enter the stack-restoration path at $EB5B with carry set.
|
|
00EB66 1 ; 2. Clear the current object's active-event entry at $06FF,X.
|
|
00EB66 1 ; 3. Wait until at least one queued event exists.
|
|
00EB66 1 ; 4. Disable NMI while modifying the queue.
|
|
00EB66 1 ; 5. Pop the newest queued object index from $0670.
|
|
00EB66 1 ; 6. Reset the stack pointer.
|
|
00EB66 1 ; 7. Push that object's saved handler/event values.
|
|
00EB66 1 ; 8. Return into the queued event's saved continuation.
|
|
00EB66 1 ;
|
|
00EB66 1 ; This routine implements a stack-based event-context switch.
|
|
00EB66 1 ; ============================================================================
|
|
00EB66 1
|
|
00EB66 1 ; ----------------------------------------------------------------------------
|
|
00EB66 1 ; Contract:
|
|
00EB66 1 ; Description: Implements Dispatch Next Queued Event.
|
|
00EB66 1 ; Entry: Registers: A, X; Memory: currentobjectindex, $e2, $2002, $dd, $0670, $06cf
|
|
00EB66 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00EB66 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB66 1 ; Memory effects: $06ff, $2000, $e2, currentobjectindex
|
|
00EB66 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB66 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB66 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 20.
|
|
00EB66 1 ; ----------------------------------------------------------------------------
|
|
00EB66 1 DispatchNextQueuedEvent: ; $EB66
|
|
00EB66 1 38 sec ; $EB66: 38
|
|
00EB67 1
|
|
00EB67 1 20 5B EB jsr RestoreObjectEventContext ; $EB67: 20 5B EB
|
|
00EB6A 1 ; Enter the previous routine after its CLC.
|
|
00EB6A 1 ;
|
|
00EB6A 1 ; Since entry is at $EB5B, carry remains set
|
|
00EB6A 1 ; through the two PLA/STA operations. Its final
|
|
00EB6A 1 ; BCC is therefore not taken, allowing this
|
|
00EB6A 1 ; routine to continue at $EB6A.
|
|
00EB6A 1
|
|
00EB6A 1 ; ============================================================================
|
|
00EB6A 1 ; $EB6A
|
|
00EB6A 1 ; Common continuation used by multiple earlier paths.
|
|
00EB6A 1 ; ============================================================================
|
|
00EB6A 1
|
|
00EB6A 1 CommonEngineExit: ; $EB6A
|
|
00EB6A 1 A6 E1 ldx CurrentObjectIndex ; $EB6A: A6 E1
|
|
00EB6C 1
|
|
00EB6C 1 A9 00 lda #$00 ; $EB6C: A9 00
|
|
00EB6E 1 9D FF 06 sta $06FF,x ; $EB6E: 9D FF 06
|
|
00EB71 1 ; Mark the current object/event inactive.
|
|
00EB71 1
|
|
00EB71 1 ; ----------------------------------------------------------------------------
|
|
00EB71 1 ; Check the queued-event count in $E2.
|
|
00EB71 1 ; ----------------------------------------------------------------------------
|
|
00EB71 1
|
|
00EB71 1 A6 E2 ldx $E2 ; $EB71: A6 E2
|
|
00EB73 1 D0 0C bne DispatchNextQueuedEvent_HaveEntry
|
|
00EB75 1 ; $EB73: D0 0C
|
|
00EB75 1
|
|
00EB75 1 ; ----------------------------------------------------------------------------
|
|
00EB75 1 ; No event is currently queued.
|
|
00EB75 1 ;
|
|
00EB75 1 ; Read PPUSTATUS to reset the PPU address latch, then restore PPUCTRL from $DD.
|
|
00EB75 1 ; Wait until an NMI or another producer adds an event to the queue.
|
|
00EB75 1 ; ----------------------------------------------------------------------------
|
|
00EB75 1
|
|
00EB75 1 AD 02 20 lda $2002 ; $EB75: AD 02 20
|
|
00EB78 1 ; Reset the PPU address latch.
|
|
00EB78 1
|
|
00EB78 1 A5 DD lda PpuCtrlShadow ; $EB78: A5 DD
|
|
00EB7A 1 8D 00 20 sta $2000 ; $EB7A: 8D 00 20
|
|
00EB7D 1 ; Restore the current PPUCTRL value.
|
|
00EB7D 1
|
|
00EB7D 1 DispatchNextQueuedEvent_Wait: ; $EB7D
|
|
00EB7D 1 A6 E2 ldx $E2 ; $EB7D: A6 E2
|
|
00EB7F 1 F0 FC beq DispatchNextQueuedEvent_Wait
|
|
00EB81 1 ; $EB7F: F0 FC
|
|
00EB81 1
|
|
00EB81 1 ; ----------------------------------------------------------------------------
|
|
00EB81 1 ; At least one queued event exists.
|
|
00EB81 1 ;
|
|
00EB81 1 ; Disable NMI by clearing bit seven of the saved PPUCTRL value.
|
|
00EB81 1 ; ----------------------------------------------------------------------------
|
|
00EB81 1
|
|
00EB81 1 DispatchNextQueuedEvent_HaveEntry: ; $EB81
|
|
00EB81 1 A5 DD lda PpuCtrlShadow ; $EB81: A5 DD
|
|
00EB83 1 29 7F and #$7F ; $EB83: 29 7F
|
|
00EB85 1 8D 00 20 sta $2000 ; $EB85: 8D 00 20
|
|
00EB88 1
|
|
00EB88 1 ; ----------------------------------------------------------------------------
|
|
00EB88 1 ; Remove the newest object/event index from the queue.
|
|
00EB88 1 ;
|
|
00EB88 1 ; $E2 behaves as a count/next-free index:
|
|
00EB88 1 ;
|
|
00EB88 1 ; X = $E2 - 1
|
|
00EB88 1 ; CurrentObjectIndex = $0670,X
|
|
00EB88 1 ; $E2 = X
|
|
00EB88 1 ; ----------------------------------------------------------------------------
|
|
00EB88 1
|
|
00EB88 1 CA dex ; $EB88: CA
|
|
00EB89 1 86 E2 stx $E2 ; $EB89: 86 E2
|
|
00EB8B 1
|
|
00EB8B 1 BD 70 06 lda $0670,x ; $EB8B: BD 70 06
|
|
00EB8E 1 85 E1 sta CurrentObjectIndex ; $EB8E: 85 E1
|
|
00EB90 1 A8 tay ; $EB90: A8
|
|
00EB91 1 ; Y = queued object/event index.
|
|
00EB91 1
|
|
00EB91 1 ; ----------------------------------------------------------------------------
|
|
00EB91 1 ; Reset the hardware stack.
|
|
00EB91 1 ;
|
|
00EB91 1 ; Setting SP to $FF discards the current call chain. The saved event values
|
|
00EB91 1 ; pushed below become the return context used by RTS.
|
|
00EB91 1 ; ----------------------------------------------------------------------------
|
|
00EB91 1
|
|
00EB91 1 A2 FF ldx #$FF ; $EB91: A2 FF
|
|
00EB93 1 9A txs ; $EB93: 9A
|
|
00EB94 1
|
|
00EB94 1 ; ----------------------------------------------------------------------------
|
|
00EB94 1 ; Push the queued object's saved continuation/context bytes.
|
|
00EB94 1 ;
|
|
00EB94 1 ; RTS at $EB9C pulls these bytes as its return address. The low byte is pushed
|
|
00EB94 1 ; second because RTS pulls low byte first.
|
|
00EB94 1 ; ----------------------------------------------------------------------------
|
|
00EB94 1
|
|
00EB94 1 B9 CF 06 lda $06CF,y ; $EB94: B9 CF 06
|
|
00EB97 1 48 pha ; $EB97: 48
|
|
00EB98 1 ; Push saved high byte.
|
|
00EB98 1
|
|
00EB98 1 B9 9F 06 lda $069F,y ; $EB98: B9 9F 06
|
|
00EB9B 1 48 pha ; $EB9B: 48
|
|
00EB9C 1 ; Push saved low byte.
|
|
00EB9C 1
|
|
00EB9C 1 60 rts ; $EB9C: 60
|
|
00EB9D 1 ; Resume the queued event continuation.
|
|
00EB9D 1
|
|
00EB9D 1 ; ============================================================================
|
|
00EB9D 1 ; $EB9D-$EBB3
|
|
00EB9D 1 ; Initialize the queued-event system and clear its event arrays.
|
|
00EB9D 1 ;
|
|
00EB9D 1 ; Operation:
|
|
00EB9D 1 ; 1. Clear the full $0600-$06FF page.
|
|
00EB9D 1 ; 2. Clear the queue count at $E2.
|
|
00EB9D 1 ; 3. Set CurrentObjectIndex to $01.
|
|
00EB9D 1 ; 4. Clear $30 entries in the active-event array beginning at $06FF.
|
|
00EB9D 1 ;
|
|
00EB9D 1 ; Exit:
|
|
00EB9D 1 ; A = $00
|
|
00EB9D 1 ; X = $00
|
|
00EB9D 1 ; $E2 = $00
|
|
00EB9D 1 ; CurrentObjectIndex = $01
|
|
00EB9D 1 ; ============================================================================
|
|
00EB9D 1
|
|
00EB9D 1 ; ----------------------------------------------------------------------------
|
|
00EB9D 1 ; Contract:
|
|
00EB9D 1 ; Description: Initializes Queued Event System.
|
|
00EB9D 1 ; Entry: Registers: A, X
|
|
00EB9D 1 ; Returns/products: Registers/clobbers: A, X
|
|
00EB9D 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00EB9D 1 ; Memory effects: $0600, $e2, currentobjectindex, $06ff
|
|
00EB9D 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00EB9D 1 ; comparison, load, or store path and are not a stable API product.
|
|
00EB9D 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 4.
|
|
00EB9D 1 ; ----------------------------------------------------------------------------
|
|
00EB9D 1 InitializeQueuedEventSystem: ; $EB9D
|
|
00EB9D 1 A9 00 lda #$00 ; $EB9D: A9 00
|
|
00EB9F 1 AA tax ; $EB9F: AA
|
|
00EBA0 1 ; A = $00, X = $00.
|
|
00EBA0 1
|
|
00EBA0 1 ; ----------------------------------------------------------------------------
|
|
00EBA0 1 ; Clear the full $0600-$06FF page.
|
|
00EBA0 1 ;
|
|
00EBA0 1 ; X begins at zero and wraps after 256 iterations:
|
|
00EBA0 1 ;
|
|
00EBA0 1 ; $0600,X = $00
|
|
00EBA0 1 ; ...
|
|
00EBA0 1 ; $06FF,X = $00
|
|
00EBA0 1 ; ----------------------------------------------------------------------------
|
|
00EBA0 1
|
|
00EBA0 1 InitializeQueuedEventSystem_ClearPage: ; $EBA0
|
|
00EBA0 1 9D 00 06 sta $0600,x ; $EBA0: 9D 00 06
|
|
00EBA3 1
|
|
00EBA3 1 E8 inx ; $EBA3: E8
|
|
00EBA4 1 D0 FA bne InitializeQueuedEventSystem_ClearPage
|
|
00EBA6 1 ; $EBA4: D0 FA
|
|
00EBA6 1
|
|
00EBA6 1 ; ----------------------------------------------------------------------------
|
|
00EBA6 1 ; Clear the queued-event count or next-free queue index.
|
|
00EBA6 1 ; ----------------------------------------------------------------------------
|
|
00EBA6 1
|
|
00EBA6 1 85 E2 sta $E2 ; $EBA6: 85 E2
|
|
00EBA8 1
|
|
00EBA8 1 ; ----------------------------------------------------------------------------
|
|
00EBA8 1 ; X wrapped to zero after the page clear. Increment it to one and use that as
|
|
00EBA8 1 ; the initial current-object/event index.
|
|
00EBA8 1 ; ----------------------------------------------------------------------------
|
|
00EBA8 1
|
|
00EBA8 1 E8 inx ; $EBA8: E8
|
|
00EBA9 1 ; X = $01.
|
|
00EBA9 1
|
|
00EBA9 1 86 E1 stx CurrentObjectIndex ; $EBA9: 86 E1
|
|
00EBAB 1
|
|
00EBAB 1 ; ----------------------------------------------------------------------------
|
|
00EBAB 1 ; Clear the active-event entries $06FF-$072E.
|
|
00EBAB 1 ;
|
|
00EBAB 1 ; X begins at $30. Because the indexed base is $06FF, the effective addresses
|
|
00EBAB 1 ; are:
|
|
00EBAB 1 ;
|
|
00EBAB 1 ; X=$30 -> $072F
|
|
00EBAB 1 ; ...
|
|
00EBAB 1 ; X=$01 -> $0700
|
|
00EBAB 1 ;
|
|
00EBAB 1 ; The loop does not write with X=$00.
|
|
00EBAB 1 ;
|
|
00EBAB 1 ; Note that $06FF itself was already cleared by the full-page loop above.
|
|
00EBAB 1 ; ----------------------------------------------------------------------------
|
|
00EBAB 1
|
|
00EBAB 1 A2 30 ldx #$30 ; $EBAB: A2 30
|
|
00EBAD 1
|
|
00EBAD 1 InitializeQueuedEventSystem_ClearActive: ; $EBAD
|
|
00EBAD 1 9D FF 06 sta $06FF,x ; $EBAD: 9D FF 06
|
|
00EBB0 1
|
|
00EBB0 1 CA dex ; $EBB0: CA
|
|
00EBB1 1 D0 FA bne InitializeQueuedEventSystem_ClearActive
|
|
00EBB3 1 ; $EBB1: D0 FA
|
|
00EBB3 1
|
|
00EBB3 1 60 rts ; $EBB3: 60
|
|
00EBB4 1
|
|
00EBB4 1 ; ============================================================================
|
|
00EBB4 1 ; $EBB4-$EBBB
|
|
00EBB4 1 ; Convert A into a three-bit value relative to $E3, then enter the common
|
|
00EBB4 1 ; object-event bank routine at $EB41.
|
|
00EBB4 1 ;
|
|
00EBB4 1 ; Entry:
|
|
00EBB4 1 ; A = source value
|
|
00EBB4 1 ;
|
|
00EBB4 1 ; Calculation:
|
|
00EBB4 1 ; A = (A - $E3) & $07
|
|
00EBB4 1 ; ============================================================================
|
|
00EBB4 1
|
|
00EBB4 1 UpdateRelativeObjectEventBank: ; $EBB4
|
|
00EBB4 1 38 sec ; $EBB4: 38
|
|
00EBB5 1
|
|
00EBB5 1 E5 E3 sbc FrameCounter ; $EBB5: E5 E3
|
|
00EBB7 1
|
|
00EBB7 1 29 07 and #$07 ; $EBB7: 29 07
|
|
00EBB9 1
|
|
00EBB9 1 4C 41 EB jmp StoreObjectEventBankValue ; $EBB9: 4C 41 EB
|
|
00EBBC 1
|
|
00EBBC 1 ; ============================================================================
|
|
00EBBC 1 ; $EBBC-$EBDB
|
|
00EBBC 1 ; Structured rendering or animation data.
|
|
00EBBC 1 ;
|
|
00EBBC 1 ; This region does not begin with a plausible executable entry point:
|
|
00EBBC 1 ;
|
|
00EBBC 1 ; $EBBC: D6 E1
|
|
00EBBC 1 ; $EBBE: B1 C7
|
|
00EBBC 1 ; $EBC0: BE C2
|
|
00EBBC 1 ;
|
|
00EBBC 1 ; The following bytes contain repeating values and fields resembling sprite or
|
|
00EBBC 1 ; animation records. Keep the exact byte layout until the routines that index
|
|
00EBBC 1 ; this region reveal its record boundaries.
|
|
00EBBC 1 ; ============================================================================
|
|
00EBBC 1
|
|
00EBBC 1 RenderingData_EBBC: ; $EBBC
|
|
00EBBC 1 D6 E1 B1 C7 .byte $D6,$E1,$B1,$C7,$BE,$C2,$50,$03
|
|
00EBC0 1 BE C2 50 03
|
|
00EBC4 1 00 27 50 03 .byte $00,$27,$50,$03,$00,$1F,$A8,$02
|
|
00EBC8 1 00 1F A8 02
|
|
00EBCC 1 3F 27 A8 02 .byte $3F,$27,$A8,$02,$3F,$1F,$A4,$03
|
|
00EBD0 1 3F 1F A4 03
|
|
00EBD4 1 F3 17 05 F0 .byte $F3,$17,$05,$F0,$C8,$41,$04,$E0
|
|
00EBD8 1 C8 41 04 E0
|
|
00EBDC 1
|
|
00EBDC 1 ; ============================================================================
|
|
00EBDC 1 ; $EBDC-$EBFB
|
|
00EBDC 1 ; Structured rendering or animation data, continued.
|
|
00EBDC 1 ;
|
|
00EBDC 1 ; The repeating $41 values and surrounding control-like fields suggest compact
|
|
00EBDC 1 ; rendering records, but the record boundaries remain unverified. Preserve the
|
|
00EBDC 1 ; exact raw byte layout.
|
|
00EBDC 1 ; ============================================================================
|
|
00EBDC 1
|
|
00EBDC 1 RenderingData_EBDC: ; $EBDC
|
|
00EBDC 1 C9 41 FC E8 .byte $C9,$41,$FC,$E8,$CA,$41,$FC,$F0
|
|
00EBE0 1 CA 41 FC F0
|
|
00EBE4 1 CB 41 FC F8 .byte $CB,$41,$FC,$F8,$CC,$41,$FC,$04
|
|
00EBE8 1 CC 41 FC 04
|
|
00EBEC 1 F0 CD 41 04 .byte $F0,$CD,$41,$04,$E8,$CE,$41,$FC
|
|
00EBF0 1 E8 CE 41 FC
|
|
00EBF4 1 F0 CF 41 FC .byte $F0,$CF,$41,$FC,$F8,$D0,$41,$FC
|
|
00EBF8 1 F8 D0 41 FC
|
|
00EBFC 1
|
|
00EBFC 1 ; ============================================================================
|
|
00EBFC 1 ; $EBFC-$EC1B
|
|
00EBFC 1 ; Structured rendering or animation data, continued.
|
|
00EBFC 1 ;
|
|
00EBFC 1 ; This block retains the same compact record pattern seen in the preceding
|
|
00EBFC 1 ; region. Preserve the raw bytes until the consuming renderer reveals the
|
|
00EBFC 1 ; exact record boundaries and field meanings.
|
|
00EBFC 1 ; ============================================================================
|
|
00EBFC 1
|
|
00EBFC 1 RenderingData_EBFC: ; $EBFC
|
|
00EBFC 1 05 E8 D1 41 .byte $05,$E8,$D1,$41,$FC,$F0,$D2,$41
|
|
00EC00 1 FC F0 D2 41
|
|
00EC04 1 FC F8 D3 41 .byte $FC,$F8,$D3,$41,$FC,$F0,$D4,$41
|
|
00EC08 1 FC F0 D4 41
|
|
00EC0C 1 F4 F6 D5 41 .byte $F4,$F6,$D5,$41,$EC,$05,$E8,$D7
|
|
00EC10 1 EC 05 E8 D7
|
|
00EC14 1 41 FC F0 D8 .byte $41,$FC,$F0,$D8,$41,$FC,$F8,$D9
|
|
00EC18 1 41 FC F8 D9
|
|
00EC1C 1
|
|
00EC1C 1 ; ============================================================================
|
|
00EC1C 1 ; Resume untouched PRG-ROM at file offset $2C1C.
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; CPU data range: $EBFC-$EC1B
|
|
00EC1C 1 ; ROM data range: $2BFC-$2C1B
|
|
00EC1C 1 ; Length decoded: $0020 bytes
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; $4000 - $2C1C = $13E4 bytes remaining.
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; The structured data continues at CPU $EC1C.
|
|
00EC1C 1 ; ============================================================================
|
|
00EC1C 1 ; $EC1C-$F9CF
|
|
00EC1C 1 ; Structured rendering, animation, sprite, text, and lookup data.
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; This continues the record data beginning at $EBBC. The region contains many
|
|
00EC1C 1 ; repeating compact record formats, including:
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; - animation frame descriptions
|
|
00EC1C 1 ; - sprite coordinate and attribute records
|
|
00EC1C 1 ; - display and text data
|
|
00EC1C 1 ; - pointer and lookup tables
|
|
00EC1C 1 ; - unused $FF padding near the end
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; No reliable executable entry point occurs inside this range. Preserve the
|
|
00EC1C 1 ; bytes directly until all consuming routines and record formats are mapped.
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; CPU range:
|
|
00EC1C 1 ; $EC1C-$F9CF
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; ROM range:
|
|
00EC1C 1 ; $2C1C-$39CF
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; Length:
|
|
00EC1C 1 ; $39D0 - $2C1C = $0DB4 bytes
|
|
00EC1C 1 ; ============================================================================
|
|
00EC1C 1
|
|
00EC1C 1 RenderingAndAnimationData_EC1C:
|
|
00EC1C 1 ; ============================================================================
|
|
00EC1C 1 ; $EC1C-$F9CF
|
|
00EC1C 1 ; Structured rendering, animation, sprite, text, and lookup data.
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; This region has no executable entry points. The only confirmed direct code
|
|
00EC1C 1 ; reference is FrameOamTemplate_F94D, copied as 88 bytes into OAM shadow RAM
|
|
00EC1C 1 ; by CopyTransitionOamTemplate at $C2E6.
|
|
00EC1C 1 ;
|
|
00EC1C 1 ; Record boundaries outside the confirmed OAM template remain provisional, so
|
|
00EC1C 1 ; the bytes are preserved explicitly without assigning unsupported semantics.
|
|
00EC1C 1 ; ============================================================================
|
|
00EC1C 1
|
|
00EC1C 1 ; Explicit bytes begin at CPU $EC1C.
|
|
00EC1C 1 41 FC F0 DA .byte $41,$FC,$F0,$DA,$41,$F4,$F0,$DB,$41,$EC,$05,$E8,$DC,$41,$FC,$F0 ; $EC1C
|
|
00EC20 1 41 F4 F0 DB
|
|
00EC24 1 41 EC 05 E8
|
|
00EC2C 1 DD 41 FC F8 .byte $DD,$41,$FC,$F8,$DE,$41,$FC,$E8,$DF,$41,$F4,$E5,$E0,$41,$EC,$05 ; $EC2C
|
|
00EC30 1 DE 41 FC E8
|
|
00EC34 1 DF 41 F4 E5
|
|
00EC3C 1 E8 E2 41 04 .byte $E8,$E2,$41,$04,$F0,$E3,$41,$04,$E8,$E4,$41,$FC,$F0,$DD,$41,$FC ; $EC3C
|
|
00EC40 1 F0 E3 41 04
|
|
00EC44 1 E8 E4 41 FC
|
|
00EC4C 1 F8 DE 41 FC .byte $F8,$DE,$41,$FC,$00,$05,$E8,$A5,$40,$00,$F0,$A0,$40,$00,$F8,$A1 ; $EC4C
|
|
00EC50 1 00 05 E8 A5
|
|
00EC54 1 40 00 F0 A0
|
|
00EC5C 1 40 FB E8 A6 .byte $40,$FB,$E8,$A6,$40,$F8,$F0,$A3,$40,$F8,$04,$E8,$9F,$40,$FC,$F0 ; $EC5C
|
|
00EC60 1 40 F8 F0 A3
|
|
00EC64 1 40 F8 04 E8
|
|
00EC6C 1 A0 40 00 F8 .byte $A0,$40,$00,$F8,$A1,$40,$FB,$F0,$A3,$40,$F8,$05,$E8,$A7,$40,$00 ; $EC6C
|
|
00EC70 1 A1 40 FB F0
|
|
00EC74 1 A3 40 F8 05
|
|
00EC7C 1 F0 A8 40 00 .byte $F0,$A8,$40,$00,$F8,$A9,$40,$FA,$E8,$AA,$40,$F8,$F0,$AB,$40,$F8 ; $EC7C
|
|
00EC80 1 F8 A9 40 FA
|
|
00EC84 1 E8 AA 40 F8
|
|
00EC8C 1 05 E8 AD 40 .byte $05,$E8,$AD,$40,$00,$F0,$A8,$40,$00,$F8,$A9,$40,$FA,$E8,$AE,$40 ; $EC8C
|
|
00EC90 1 00 F0 A8 40
|
|
00EC94 1 00 F8 A9 40
|
|
00EC9C 1 F8 F0 AB 40 .byte $F8,$F0,$AB,$40,$F8,$05,$F3,$C1,$40,$04,$E8,$C3,$40,$FC,$F0,$C4 ; $EC9C
|
|
00ECA0 1 F8 05 F3 C1
|
|
00ECA4 1 40 04 E8 C3
|
|
00ECAC 1 40 FC F8 C5 .byte $40,$FC,$F8,$C5,$40,$FC,$EB,$C6,$40,$F4,$05,$EC,$93,$40,$04,$E8 ; $ECAC
|
|
00ECB0 1 40 FC EB C6
|
|
00ECB4 1 40 F4 05 EC
|
|
00ECBC 1 C3 00 FC F0 .byte $C3,$00,$FC,$F0,$94,$40,$FC,$F8,$C5,$00,$FC,$F3,$C1,$00,$F4,$06 ; $ECBC
|
|
00ECC0 1 94 40 FC F8
|
|
00ECC4 1 C5 00 FC F3
|
|
00ECCC 1 EC AF 40 04 .byte $EC,$AF,$40,$04,$F8,$B0,$40,$04,$EC,$B2,$40,$FC,$F4,$B3,$40,$FC ; $ECCC
|
|
00ECD0 1 F8 B0 40 04
|
|
00ECD4 1 EC B2 40 FC
|
|
00ECDC 1 FC B4 40 FC .byte $FC,$B4,$40,$FC,$F4,$B5,$40,$F4,$06,$EC,$AF,$40,$04,$F4,$B6,$40 ; $ECDC
|
|
00ECE0 1 F4 B5 40 F4
|
|
00ECE4 1 06 EC AF 40
|
|
00ECEC 1 04 EC B2 40 .byte $04,$EC,$B2,$40,$FC,$F4,$B3,$40,$FC,$FC,$B4,$40,$FC,$F4,$B5,$40 ; $ECEC
|
|
00ECF0 1 FC F4 B3 40
|
|
00ECF4 1 FC FC B4 40
|
|
00ECFC 1 F4 04 EC B7 .byte $F4,$04,$EC,$B7 ; $ECFC
|
|
00ED00 1
|
|
00ED00 1 RenderingAnimationData_ED00: ; $ED00
|
|
00ED00 1 40 04 EC B8 .byte $40,$04,$EC,$B8,$40,$FC,$F4,$B9,$40,$FC,$FC,$BA,$40,$FC,$05,$F0 ; $ED00
|
|
00ED04 1 40 FC F4 B9
|
|
00ED08 1 40 FC FC BA
|
|
00ED10 1 BB 40 FC F8 .byte $BB,$40,$FC,$F8,$BC,$40,$00,$00,$BD,$40,$00,$F8,$BF,$40,$F8,$00 ; $ED10
|
|
00ED14 1 BC 40 00 00
|
|
00ED18 1 BD 40 00 F8
|
|
00ED20 1 C0 40 F8 05 .byte $C0,$40,$F8,$05,$E8,$E7,$40,$00,$F0,$E8,$40,$00,$F8,$A9,$40,$FA ; $ED20
|
|
00ED24 1 E8 E7 40 00
|
|
00ED28 1 F0 E8 40 00
|
|
00ED30 1 E8 AA 40 F8 .byte $E8,$AA,$40,$F8,$F0,$E9,$40,$F8,$00,$05,$F0,$C8,$01,$F4,$E0,$C9 ; $ED30
|
|
00ED34 1 F0 E9 40 F8
|
|
00ED38 1 00 05 F0 C8
|
|
00ED40 1 01 FC E8 CA .byte $01,$FC,$E8,$CA,$01,$FC,$F0,$CB,$01,$FC,$F8,$CC,$01,$FC,$04,$F0 ; $ED40
|
|
00ED44 1 01 FC F0 CB
|
|
00ED48 1 01 FC F8 CC
|
|
00ED50 1 CD 01 F4 E8 .byte $CD,$01,$F4,$E8,$CE,$01,$FC,$F0,$CF,$01,$FC,$F8,$D0,$01,$FC,$05 ; $ED50
|
|
00ED54 1 CE 01 FC F0
|
|
00ED58 1 CF 01 FC F8
|
|
00ED60 1 E8 D1 01 FC .byte $E8,$D1,$01,$FC,$F0,$D2,$01,$FC,$F8,$D3,$01,$FC,$F0,$D4,$01,$04 ; $ED60
|
|
00ED64 1 F0 D2 01 FC
|
|
00ED68 1 F8 D3 01 FC
|
|
00ED70 1 F6 D5 01 0C .byte $F6,$D5,$01,$0C,$05,$E8,$D7,$01,$FC,$F0,$D8,$01,$FC,$F8,$D9,$01 ; $ED70
|
|
00ED74 1 05 E8 D7 01
|
|
00ED78 1 FC F0 D8 01
|
|
00ED80 1 FC F0 DA 01 .byte $FC,$F0,$DA,$01,$04,$F0,$DB,$01,$0C,$05,$E8,$DC,$01,$FC,$F0,$DD ; $ED80
|
|
00ED84 1 04 F0 DB 01
|
|
00ED88 1 0C 05 E8 DC
|
|
00ED90 1 01 FC F8 DE .byte $01,$FC,$F8,$DE,$01,$FC,$E8,$DF,$01,$04,$E5,$E0,$01,$0C,$05,$E8 ; $ED90
|
|
00ED94 1 01 FC E8 DF
|
|
00ED98 1 01 04 E5 E0
|
|
00EDA0 1 E2 01 F4 F0 .byte $E2,$01,$F4,$F0,$E3,$01,$F4,$E8,$E4,$01,$FC,$F0,$DD,$01,$FC,$F8 ; $EDA0
|
|
00EDA4 1 E3 01 F4 E8
|
|
00EDA8 1 E4 01 FC F0
|
|
00EDB0 1 DE 01 FC 00 .byte $DE,$01,$FC,$00,$05,$E8,$A5,$00,$F8,$F0,$A0,$00,$F8,$F8,$A1,$00 ; $EDB0
|
|
00EDB4 1 05 E8 A5 00
|
|
00EDB8 1 F8 F0 A0 00
|
|
00EDC0 1 FD E8 A6 00 .byte $FD,$E8,$A6,$00,$00,$F0,$A3,$00,$00,$04,$E8,$9F,$00,$FC,$F0,$A0 ; $EDC0
|
|
00EDC4 1 00 F0 A3 00
|
|
00EDC8 1 00 04 E8 9F
|
|
00EDD0 1 00 F8 F8 A1 .byte $00,$F8,$F8,$A1,$00,$FD,$F0,$A3,$00,$00,$05,$E8,$A7,$00,$F8,$F0 ; $EDD0
|
|
00EDD4 1 00 FD F0 A3
|
|
00EDD8 1 00 00 05 E8
|
|
00EDE0 1 A8 00 F8 F8 .byte $A8,$00,$F8,$F8,$A9,$00,$FE,$E8,$AA,$00,$00,$F0,$AB,$00,$00,$05 ; $EDE0
|
|
00EDE4 1 A9 00 FE E8
|
|
00EDE8 1 AA 00 00 F0
|
|
00EDF0 1 E8 AD 00 F8 .byte $E8,$AD,$00,$F8,$F0,$A8,$00,$F8,$F8,$A9,$00,$FE,$E8,$AE,$00,$00 ; $EDF0
|
|
00EDF4 1 F0 A8 00 F8
|
|
00EDF8 1 F8 A9 00 FE
|
|
00EE00 1
|
|
00EE00 1 RenderingAnimationData_EE00: ; $EE00
|
|
00EE00 1 F0 AB 00 00 .byte $F0,$AB,$00,$00,$05,$EC,$93,$00,$EC,$E8,$C3,$40,$F4,$F0,$94,$00 ; $EE00
|
|
00EE04 1 05 EC 93 00
|
|
00EE08 1 EC E8 C3 40
|
|
00EE10 1 F4 F8 C5 40 .byte $F4,$F8,$C5,$40,$F4,$F3,$C1,$40,$FC,$05,$F1,$C1,$00,$F4,$E6,$C3 ; $EE10
|
|
00EE14 1 F4 F3 C1 40
|
|
00EE18 1 FC 05 F1 C1
|
|
00EE20 1 00 FC EE C4 .byte $00,$FC,$EE,$C4,$00,$FC,$F6,$C5,$00,$FC,$E9,$C6,$00,$04,$06,$EC ; $EE20
|
|
00EE24 1 00 FC F6 C5
|
|
00EE28 1 00 FC E9 C6
|
|
00EE30 1 AF 00 F4 F8 .byte $AF,$00,$F4,$F8,$B0,$00,$F4,$EC,$B2,$00,$FC,$F4,$B3,$00,$FC,$FC ; $EE30
|
|
00EE34 1 B0 00 F4 EC
|
|
00EE38 1 B2 00 FC F4
|
|
00EE40 1 B4 00 FC F4 .byte $B4,$00,$FC,$F4,$B5,$00,$04,$06,$EC,$AF,$00,$F4,$F4,$B6,$00,$F4 ; $EE40
|
|
00EE44 1 B5 00 04 06
|
|
00EE48 1 EC AF 00 F4
|
|
00EE50 1 EC B2 00 FC .byte $EC,$B2,$00,$FC,$F4,$B3,$00,$FC,$FC,$B4,$00,$FC,$F4,$B5,$00,$04 ; $EE50
|
|
00EE54 1 F4 B3 00 FC
|
|
00EE58 1 FC B4 00 FC
|
|
00EE60 1 04 EC B7 00 .byte $04,$EC,$B7,$00,$F4,$EC,$B8,$00,$FC,$F4,$B9,$00,$FC,$FC,$BA,$00 ; $EE60
|
|
00EE64 1 F4 EC B8 00
|
|
00EE68 1 FC F4 B9 00
|
|
00EE70 1 FC 05 F0 BB .byte $FC,$05,$F0,$BB,$00,$FC,$F8,$BC,$00,$F8,$00,$BD,$00,$F8,$F8,$BF ; $EE70
|
|
00EE74 1 00 FC F8 BC
|
|
00EE78 1 00 F8 00 BD
|
|
00EE80 1 00 00 00 C0 .byte $00,$00,$00,$C0,$00,$00,$05,$E8,$E7,$00,$F8,$F0,$E8,$00,$F8,$F8 ; $EE80
|
|
00EE84 1 00 00 05 E8
|
|
00EE88 1 E7 00 F8 F0
|
|
00EE90 1 A9 00 FE E8 .byte $A9,$00,$FE,$E8,$AA,$00,$00,$F0,$E9,$00,$00,$00,$04,$F0,$68,$40 ; $EE90
|
|
00EE94 1 AA 00 00 F0
|
|
00EE98 1 E9 00 00 00
|
|
00EEA0 1 F8 F8 69 40 .byte $F8,$F8,$69,$40,$F8,$F0,$68,$00,$00,$F8,$69,$00,$00,$06,$E8,$6A ; $EEA0
|
|
00EEA4 1 F8 F0 68 00
|
|
00EEA8 1 00 F8 69 00
|
|
00EEB0 1 40 F8 F0 6B .byte $40,$F8,$F0,$6B,$40,$F8,$F8,$6C,$40,$F8,$E8,$6D,$00,$00,$F0,$6E ; $EEB0
|
|
00EEB4 1 40 F8 F8 6C
|
|
00EEB8 1 40 F8 E8 6D
|
|
00EEC0 1 00 00 F8 6F .byte $00,$00,$F8,$6F,$00,$00,$06,$E8,$6A,$40,$F8,$F0,$6B,$40,$F8,$F8 ; $EEC0
|
|
00EEC4 1 00 00 06 E8
|
|
00EEC8 1 6A 40 F8 F0
|
|
00EED0 1 6C 40 F8 E8 .byte $6C,$40,$F8,$E8,$6A,$00,$00,$F0,$6B,$00,$00,$F8,$6C,$00,$00,$05 ; $EED0
|
|
00EED4 1 6A 00 00 F0
|
|
00EED8 1 6B 00 00 F8
|
|
00EEE0 1 F1 97 00 F8 .byte $F1,$97,$00,$F8,$F9,$7E,$00,$F8,$E9,$98,$00,$FE,$F1,$10,$00,$00 ; $EEE0
|
|
00EEE4 1 F9 7E 00 F8
|
|
00EEE8 1 E9 98 00 FE
|
|
00EEF0 1 F9 81 00 00 .byte $F9,$81,$00,$00,$05,$F0,$11,$00,$F8,$F8,$83,$00,$F8,$E8,$98,$00 ; $EEF0
|
|
00EEF4 1 05 F0 11 00
|
|
00EEF8 1 F8 F8 83 00
|
|
00EF00 1
|
|
00EF00 1 RenderingAnimationData_EF00: ; $EF00
|
|
00EF00 1 FE F0 12 00 .byte $FE,$F0,$12,$00,$00,$F8,$8E,$00,$00,$05,$F0,$13,$00,$F8,$F8,$90 ; $EF00
|
|
00EF04 1 00 F8 8E 00
|
|
00EF08 1 00 05 F0 13
|
|
00EF10 1 00 F8 E8 98 .byte $00,$F8,$E8,$98,$00,$FE,$F0,$14,$00,$00,$F8,$92,$00,$00,$05,$F1 ; $EF10
|
|
00EF14 1 00 FE F0 14
|
|
00EF18 1 00 00 F8 92
|
|
00EF20 1 97 40 00 F9 .byte $97,$40,$00,$F9,$7E,$40,$00,$E9,$98,$40,$FA,$F1,$10,$40,$F8,$F9 ; $EF20
|
|
00EF24 1 7E 40 00 E9
|
|
00EF28 1 98 40 FA F1
|
|
00EF30 1 81 40 F8 05 .byte $81,$40,$F8,$05,$F0,$11,$40,$00,$F8,$83,$40,$00,$E8,$98,$40,$FA ; $EF30
|
|
00EF34 1 F0 11 40 00
|
|
00EF38 1 F8 83 40 00
|
|
00EF40 1 F0 12 40 F8 .byte $F0,$12,$40,$F8,$F8,$8E,$40,$F8,$05,$F0,$13,$40,$00,$F8,$90,$40 ; $EF40
|
|
00EF44 1 F8 8E 40 F8
|
|
00EF48 1 05 F0 13 40
|
|
00EF50 1 00 E8 98 40 .byte $00,$E8,$98,$40,$FA,$F0,$14,$40,$F8,$F8,$92,$40,$F8,$05,$F1,$7D ; $EF50
|
|
00EF54 1 FA F0 14 40
|
|
00EF58 1 F8 F8 92 40
|
|
00EF60 1 01 F8 F9 7E .byte $01,$F8,$F9,$7E,$01,$F8,$E9,$7F,$01,$00,$F1,$80,$01,$00,$F9,$81 ; $EF60
|
|
00EF64 1 01 F8 E9 7F
|
|
00EF68 1 01 00 F1 80
|
|
00EF70 1 01 00 05 F0 .byte $01,$00,$05,$F0,$82,$01,$F8,$F8,$83,$01,$F8,$E8,$7F,$01,$00,$F0 ; $EF70
|
|
00EF74 1 82 01 F8 F8
|
|
00EF78 1 83 01 F8 E8
|
|
00EF80 1 8D 01 00 F8 .byte $8D,$01,$00,$F8,$8E,$01,$00,$05,$F0,$8F,$01,$F8,$F8,$90,$01,$F8 ; $EF80
|
|
00EF84 1 8E 01 00 05
|
|
00EF88 1 F0 8F 01 F8
|
|
00EF90 1 E8 7F 01 00 .byte $E8,$7F,$01,$00,$F0,$91,$01,$00,$F8,$92,$01,$00,$04,$F0,$89,$01 ; $EF90
|
|
00EF94 1 F0 91 01 00
|
|
00EF98 1 F8 92 01 00
|
|
00EFA0 1 F8 F8 8A 01 .byte $F8,$F8,$8A,$01,$F8,$F0,$8B,$01,$00,$F8,$8C,$01,$00,$05,$F1,$7D ; $EFA0
|
|
00EFA4 1 F8 F0 8B 01
|
|
00EFA8 1 00 F8 8C 01
|
|
00EFB0 1 41 00 F9 7E .byte $41,$00,$F9,$7E,$41,$00,$E9,$7F,$41,$F8,$F1,$80,$41,$F8,$F9,$81 ; $EFB0
|
|
00EFB4 1 41 00 E9 7F
|
|
00EFB8 1 41 F8 F1 80
|
|
00EFC0 1 41 F8 05 F0 .byte $41,$F8,$05,$F0,$82,$41,$00,$F8,$83,$41,$00,$E8,$7F,$41,$F8,$F0 ; $EFC0
|
|
00EFC4 1 82 41 00 F8
|
|
00EFC8 1 83 41 00 E8
|
|
00EFD0 1 8D 41 F8 F8 .byte $8D,$41,$F8,$F8,$8E,$41,$F8,$05,$F0,$8F,$41,$00,$F8,$90,$41,$00 ; $EFD0
|
|
00EFD4 1 8E 41 F8 05
|
|
00EFD8 1 F0 8F 41 00
|
|
00EFE0 1 E8 7F 41 F8 .byte $E8,$7F,$41,$F8,$F0,$91,$41,$F8,$F8,$92,$41,$F8,$05,$F8,$99,$01 ; $EFE0
|
|
00EFE4 1 F0 91 41 F8
|
|
00EFE8 1 F8 92 41 F8
|
|
00EFF0 1 F4 F8 9A 01 .byte $F4,$F8,$9A,$01,$FC,$F0,$9B,$01,$04,$F8,$9C,$01,$04,$F8,$9D,$03 ; $EFF0
|
|
00EFF4 1 FC F0 9B 01
|
|
00EFF8 1 04 F8 9C 01
|
|
00F000 1
|
|
00F000 1 RenderingAnimationData_F000: ; $F000
|
|
00F000 1 0C 05 F8 99 .byte $0C,$05,$F8,$99,$01,$F4,$F8,$9A,$01,$FC,$F0,$9B,$01,$04,$F8,$9C ; $F000
|
|
00F004 1 01 F4 F8 9A
|
|
00F008 1 01 FC F0 9B
|
|
00F010 1 01 04 F8 9E .byte $01,$04,$F8,$9E,$03,$14,$05,$F0,$70,$41,$00,$F8,$71,$41,$00,$E8 ; $F010
|
|
00F014 1 03 14 05 F0
|
|
00F018 1 70 41 00 F8
|
|
00F020 1 72 41 F8 F0 .byte $72,$41,$F8,$F0,$73,$41,$F8,$F8,$74,$41,$F8,$05,$F0,$75,$41,$00 ; $F020
|
|
00F024 1 73 41 F8 F8
|
|
00F028 1 74 41 F8 05
|
|
00F030 1 F8 76 41 00 .byte $F8,$76,$41,$00,$E8,$72,$41,$F8,$F0,$77,$41,$F8,$F8,$78,$41,$F8 ; $F030
|
|
00F034 1 E8 72 41 F8
|
|
00F038 1 F0 77 41 F8
|
|
00F040 1 05 F1 79 41 .byte $05,$F1,$79,$41,$00,$F9,$7A,$41,$00,$E9,$72,$41,$F8,$F1,$7B,$41 ; $F040
|
|
00F044 1 00 F9 7A 41
|
|
00F048 1 00 E9 72 41
|
|
00F050 1 F8 F9 7C 41 .byte $F8,$F9,$7C,$41,$F8,$05,$E8,$84,$01,$F8,$F0,$85,$01,$F8,$F8,$86 ; $F050
|
|
00F054 1 F8 05 E8 84
|
|
00F058 1 01 F8 F0 85
|
|
00F060 1 01 F8 F0 87 .byte $01,$F8,$F0,$87,$01,$00,$F8,$88,$01,$00,$05,$F0,$70,$01,$F8,$F8 ; $F060
|
|
00F064 1 01 00 F8 88
|
|
00F068 1 01 00 05 F0
|
|
00F070 1 71 01 F8 E8 .byte $71,$01,$F8,$E8,$72,$01,$00,$F0,$73,$01,$00,$F8,$74,$01,$00,$05 ; $F070
|
|
00F074 1 72 01 00 F0
|
|
00F078 1 73 01 00 F8
|
|
00F080 1 F0 75 01 F8 .byte $F0,$75,$01,$F8,$F8,$76,$01,$F8,$E8,$72,$01,$00,$F0,$77,$01,$00 ; $F080
|
|
00F084 1 F8 76 01 F8
|
|
00F088 1 E8 72 01 00
|
|
00F090 1 F8 78 01 00 .byte $F8,$78,$01,$00,$05,$F1,$79,$01,$F8,$F9,$7A,$01,$F8,$E9,$72,$01 ; $F090
|
|
00F094 1 05 F1 79 01
|
|
00F098 1 F8 F9 7A 01
|
|
00F0A0 1 00 F1 7B 01 .byte $00,$F1,$7B,$01,$00,$F9,$7C,$01,$00,$04,$F0,$5B,$00,$F8,$F8,$5C ; $F0A0
|
|
00F0A4 1 00 F9 7C 01
|
|
00F0A8 1 00 04 F0 5B
|
|
00F0B0 1 00 F8 F0 5D .byte $00,$F8,$F0,$5D,$00,$00,$F8,$5E,$00,$00,$04,$F0,$5B,$40,$00,$F8 ; $F0B0
|
|
00F0B4 1 00 00 F8 5E
|
|
00F0B8 1 00 00 04 F0
|
|
00F0C0 1 5C 40 00 F0 .byte $5C,$40,$00,$F0,$5D,$40,$F8,$F8,$5E,$40,$F8,$04,$F0,$5F,$00,$F8 ; $F0C0
|
|
00F0C4 1 5D 40 F8 F8
|
|
00F0C8 1 5E 40 F8 04
|
|
00F0D0 1 F8 60 00 F8 .byte $F8,$60,$00,$F8,$F0,$61,$00,$00,$F8,$62,$00,$00,$05,$F0,$63,$00 ; $F0D0
|
|
00F0D4 1 F0 61 00 00
|
|
00F0D8 1 F8 62 00 00
|
|
00F0E0 1 F0 F0 64 00 .byte $F0,$F0,$64,$00,$F8,$F8,$65,$00,$F8,$F0,$66,$00,$00,$F8,$67,$00 ; $F0E0
|
|
00F0E4 1 F8 F8 65 00
|
|
00F0E8 1 F8 F0 66 00
|
|
00F0F0 1 00 05 F0 63 .byte $00,$05,$F0,$63,$40,$08,$F0,$64,$40,$00,$F8,$65,$40,$00,$F0,$66 ; $F0F0
|
|
00F0F4 1 40 08 F0 64
|
|
00F0F8 1 40 00 F8 65
|
|
00F100 1
|
|
00F100 1 RenderingAnimationData_F100: ; $F100
|
|
00F100 1 40 F8 F8 67 .byte $40,$F8,$F8,$67,$40,$F8,$04,$F0,$44,$00,$F8,$F8,$95,$00,$F8,$F0 ; $F100
|
|
00F104 1 40 F8 04 F0
|
|
00F108 1 44 00 F8 F8
|
|
00F110 1 46 00 00 F8 .byte $46,$00,$00,$F8,$96,$00,$00,$04,$F0,$40,$00,$F8,$F8,$41,$00,$F8 ; $F110
|
|
00F114 1 96 00 00 04
|
|
00F118 1 F0 40 00 F8
|
|
00F120 1 F0 42 00 00 .byte $F0,$42,$00,$00,$F8,$43,$00,$00,$04,$F0,$44,$00,$F8,$F8,$45,$00 ; $F120
|
|
00F124 1 F8 43 00 00
|
|
00F128 1 04 F0 44 00
|
|
00F130 1 F8 F0 46 00 .byte $F8,$F0,$46,$00,$00,$F8,$47,$00,$00,$05,$F1,$97,$00,$F8,$F9,$7E ; $F130
|
|
00F134 1 00 F8 47 00
|
|
00F138 1 00 05 F1 97
|
|
00F140 1 00 F8 E9 7F .byte $00,$F8,$E9,$7F,$00,$00,$F1,$10,$00,$00,$F9,$81,$00,$00,$05,$F0 ; $F140
|
|
00F144 1 00 00 F1 10
|
|
00F148 1 00 00 F9 81
|
|
00F150 1 11 00 F8 F8 .byte $11,$00,$F8,$F8,$83,$00,$F8,$E8,$7F,$00,$00,$F0,$12,$00,$00,$F8 ; $F150
|
|
00F154 1 83 00 F8 E8
|
|
00F158 1 7F 00 00 F0
|
|
00F160 1 8E 00 00 05 .byte $8E,$00,$00,$05,$F0,$13,$00,$F8,$F8,$90,$00,$F8,$E8,$7F,$00,$00 ; $F160
|
|
00F164 1 F0 13 00 F8
|
|
00F168 1 F8 90 00 F8
|
|
00F170 1 F0 14 00 00 .byte $F0,$14,$00,$00,$F8,$92,$00,$00,$05,$F1,$97,$40,$00,$F9,$7E,$40 ; $F170
|
|
00F174 1 F8 92 00 00
|
|
00F178 1 05 F1 97 40
|
|
00F180 1 00 E9 7F 40 .byte $00,$E9,$7F,$40,$F8,$F1,$10,$40,$F8,$F9,$81,$40,$F8,$05,$F0,$11 ; $F180
|
|
00F184 1 F8 F1 10 40
|
|
00F188 1 F8 F9 81 40
|
|
00F190 1 40 00 F8 83 .byte $40,$00,$F8,$83,$40,$00,$E8,$7F,$40,$F8,$F0,$12,$40,$F8,$F8,$8E ; $F190
|
|
00F194 1 40 00 E8 7F
|
|
00F198 1 40 F8 F0 12
|
|
00F1A0 1 40 F8 05 F0 .byte $40,$F8,$05,$F0,$13,$40,$00,$F8,$90,$40,$00,$E8,$7F,$40,$F8,$F0 ; $F1A0
|
|
00F1A4 1 13 40 00 F8
|
|
00F1A8 1 90 40 00 E8
|
|
00F1B0 1 14 40 F8 F8 .byte $14,$40,$F8,$F8,$92,$40,$F8,$05,$F0,$15,$40,$00,$F8,$71,$40,$00 ; $F1B0
|
|
00F1B4 1 92 40 F8 05
|
|
00F1B8 1 F0 15 40 00
|
|
00F1C0 1 E8 72 40 F8 .byte $E8,$72,$40,$F8,$F0,$E5,$40,$F8,$F8,$74,$40,$F8,$05,$F0,$15,$40 ; $F1C0
|
|
00F1C4 1 F0 E5 40 F8
|
|
00F1C8 1 F8 74 40 F8
|
|
00F1D0 1 00 F8 76 40 .byte $00,$F8,$76,$40,$00,$E8,$72,$40,$F8,$F0,$E5,$40,$F8,$F8,$78,$40 ; $F1D0
|
|
00F1D4 1 00 E8 72 40
|
|
00F1D8 1 F8 F0 E5 40
|
|
00F1E0 1 F8 05 F1 79 .byte $F8,$05,$F1,$79,$40,$00,$F9,$7A,$40,$00,$E9,$72,$40,$F8,$F1,$E6 ; $F1E0
|
|
00F1E4 1 40 00 F9 7A
|
|
00F1E8 1 40 00 E9 72
|
|
00F1F0 1 40 F8 F9 7C .byte $40,$F8,$F9,$7C,$40,$F8,$05,$F0,$15,$00,$F8,$F8,$71,$00,$F8,$E8 ; $F1F0
|
|
00F1F4 1 40 F8 05 F0
|
|
00F1F8 1 15 00 F8 F8
|
|
00F200 1
|
|
00F200 1 RenderingAnimationData_F200: ; $F200
|
|
00F200 1 72 00 00 F0 .byte $72,$00,$00,$F0,$E5,$00,$00,$F8,$74,$00,$00,$05,$F0,$15,$00,$F8 ; $F200
|
|
00F204 1 E5 00 00 F8
|
|
00F208 1 74 00 00 05
|
|
00F210 1 F8 76 00 F8 .byte $F8,$76,$00,$F8,$E8,$72,$00,$00,$F0,$E5,$00,$00,$F8,$78,$00,$00 ; $F210
|
|
00F214 1 E8 72 00 00
|
|
00F218 1 F0 E5 00 00
|
|
00F220 1 05 F1 79 00 .byte $05,$F1,$79,$00,$F8,$F9,$7A,$00,$F8,$E9,$72,$00,$00,$F1,$E6,$00 ; $F220
|
|
00F224 1 F8 F9 7A 00
|
|
00F228 1 F8 E9 72 00
|
|
00F230 1 00 F9 7C 00 .byte $00,$F9,$7C,$00,$00,$04,$F0,$48,$00,$F8,$F8,$49,$00,$F8,$F0,$4A ; $F230
|
|
00F234 1 00 04 F0 48
|
|
00F238 1 00 F8 F8 49
|
|
00F240 1 00 00 F8 4B .byte $00,$00,$F8,$4B,$00,$00,$04,$F0,$4C,$00,$F8,$F8,$4D,$00,$F8,$F0 ; $F240
|
|
00F244 1 00 00 04 F0
|
|
00F248 1 4C 00 F8 F8
|
|
00F250 1 4E 00 00 F8 .byte $4E,$00,$00,$F8,$4F,$00,$00,$04,$F0,$4C,$40,$00,$F8,$4D,$40,$00 ; $F250
|
|
00F254 1 4F 00 00 04
|
|
00F258 1 F0 4C 40 00
|
|
00F260 1 F0 4E 40 F8 .byte $F0,$4E,$40,$F8,$F8,$4F,$40,$F8,$05,$F0,$50,$00,$F8,$F8,$51,$00 ; $F260
|
|
00F264 1 F8 4F 40 F8
|
|
00F268 1 05 F0 50 00
|
|
00F270 1 F8 E8 52 00 .byte $F8,$E8,$52,$00,$00,$F0,$53,$00,$00,$F8,$54,$00,$00,$05,$F0,$50 ; $F270
|
|
00F274 1 00 F0 53 00
|
|
00F278 1 00 F8 54 00
|
|
00F280 1 00 F8 F8 55 .byte $00,$F8,$F8,$55,$00,$F8,$E8,$52,$00,$00,$F0,$53,$00,$00,$F8,$56 ; $F280
|
|
00F284 1 00 F8 E8 52
|
|
00F288 1 00 00 F0 53
|
|
00F290 1 00 00 04 F0 .byte $00,$00,$04,$F0,$84,$00,$F8,$F8,$85,$00,$F8,$F0,$86,$00,$00,$F8 ; $F290
|
|
00F294 1 84 00 F8 F8
|
|
00F298 1 85 00 F8 F0
|
|
00F2A0 1 87 00 00 04 .byte $87,$00,$00,$04,$F8,$57,$40,$04,$F0,$58,$40,$00,$F8,$59,$40,$00 ; $F2A0
|
|
00F2A4 1 F8 57 40 04
|
|
00F2A8 1 F0 58 40 00
|
|
00F2B0 1 F8 5A 40 F8 .byte $F8,$5A,$40,$F8,$06,$F0,$EA,$02,$F8,$F8,$EB,$02,$F8,$E8,$EC,$02 ; $F2B0
|
|
00F2B4 1 06 F0 EA 02
|
|
00F2B8 1 F8 F8 EB 02
|
|
00F2C0 1 00 F0 F0 02 .byte $00,$F0,$F0,$02,$00,$F8,$EE,$02,$00,$F0,$F1,$02,$08,$06,$F0,$EA ; $F2C0
|
|
00F2C4 1 00 F8 EE 02
|
|
00F2C8 1 00 F0 F1 02
|
|
00F2D0 1 02 F8 F8 EB .byte $02,$F8,$F8,$EB,$02,$F8,$E8,$EC,$02,$00,$F0,$F0,$02,$00,$F8,$EE ; $F2D0
|
|
00F2D4 1 02 F8 E8 EC
|
|
00F2D8 1 02 00 F0 F0
|
|
00F2E0 1 02 00 ED F2 .byte $02,$00,$ED,$F2,$02,$08,$04,$F0,$F4,$42,$F8,$F8,$F5,$42,$F8,$F0 ; $F2E0
|
|
00F2E4 1 02 08 04 F0
|
|
00F2E8 1 F4 42 F8 F8
|
|
00F2F0 1 F4 02 00 F8 .byte $F4,$02,$00,$F8,$F5,$02,$00,$04,$F0,$F6,$42,$F8,$F8,$F7,$42,$F8 ; $F2F0
|
|
00F2F4 1 F5 02 00 04
|
|
00F2F8 1 F0 F6 42 F8
|
|
00F300 1
|
|
00F300 1 RenderingAnimationData_F300: ; $F300
|
|
00F300 1 F0 F6 02 00 .byte $F0,$F6,$02,$00,$F8,$F7,$02,$00,$06,$F0,$EA,$02,$F8,$F8,$EB,$02 ; $F300
|
|
00F304 1 F8 F7 02 00
|
|
00F308 1 06 F0 EA 02
|
|
00F310 1 F8 E8 EC 02 .byte $F8,$E8,$EC,$02,$00,$F0,$ED,$02,$00,$F8,$EE,$02,$00,$F0,$EF,$02 ; $F310
|
|
00F314 1 00 F0 ED 02
|
|
00F318 1 00 F8 EE 02
|
|
00F320 1 08 04 F0 FC .byte $08,$04,$F0,$FC,$02,$F8,$F8,$FD,$02,$F8,$F0,$FE,$02,$00,$F8,$FF ; $F320
|
|
00F324 1 02 F8 F8 FD
|
|
00F328 1 02 F8 F0 FE
|
|
00F330 1 02 00 04 F0 .byte $02,$00,$04,$F0,$F8,$42,$F8,$F8,$F9,$42,$F8,$F0,$F8,$02,$00,$F8 ; $F330
|
|
00F334 1 F8 42 F8 F8
|
|
00F338 1 F9 42 F8 F0
|
|
00F340 1 F9 02 00 04 .byte $F9,$02,$00,$04,$F0,$FA,$42,$F8,$F8,$FB,$42,$F8,$F0,$FA,$02,$00 ; $F340
|
|
00F344 1 F0 FA 42 F8
|
|
00F348 1 F8 FB 42 F8
|
|
00F350 1 F8 FB 02 00 .byte $F8,$FB,$02,$00,$02,$F0,$1C,$01,$FC,$F8,$1D,$01,$FC,$02,$F0,$1E ; $F350
|
|
00F354 1 02 F0 1C 01
|
|
00F358 1 FC F8 1D 01
|
|
00F360 1 01 FC F8 1F .byte $01,$FC,$F8,$1F,$01,$FC,$02,$F0,$20,$01,$FC,$F8,$21,$01,$FC,$02 ; $F360
|
|
00F364 1 01 FC 02 F0
|
|
00F368 1 20 01 FC F8
|
|
00F370 1 F0 1C 41 FC .byte $F0,$1C,$41,$FC,$F8,$1D,$41,$FC,$02,$F0,$1E,$41,$FC,$F8,$1F,$41 ; $F370
|
|
00F374 1 F8 1D 41 FC
|
|
00F378 1 02 F0 1E 41
|
|
00F380 1 FC 02 F0 20 .byte $FC,$02,$F0,$20,$41,$FC,$F8,$21,$41,$FC,$02,$F0,$16,$41,$FC,$F8 ; $F380
|
|
00F384 1 41 FC F8 21
|
|
00F388 1 41 FC 02 F0
|
|
00F390 1 17 41 FC 02 .byte $17,$41,$FC,$02,$F0,$18,$41,$FC,$F8,$19,$41,$FC,$02,$F0,$1A,$41 ; $F390
|
|
00F394 1 F0 18 41 FC
|
|
00F398 1 F8 19 41 FC
|
|
00F3A0 1 FC F8 1B 41 .byte $FC,$F8,$1B,$41,$FC,$02,$F0,$16,$01,$FC,$F8,$17,$01,$FC,$02,$F0 ; $F3A0
|
|
00F3A4 1 FC 02 F0 16
|
|
00F3A8 1 01 FC F8 17
|
|
00F3B0 1 18 01 FC F8 .byte $18,$01,$FC,$F8,$19,$01,$FC,$02,$F0,$1A,$01,$FC,$F8,$1B,$01,$FC ; $F3B0
|
|
00F3B4 1 19 01 FC 02
|
|
00F3B8 1 F0 1A 01 FC
|
|
00F3C0 1 02 F0 24 00 .byte $02,$F0,$24,$00,$FC,$F8,$25,$00,$FC,$02,$F0,$22,$00,$FC,$F8,$23 ; $F3C0
|
|
00F3C4 1 FC F8 25 00
|
|
00F3C8 1 FC 02 F0 22
|
|
00F3D0 1 00 FC 02 F0 .byte $00,$FC,$02,$F0,$3D,$00,$FC,$F8,$3E,$00,$FC,$02,$F0,$00,$00,$FC ; $F3D0
|
|
00F3D4 1 3D 00 FC F8
|
|
00F3D8 1 3E 00 FC 02
|
|
00F3E0 1 F8 01 00 FC .byte $F8,$01,$00,$FC,$02,$F0,$02,$00,$FC,$F8,$03,$00,$FC,$02,$F0,$04 ; $F3E0
|
|
00F3E4 1 02 F0 02 00
|
|
00F3E8 1 FC F8 03 00
|
|
00F3F0 1 00 FC F8 05 .byte $00,$FC,$F8,$05,$00,$FC,$02,$F0,$06,$00,$FC,$F8,$07,$00,$FC,$02 ; $F3F0
|
|
00F3F4 1 00 FC 02 F0
|
|
00F3F8 1 06 00 FC F8
|
|
00F400 1
|
|
00F400 1 RenderingAnimationData_F400: ; $F400
|
|
00F400 1 F0 08 00 FC .byte $F0,$08,$00,$FC,$F8,$09,$00,$FC,$02,$F0,$0A,$40,$FC,$F8,$0B,$40 ; $F400
|
|
00F404 1 F8 09 00 FC
|
|
00F408 1 02 F0 0A 40
|
|
00F410 1 FC 02 F0 0C .byte $FC,$02,$F0,$0C,$40,$FC,$F8,$0D,$40,$FC,$02,$F0,$0E,$40,$FC,$F8 ; $F410
|
|
00F414 1 40 FC F8 0D
|
|
00F418 1 40 FC 02 F0
|
|
00F420 1 0F 40 FC 02 .byte $0F,$40,$FC,$02,$F0,$0A,$00,$FC,$F8,$0B,$00,$FC,$02,$F0,$0C,$00 ; $F420
|
|
00F424 1 F0 0A 00 FC
|
|
00F428 1 F8 0B 00 FC
|
|
00F430 1 FC F8 0D 00 .byte $FC,$F8,$0D,$00,$FC,$02,$F0,$0E,$00,$FC,$F8,$0F,$00,$FC,$02,$F0 ; $F430
|
|
00F434 1 FC 02 F0 0E
|
|
00F438 1 00 FC F8 0F
|
|
00F440 1 00 00 FC F8 .byte $00,$00,$FC,$F8,$3C,$00,$FC,$02,$F0,$28,$02,$FC,$F8,$29,$02,$FC ; $F440
|
|
00F444 1 3C 00 FC 02
|
|
00F448 1 F0 28 02 FC
|
|
00F450 1 02 F0 26 02 .byte $02,$F0,$26,$02,$FC,$F8,$27,$02,$FC,$02,$F0,$2A,$02,$FC,$F8,$2B ; $F450
|
|
00F454 1 FC F8 27 02
|
|
00F458 1 FC 02 F0 2A
|
|
00F460 1 02 FC 02 F0 .byte $02,$FC,$02,$F0,$2C,$02,$FC,$F8,$2D,$02,$FC,$02,$F0,$2E,$02,$FC ; $F460
|
|
00F464 1 2C 02 FC F8
|
|
00F468 1 2D 02 FC 02
|
|
00F470 1 F8 2D 02 FC .byte $F8,$2D,$02,$FC,$03,$F0,$31,$02,$FC,$F8,$32,$02,$FC,$F8,$33,$02 ; $F470
|
|
00F474 1 03 F0 31 02
|
|
00F478 1 FC F8 32 02
|
|
00F480 1 04 02 F0 2F .byte $04,$02,$F0,$2F,$02,$FC,$F8,$30,$02,$FC,$02,$F0,$34,$02,$FC,$F8 ; $F480
|
|
00F484 1 02 FC F8 30
|
|
00F488 1 02 FC 02 F0
|
|
00F490 1 35 02 FC 01 .byte $35,$02,$FC,$01,$F8,$36,$03,$00,$04,$FF,$36,$C3,$F8,$F7,$36,$43 ; $F490
|
|
00F494 1 F8 36 03 00
|
|
00F498 1 04 FF 36 C3
|
|
00F4A0 1 F8 FF 36 83 .byte $F8,$FF,$36,$83,$00,$F7,$36,$03,$00,$04,$FE,$37,$C3,$F8,$F6,$37 ; $F4A0
|
|
00F4A4 1 00 F7 36 03
|
|
00F4A8 1 00 04 FE 37
|
|
00F4B0 1 43 F8 FE 37 .byte $43,$F8,$FE,$37,$83,$00,$F6,$37,$03,$00,$01,$F9,$38,$03,$FD,$01 ; $F4B0
|
|
00F4B4 1 83 00 F6 37
|
|
00F4B8 1 03 00 01 F9
|
|
00F4C0 1 F8 39 03 FD .byte $F8,$39,$03,$FD,$04,$F0,$3A,$03,$F8,$F0,$3A,$43,$00,$F8,$3A,$83 ; $F4C0
|
|
00F4C4 1 04 F0 3A 03
|
|
00F4C8 1 F8 F0 3A 43
|
|
00F4D0 1 F8 F8 3A C3 .byte $F8,$F8,$3A,$C3,$00,$01,$F8,$36,$02,$00,$02,$F8,$36,$02,$00,$F8 ; $F4D0
|
|
00F4D4 1 00 01 F8 36
|
|
00F4D8 1 02 00 02 F8
|
|
00F4E0 1 36 42 F8 02 .byte $36,$42,$F8,$02,$F9,$37,$02,$00,$FF,$37,$C2,$F8,$01,$FE,$3B,$02 ; $F4E0
|
|
00F4E4 1 F9 37 02 00
|
|
00F4E8 1 FF 37 C2 F8
|
|
00F4F0 1 FC 00 3F 00 .byte $FC,$00,$3F,$00,$20,$30,$18,$1A,$07,$30,$01,$1A,$28,$30,$0F,$1A ; $F4F0
|
|
00F4F4 1 20 30 18 1A
|
|
00F4F8 1 07 30 01 1A
|
|
00F500 1
|
|
00F500 1 RenderingAnimationData_F500: ; $F500
|
|
00F500 1 30 30 0F 2C .byte $30,$30,$0F,$2C,$28,$30,$16,$27,$30,$30,$0F,$27,$30,$30,$11,$27 ; $F500
|
|
00F504 1 28 30 16 27
|
|
00F508 1 30 30 0F 27
|
|
00F510 1 0F 30 28 22 .byte $0F,$30,$28,$22,$30,$2B,$C0,$60,$00,$2B,$E0,$60,$00,$2B,$E8,$02 ; $F510
|
|
00F514 1 30 2B C0 60
|
|
00F518 1 00 2B E0 60
|
|
00F520 1 88 22 2B F0 .byte $88,$22,$2B,$F0,$02,$88,$22,$2B,$F5,$03,$88,$AA,$22,$2B,$E3,$42 ; $F520
|
|
00F524 1 02 88 22 2B
|
|
00F528 1 F5 03 88 AA
|
|
00F530 1 AA 23 E0 60 .byte $AA,$23,$E0,$60,$00,$23,$C0,$48,$FF,$23,$C8,$08,$5F,$5F,$5B,$5A ; $F530
|
|
00F534 1 00 23 C0 48
|
|
00F538 1 FF 23 C8 08
|
|
00F540 1 5A 5E 5F 5F .byte $5A,$5E,$5F,$5F,$23,$D0,$51,$55,$23,$DA,$44,$AA,$23,$E7,$01,$55 ; $F540
|
|
00F544 1 23 D0 51 55
|
|
00F548 1 23 DA 44 AA
|
|
00F550 1 23 F0 02 88 .byte $23,$F0,$02,$88,$22,$23,$F5,$03,$88,$AA,$22,$2A,$AD,$06,$B2,$34 ; $F550
|
|
00F554 1 22 23 F5 03
|
|
00F558 1 88 AA 22 2A
|
|
00F560 1 25 25 BD C0 .byte $25,$25,$BD,$C0,$2A,$CC,$08,$B0,$B3,$B6,$B9,$BB,$BE,$C1,$C4,$2A ; $F560
|
|
00F564 1 2A CC 08 B0
|
|
00F568 1 B3 B6 B9 BB
|
|
00F570 1 EB 0A B0 25 .byte $EB,$0A,$B0,$25,$B4,$B7,$BA,$BC,$21,$C2,$25,$C4,$2B,$0B,$0A,$25 ; $F570
|
|
00F574 1 B4 B7 BA BC
|
|
00F578 1 21 C2 25 C4
|
|
00F580 1 25 B5 B8 25 .byte $25,$B5,$B8,$25,$25,$BF,$C3,$25,$25,$2B,$2B,$0A,$B1,$25,$25,$B4 ; $F580
|
|
00F584 1 25 BF C3 25
|
|
00F588 1 25 2B 2B 0A
|
|
00F590 1 25 25 C2 25 .byte $25,$25,$C2,$25,$25,$C5,$2B,$4C,$08,$B1,$25,$B5,$C6,$C6,$C3,$25 ; $F590
|
|
00F594 1 25 C5 2B 4C
|
|
00F598 1 08 B1 25 B5
|
|
00F5A0 1 C5 2B 6D 06 .byte $C5,$2B,$6D,$06,$B1,$25,$25,$25,$25,$C5,$29,$4E,$04,$CB,$CC,$CD ; $F5A0
|
|
00F5A4 1 B1 25 25 25
|
|
00F5A8 1 25 C5 29 4E
|
|
00F5B0 1 CE 29 6E 04 .byte $CE,$29,$6E,$04,$CF,$27,$27,$D0,$29,$8E,$04,$D1,$D2,$D3,$D4,$29 ; $F5B0
|
|
00F5B4 1 CF 27 27 D0
|
|
00F5B8 1 29 8E 04 D1
|
|
00F5C0 1 77 06 FE FF .byte $77,$06,$FE,$FF,$DF,$E0,$C9,$CA,$29,$98,$05,$E1,$E2,$E3,$E4,$D8 ; $F5C0
|
|
00F5C4 1 DF E0 C9 CA
|
|
00F5C8 1 29 98 05 E1
|
|
00F5D0 1 29 B8 05 E5 .byte $29,$B8,$05,$E5,$E6,$E7,$E8,$E9,$29,$D8,$04,$C9,$EA,$EB,$E9,$28 ; $F5D0
|
|
00F5D4 1 E6 E7 E8 E9
|
|
00F5D8 1 29 D8 04 C9
|
|
00F5E0 1 AE 04 D5 D6 .byte $AE,$04,$D5,$D6,$D7,$D8,$28,$CE,$04,$D9,$DA,$DB,$DC,$28,$EC,$08 ; $F5E0
|
|
00F5E4 1 D7 D8 28 CE
|
|
00F5E8 1 04 D9 DA DB
|
|
00F5F0 1 FB FC FD DD .byte $FB,$FC,$FD,$DD,$DE,$FE,$FF,$49,$29,$63,$06,$C7,$C8,$EC,$ED,$FC ; $F5F0
|
|
00F5F4 1 DE FE FF 49
|
|
00F5F8 1 29 63 06 C7
|
|
00F600 1
|
|
00F600 1 RenderingAnimationData_F600: ; $F600
|
|
00F600 1 FD 29 83 05 .byte $FD,$29,$83,$05,$D5,$EE,$EF,$F0,$F1,$29,$A3,$05,$F2,$F3,$F4,$F5 ; $F600
|
|
00F604 1 D5 EE EF F0
|
|
00F608 1 F1 29 A3 05
|
|
00F610 1 F6 29 C4 04 .byte $F6,$29,$C4,$04,$F2,$F7,$F8,$C8,$29,$00,$02,$C7,$C8,$29,$21,$02 ; $F610
|
|
00F614 1 F2 F7 F8 C8
|
|
00F618 1 29 00 02 C7
|
|
00F620 1 C7 C8 29 42 .byte $C7,$C8,$29,$42,$02,$C7,$C8,$29,$E7,$02,$C7,$C8,$2A,$08,$02,$C7 ; $F620
|
|
00F624 1 02 C7 C8 29
|
|
00F628 1 E7 02 C7 C8
|
|
00F630 1 C8 2A 29 02 .byte $C8,$2A,$29,$02,$C7,$C8,$2A,$4A,$02,$C7,$C8,$2A,$6B,$02,$C7,$C8 ; $F630
|
|
00F634 1 C7 C8 2A 4A
|
|
00F638 1 02 C7 C8 2A
|
|
00F640 1 2A 8C 02 C7 .byte $2A,$8C,$02,$C7,$C8,$2A,$92,$02,$C9,$CA,$2A,$73,$02,$C9,$CA,$2A ; $F640
|
|
00F644 1 C8 2A 92 02
|
|
00F648 1 C9 CA 2A 73
|
|
00F650 1 54 02 C9 CA .byte $54,$02,$C9,$CA,$2A,$35,$02,$C9,$CA,$2A,$16,$02,$C9,$CA,$29,$F7 ; $F650
|
|
00F654 1 2A 35 02 C9
|
|
00F658 1 CA 2A 16 02
|
|
00F660 1 02 C9 CA 29 .byte $02,$C9,$CA,$29,$5C,$02,$C9,$CA,$29,$3D,$02,$C9,$CA,$29,$1E,$02 ; $F660
|
|
00F664 1 5C 02 C9 CA
|
|
00F668 1 29 3D 02 C9
|
|
00F670 1 C9 CA 29 48 .byte $C9,$CA,$29,$48,$02,$F9,$FA,$29,$29,$03,$FB,$FC,$FD,$29,$0B,$02 ; $F670
|
|
00F674 1 02 F9 FA 29
|
|
00F678 1 29 03 FB FC
|
|
00F680 1 F9 FA 29 13 .byte $F9,$FA,$29,$13,$02,$4A,$4B,$29,$34,$03,$FE,$FF,$49,$29,$56,$02 ; $F680
|
|
00F684 1 02 4A 4B 29
|
|
00F688 1 34 03 FE FF
|
|
00F690 1 4A 4B 2A 83 .byte $4A,$4B,$2A,$83,$01,$3B,$2B,$02,$83,$0B,$1C,$18,$2A,$A3,$C6,$25 ; $F690
|
|
00F694 1 01 3B 2B 02
|
|
00F698 1 83 0B 1C 18
|
|
00F6A0 1 2A A4 C6 25 .byte $2A,$A4,$C6,$25,$2A,$A5,$C6,$25,$2A,$E2,$44,$26,$2A,$A5,$C2,$00 ; $F6A0
|
|
00F6A4 1 2A A5 C6 25
|
|
00F6A8 1 2A E2 44 26
|
|
00F6B0 1 2B 16 48 25 .byte $2B,$16,$48,$25,$2B,$36,$48,$25,$2B,$56,$48,$25,$20,$4A,$4C,$37 ; $F6B0
|
|
00F6B4 1 2B 36 48 25
|
|
00F6B8 1 2B 56 48 25
|
|
00F6C0 1 20 6A 0C 33 .byte $20,$6A,$0C,$33,$29,$2A,$2B,$2C,$2D,$2E,$2F,$30,$31,$33,$35,$20 ; $F6C0
|
|
00F6C4 1 29 2A 2B 2C
|
|
00F6C8 1 2D 2E 2F 30
|
|
00F6D0 1 8A 4B 33 20 .byte $8A,$4B,$33,$20,$AA,$4B,$33,$20,$95,$C2,$28,$20,$56,$84,$C8,$36 ; $F6D0
|
|
00F6D4 1 AA 4B 33 20
|
|
00F6D8 1 95 C2 28 20
|
|
00F6E0 1 36 36 20 A4 .byte $36,$36,$20,$A4,$05,$38,$26,$38,$26,$38,$20,$B7,$05,$38,$26,$38 ; $F6E0
|
|
00F6E4 1 05 38 26 38
|
|
00F6E8 1 26 38 20 B7
|
|
00F6F0 1 26 38 20 C0 .byte $26,$38,$20,$C0,$60,$6A,$20,$E0,$7F,$6B,$21,$1F,$66,$6B,$21,$5B ; $F6F0
|
|
00F6F4 1 60 6A 20 E0
|
|
00F6F8 1 7F 6B 21 1F
|
|
00F700 1
|
|
00F700 1 RenderingAnimationData_F700: ; $F700
|
|
00F700 1 47 6B 20 C8 .byte $47,$6B,$20,$C8,$03,$53,$50,$40,$20,$CB,$4A,$41,$20,$D5,$03,$42 ; $F700
|
|
00F704 1 03 53 50 40
|
|
00F708 1 20 CB 4A 41
|
|
00F710 1 70 73 20 E8 .byte $70,$73,$20,$E8,$03,$54,$50,$43,$20,$EB,$4A,$25,$20,$F5,$03,$43 ; $F710
|
|
00F714 1 03 54 50 43
|
|
00F718 1 20 EB 4A 25
|
|
00F720 1 70 74 21 09 .byte $70,$74,$21,$09,$03,$51,$44,$45,$21,$0C,$48,$46,$21,$14,$03,$47 ; $F720
|
|
00F724 1 03 51 44 45
|
|
00F728 1 21 0C 48 46
|
|
00F730 1 48 71 21 28 .byte $48,$71,$21,$28,$10,$55,$52,$56,$57,$17,$12,$17,$1D,$0E,$17,$0D ; $F730
|
|
00F734 1 10 55 52 56
|
|
00F738 1 57 17 12 17
|
|
00F740 1 18 77 76 72 .byte $18,$77,$76,$72,$75,$21,$45,$07,$58,$59,$5A,$5B,$5C,$5D,$5E,$21 ; $F740
|
|
00F744 1 75 21 45 07
|
|
00F748 1 58 59 5A 5B
|
|
00F750 1 54 07 7E 7D .byte $54,$07,$7E,$7D,$7C,$7B,$7A,$79,$78,$21,$63,$05,$62,$61,$25,$5F ; $F750
|
|
00F754 1 7C 7B 7A 79
|
|
00F758 1 78 21 63 05
|
|
00F760 1 60 21 78 0F .byte $60,$21,$78,$0F,$80,$7F,$25,$81,$82,$87,$6B,$6B,$6B,$62,$63,$25 ; $F760
|
|
00F764 1 80 7F 25 81
|
|
00F768 1 82 87 6B 6B
|
|
00F770 1 25 24 23 21 .byte $25,$24,$23,$21,$99,$0C,$1A,$1F,$25,$25,$83,$82,$6B,$61,$25,$64 ; $F770
|
|
00F774 1 99 0C 1A 1F
|
|
00F778 1 25 25 83 82
|
|
00F780 1 25 66 21 BB .byte $25,$66,$21,$BB,$09,$86,$25,$84,$25,$81,$25,$25,$64,$66,$21,$DC ; $F780
|
|
00F784 1 09 86 25 84
|
|
00F788 1 25 81 25 25
|
|
00F790 1 07 86 84 25 .byte $07,$86,$84,$25,$25,$25,$25,$65,$21,$FD,$07,$85,$25,$25,$25,$66 ; $F790
|
|
00F794 1 25 25 25 65
|
|
00F798 1 21 FD 07 85
|
|
00F7A0 1 6E 6F 22 1C .byte $6E,$6F,$22,$1C,$0A,$4E,$4F,$86,$25,$66,$26,$26,$26,$6C,$6D,$20 ; $F7A0
|
|
00F7A4 1 0A 4E 4F 86
|
|
00F7A8 1 25 66 26 26
|
|
00F7B0 1 82 88 69 69 .byte $82,$88,$69,$69,$68,$67,$67,$67,$67,$67,$20,$9D,$87,$89,$89,$88 ; $F7B0
|
|
00F7B4 1 68 67 67 67
|
|
00F7B8 1 67 67 20 9D
|
|
00F7C0 1 87 87 87 87 .byte $87,$87,$87,$87,$22,$2E,$04,$8A,$8B,$8C,$8D,$22,$3A,$06,$4C,$4D ; $F7C0
|
|
00F7C4 1 22 2E 04 8A
|
|
00F7C8 1 8B 8C 8D 22
|
|
00F7D0 1 26 26 26 86 .byte $26,$26,$26,$86,$22,$45,$02,$6E,$6F,$22,$4D,$06,$AA,$AB,$8E,$8F ; $F7D0
|
|
00F7D4 1 22 45 02 6E
|
|
00F7D8 1 6F 22 4D 06
|
|
00F7E0 1 A8 A9 22 59 .byte $A8,$A9,$22,$59,$02,$4E,$4F,$22,$67,$12,$6C,$6D,$26,$26,$AA,$AB ; $F7E0
|
|
00F7E4 1 02 4E 4F 22
|
|
00F7E8 1 67 12 6C 6D
|
|
00F7F0 1 26 26 9C 9E .byte $26,$26,$9C,$9E,$26,$26,$A8,$A9,$26,$26,$4C,$4D,$22,$88,$03,$6E ; $F7F0
|
|
00F7F4 1 26 26 A8 A9
|
|
00F7F8 1 26 26 4C 4D
|
|
00F800 1
|
|
00F800 1 RenderingAnimationData_F800: ; $F800
|
|
00F800 1 A4 A6 22 8F .byte $A4,$A6,$22,$8F,$02,$9D,$9F,$22,$95,$03,$A0,$A2,$4F,$22,$A9,$03 ; $F800
|
|
00F804 1 02 9D 9F 22
|
|
00F808 1 95 03 A0 A2
|
|
00F810 1 A5 A7 6D 22 .byte $A5,$A7,$6D,$22,$B4,$03,$4C,$A1,$A3,$22,$CB,$02,$6E,$6F,$22,$D3 ; $F810
|
|
00F814 1 B4 03 4C A1
|
|
00F818 1 A3 22 CB 02
|
|
00F820 1 02 4E 4F 22 .byte $02,$4E,$4F,$22,$ED,$06,$6C,$6D,$26,$26,$4C,$4D,$23,$0E,$04,$90 ; $F820
|
|
00F824 1 ED 06 6C 6D
|
|
00F828 1 26 26 4C 4D
|
|
00F830 1 93 96 99 23 .byte $93,$96,$99,$23,$2E,$04,$91,$94,$97,$9A,$23,$4E,$04,$92,$95,$98 ; $F830
|
|
00F834 1 2E 04 91 94
|
|
00F838 1 97 9A 23 4E
|
|
00F840 1 9B 23 02 83 .byte $9B,$23,$02,$83,$0B,$1C,$18,$23,$03,$43,$25,$23,$23,$43,$25,$23 ; $F840
|
|
00F844 1 0B 1C 18 23
|
|
00F848 1 03 43 25 23
|
|
00F850 1 43 43 25 23 .byte $43,$43,$25,$23,$16,$48,$25,$23,$36,$48,$25,$23,$56,$48,$25,$21 ; $F850
|
|
00F854 1 16 48 25 23
|
|
00F858 1 36 48 25 23
|
|
00F860 1 88 10 1C 0E .byte $88,$10,$1C,$0E,$15,$0E,$0C,$1D,$25,$22,$18,$1E,$1B,$25,$1D,$0E ; $F860
|
|
00F864 1 15 0E 0C 1D
|
|
00F868 1 25 22 18 1E
|
|
00F870 1 0A 16 21 A8 .byte $0A,$16,$21,$A8,$50,$25,$21,$C8,$50,$25,$21,$CA,$0B,$0A,$25,$0C ; $F870
|
|
00F874 1 50 25 21 C8
|
|
00F878 1 50 25 21 CA
|
|
00F880 1 25 0D 25 19 .byte $25,$0D,$25,$19,$25,$1B,$25,$22,$21,$E8,$50,$25,$00,$3F,$00,$14 ; $F880
|
|
00F884 1 25 1B 25 22
|
|
00F888 1 21 E8 50 25
|
|
00F890 1 0F 0F 11 30 .byte $0F,$0F,$11,$30,$0F,$0F,$0F,$24,$0F,$0F,$0F,$27,$0F,$0F,$0F,$30 ; $F890
|
|
00F894 1 0F 0F 0F 24
|
|
00F898 1 0F 0F 0F 27
|
|
00F8A0 1 0F 0F 11 30 .byte $0F,$0F,$11,$30,$23,$C0,$6A,$00,$23,$EA,$01,$99,$23,$EB,$45,$AA ; $F8A0
|
|
00F8A4 1 23 C0 6A 00
|
|
00F8A8 1 23 EA 01 99
|
|
00F8B0 1 23 F0 50 FF .byte $23,$F0,$50,$FF,$20,$A4,$53,$AE,$20,$E4,$53,$AE,$21,$24,$53,$AE ; $F8B0
|
|
00F8B4 1 20 A4 53 AE
|
|
00F8B8 1 20 E4 53 AE
|
|
00F8C0 1 21 69 48 AE .byte $21,$69,$48,$AE,$21,$A9,$49,$AE,$21,$E9,$43,$AE,$21,$F3,$49,$AE ; $F8C0
|
|
00F8C4 1 21 A9 49 AE
|
|
00F8C8 1 21 E9 43 AE
|
|
00F8D0 1 20 A4 C5 AE .byte $20,$A4,$C5,$AE,$20,$C9,$CA,$AE,$20,$CC,$C4,$AE,$21,$8E,$C4,$AE ; $F8D0
|
|
00F8D4 1 20 C9 CA AE
|
|
00F8D8 1 20 CC C4 AE
|
|
00F8E0 1 21 91 C4 AE .byte $21,$91,$C4,$AE,$20,$B3,$CB,$AE,$21,$78,$C5,$AE,$20,$A7,$48,$25 ; $F8E0
|
|
00F8E4 1 20 B3 CB AE
|
|
00F8E8 1 21 78 C5 AE
|
|
00F8F0 1 20 E7 42 25 .byte $20,$E7,$42,$25,$21,$27,$42,$25,$21,$2A,$42,$25,$21,$6C,$47,$25 ; $F8F0
|
|
00F8F4 1 21 27 42 25
|
|
00F8F8 1 21 2A 42 25
|
|
00F900 1
|
|
00F900 1 RenderingAnimationData_F900: ; $F900
|
|
00F900 1 21 AC 42 25 .byte $21,$AC,$42,$25,$21,$F7,$01,$25,$21,$49,$4B,$25,$20,$ED,$C3,$25 ; $F900
|
|
00F904 1 21 F7 01 25
|
|
00F908 1 21 49 4B 25
|
|
00F910 1 20 B2 C5 25 .byte $20,$B2,$C5,$25,$20,$AE,$C5,$25,$20,$B1,$C5,$25,$20,$63,$5A,$26 ; $F910
|
|
00F914 1 20 AE C5 25
|
|
00F918 1 20 B1 C5 25
|
|
00F920 1 22 23 5A 26 .byte $22,$23,$5A,$26,$20,$82,$CD,$26,$20,$9D,$CD,$26,$22,$AA,$0D,$01 ; $F920
|
|
00F924 1 20 82 CD 26
|
|
00F928 1 20 9D CD 26
|
|
00F930 1 25 19 15 0A .byte $25,$19,$15,$0A,$22,$0E,$1B,$25,$10,$0A,$16,$0E,$22,$EA,$0D,$02 ; $F930
|
|
00F934 1 22 0E 1B 25
|
|
00F938 1 10 0A 16 0E
|
|
00F940 1 25 19 15 0A .byte $25,$19,$15,$0A,$22,$0E,$1B,$25,$10,$0A,$16,$0E,$00 ; $F940
|
|
00F944 1 22 0E 1B 25
|
|
00F948 1 10 0A 16 0E
|
|
00F94D 1
|
|
00F94D 1 FrameOamTemplate_F94D: ; $F94D
|
|
00F94D 1 ; 22 OAM entries x 4 bytes = 88 bytes.
|
|
00F94D 1 ; Entry format: Y, tile, attributes, X.
|
|
00F94D 1 2F AE 00 34 .byte $2F,$AE,$00,$34,$3B,$AE,$00,$38,$43,$AE,$00,$38,$27,$AE,$00,$4C ; $F94D
|
|
00F951 1 3B AE 00 38
|
|
00F955 1 43 AE 00 38
|
|
00F95D 1 27 AE 00 54 .byte $27,$AE,$00,$54,$27,$AE,$00,$5C,$2B,$AE,$00,$70,$33,$AE,$00,$70 ; $F95D
|
|
00F961 1 27 AE 00 5C
|
|
00F965 1 2B AE 00 70
|
|
00F96D 1 43 AE 00 70 .byte $43,$AE,$00,$70,$2B,$AE,$00,$88,$3B,$AE,$00,$88,$43,$AE,$00,$88 ; $F96D
|
|
00F971 1 2B AE 00 88
|
|
00F975 1 3B AE 00 88
|
|
00F97D 1 5F AE 00 5C .byte $5F,$AE,$00,$5C,$6B,$AE,$00,$60,$73,$AE,$00,$60,$57,$AE,$00,$74 ; $F97D
|
|
00F981 1 6B AE 00 60
|
|
00F985 1 73 AE 00 60
|
|
00F98D 1 57 AE 00 7C .byte $57,$AE,$00,$7C,$57,$AE,$00,$84,$17,$13,$00,$10,$17,$13,$40,$E8 ; $F98D
|
|
00F991 1 57 AE 00 84
|
|
00F995 1 17 13 00 10
|
|
00F99D 1 87 13 80 10 .byte $87,$13,$80,$10,$87,$13,$C0,$E8 ; $F99D
|
|
00F9A1 1 87 13 C0 E8
|
|
00F9A5 1
|
|
00F9A5 1 RenderingAnimationData_F9A5: ; $F9A5
|
|
00F9A5 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; $F9A5
|
|
00F9A9 1 FF FF FF FF
|
|
00F9AD 1 FF FF FF FF
|
|
00F9B5 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; $F9B5
|
|
00F9B9 1 FF FF FF FF
|
|
00F9BD 1 FF FF FF FF
|
|
00F9C5 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; $F9C5
|
|
00F9C9 1 FF FF FF FF
|
|
00F9CD 1 FF FF FF
|
|
00F9D0 1
|
|
00F9D0 1 ; ============================================================================
|
|
00F9D0 1 ; $F9D0-$F9F4
|
|
00F9D0 1 ; Initialize the audio engine and APU output state.
|
|
00F9D0 1 ;
|
|
00F9D0 1 ; Operation:
|
|
00F9D0 1 ; 1. Configure the APU frame counter.
|
|
00F9D0 1 ; 2. Initialize the main audio subsystem through $FB05.
|
|
00F9D0 1 ; 3. Clear three audio/engine state bytes.
|
|
00F9D0 1 ; 4. Decrement the startup value at $07FF up to two times.
|
|
00F9D0 1 ; 5. Write the resulting value to the APU DMC direct-load register.
|
|
00F9D0 1 ;
|
|
00F9D0 1 ; Exit:
|
|
00F9D0 1 ; A = final value from $07FF
|
|
00F9D0 1 ; ============================================================================
|
|
00F9D0 1
|
|
00F9D0 1 ; ----------------------------------------------------------------------------
|
|
00F9D0 1 ; Contract:
|
|
00F9D0 1 ; Description: Initializes Audio Engine.
|
|
00F9D0 1 ; Entry: Registers: A; Memory: $07ff
|
|
00F9D0 1 ; Returns/products: Registers/clobbers: A
|
|
00F9D0 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00F9D0 1 ; Memory effects: $4017, $ff, pendingaudioflags, $fd, $4011
|
|
00F9D0 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00F9D0 1 ; comparison, load, or store path and are not a stable API product.
|
|
00F9D0 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00F9D0 1 ; ----------------------------------------------------------------------------
|
|
00F9D0 1 InitializeAudioEngine: ; $F9D0
|
|
00F9D0 1 A9 C0 lda #$C0 ; $F9D0: A9 C0
|
|
00F9D2 1 8D 17 40 sta $4017 ; $F9D2: 8D 17 40
|
|
00F9D5 1 ; Configure the APU frame counter:
|
|
00F9D5 1 ; bit 7 = five-step sequence
|
|
00F9D5 1 ; bit 6 = inhibit frame IRQ
|
|
00F9D5 1
|
|
00F9D5 1 ; ----------------------------------------------------------------------------
|
|
00F9D5 1 ; Initialize the remaining audio subsystem state.
|
|
00F9D5 1 ; ----------------------------------------------------------------------------
|
|
00F9D5 1
|
|
00F9D5 1 20 05 FB jsr UpdateAudioEngine ; $F9D5: 20 05 FB
|
|
00F9D8 1
|
|
00F9D8 1 ; ----------------------------------------------------------------------------
|
|
00F9D8 1 ; Clear shared audio and engine state.
|
|
00F9D8 1 ; ----------------------------------------------------------------------------
|
|
00F9D8 1
|
|
00F9D8 1 A9 00 lda #$00 ; $F9D8: A9 00
|
|
00F9DA 1
|
|
00F9DA 1 85 FF sta RenderStateFlags ; $F9DA: 85 FF
|
|
00F9DC 1 85 FE sta PendingAudioFlags ; $F9DC: 85 FE
|
|
00F9DE 1 85 FD sta $FD ; $F9DE: 85 FD
|
|
00F9E0 1
|
|
00F9E0 1 ; ----------------------------------------------------------------------------
|
|
00F9E0 1 ; Apply a short two-step countdown to the value at $07FF.
|
|
00F9E0 1 ;
|
|
00F9E0 1 ; If the initial value is zero:
|
|
00F9E0 1 ; no decrement occurs.
|
|
00F9E0 1 ;
|
|
00F9E0 1 ; If the initial value is one:
|
|
00F9E0 1 ; one decrement occurs, producing zero.
|
|
00F9E0 1 ;
|
|
00F9E0 1 ; If the initial value is two or greater:
|
|
00F9E0 1 ; two decrements occur.
|
|
00F9E0 1 ; ----------------------------------------------------------------------------
|
|
00F9E0 1
|
|
00F9E0 1 AD FF 07 lda $07FF ; $F9E0: AD FF 07
|
|
00F9E3 1 F0 08 beq InitializeAudioEngine_WriteDmc
|
|
00F9E5 1 ; $F9E3: F0 08
|
|
00F9E5 1
|
|
00F9E5 1 CE FF 07 dec $07FF ; $F9E5: CE FF 07
|
|
00F9E8 1 F0 03 beq InitializeAudioEngine_WriteDmc
|
|
00F9EA 1 ; $F9E8: F0 03
|
|
00F9EA 1
|
|
00F9EA 1 CE FF 07 dec $07FF ; $F9EA: CE FF 07
|
|
00F9ED 1
|
|
00F9ED 1 ; ----------------------------------------------------------------------------
|
|
00F9ED 1 ; Write the resulting value to the APU DMC direct-load register.
|
|
00F9ED 1 ;
|
|
00F9ED 1 ; $4011 controls the seven-bit DMC output level.
|
|
00F9ED 1 ; ----------------------------------------------------------------------------
|
|
00F9ED 1
|
|
00F9ED 1 InitializeAudioEngine_WriteDmc: ; $F9ED
|
|
00F9ED 1 AD FF 07 lda $07FF ; $F9ED: AD FF 07
|
|
00F9F0 1 8D 11 40 sta $4011 ; $F9F0: 8D 11 40
|
|
00F9F3 1
|
|
00F9F3 1 60 rts ; $F9F3: 60
|
|
00F9F4 1
|
|
00F9F4 1 ; ============================================================================
|
|
00F9F4 1 ; $F9F4-$F9FF
|
|
00F9F4 1 ; Unused/padding bytes.
|
|
00F9F4 1 ; ============================================================================
|
|
00F9F4 1
|
|
00F9F4 1 AudioPadding_F9F4: ; $F9F4
|
|
00F9F4 1 FF FF FF FF .byte $FF,$FF,$FF,$FF
|
|
00F9F8 1 FF FF FF FF .byte $FF,$FF,$FF,$FF
|
|
00F9FC 1 FF FF FF FF .byte $FF,$FF,$FF,$FF
|
|
00FA00 1
|
|
00FA00 1 ; ============================================================================
|
|
00FA00 1 ; $FA00-$FA5F
|
|
00FA00 1 ; Audio engine lookup data.
|
|
00FA00 1 ;
|
|
00FA00 1 ; This region contains several adjacent tables used by the audio routines that
|
|
00FA00 1 ; follow. The first portion consists primarily of little-endian timer or period
|
|
00FA00 1 ; values, followed by smaller rhythm, duration, envelope, or index tables.
|
|
00FA00 1 ;
|
|
00FA00 1 ; Keep the exact byte layout because later routines reference internal
|
|
00FA00 1 ; addresses such as $FA01 and $FA4A directly.
|
|
00FA00 1 ; ============================================================================
|
|
00FA00 1
|
|
00FA00 1 AudioLookupData_FA00: ; $FA00
|
|
00FA00 1 07 F0 00 69 .byte $07,$F0,$00,$69,$00,$00,$00,$D4
|
|
00FA04 1 00 00 00 D4
|
|
00FA08 1 00 BD 00 B2 .byte $00,$BD,$00,$B2,$00,$A8,$00,$9F
|
|
00FA0C 1 00 A8 00 9F
|
|
00FA10 1 00 96 00 8D .byte $00,$96,$00,$8D,$00,$7E,$00,$70
|
|
00FA14 1 00 7E 00 70
|
|
00FA18 1 01 AB 01 93 .byte $01,$AB,$01,$93,$01,$7C,$01,$67
|
|
00FA1C 1 01 7C 01 67
|
|
00FA20 1 01 52 01 3F .byte $01,$52,$01,$3F,$01,$2D,$01,$1C
|
|
00FA24 1 01 2D 01 1C
|
|
00FA28 1 01 0C 00 FD .byte $01,$0C,$00,$FD,$00,$EE,$00,$E1
|
|
00FA2C 1 00 EE 00 E1
|
|
00FA30 1 03 57 02 F9 .byte $03,$57,$02,$F9,$02,$A6,$02,$80
|
|
00FA34 1 02 A6 02 80
|
|
00FA38 1 02 3A 01 FC .byte $02,$3A,$01,$FC,$01,$C4,$00,$5E
|
|
00FA3C 1 01 C4 00 5E
|
|
00FA40 1 00 53 00 4F .byte $00,$53,$00,$4F,$00,$4A,$00,$3E
|
|
00FA44 1 00 4A 00 3E
|
|
00FA48 1 00 20 05 0A .byte $00,$20,$05,$0A,$14,$28,$0D,$21
|
|
00FA4C 1 14 28 0D 21
|
|
00FA50 1 06 07 06 0C .byte $06,$07,$06,$0C,$18,$30,$10,$24
|
|
00FA54 1 18 30 10 24
|
|
00FA58 1 48 08 FF FF .byte $48,$08,$FF,$FF,$FF,$FF,$FF,$FF
|
|
00FA5C 1 FF FF FF FF
|
|
00FA60 1
|
|
00FA60 1 ; ============================================================================
|
|
00FA60 1 ; Useful internal table bases referenced by later audio routines.
|
|
00FA60 1 ; ============================================================================
|
|
00FA60 1
|
|
00FA60 1 ApuTimerTableHighBytes = $FA00
|
|
00FA60 1 ApuTimerTableLowBytes = $FA01
|
|
00FA60 1
|
|
00FA60 1 NoteDurationTable = $FA4A
|
|
00FA60 1 ; ============================================================================
|
|
00FA60 1 ; $FA60-$FA70
|
|
00FA60 1 ; Write preset or caller-supplied control values to pulse channel 1.
|
|
00FA60 1 ; ============================================================================
|
|
00FA60 1
|
|
00FA60 1 ConfigurePulse1ControlPreset: ; $FA60
|
|
00FA60 1 A2 90 ldx #$90 ; $FA60: A2 90
|
|
00FA62 1 D0 09 bne WritePulse1Control ; $FA62: D0 09
|
|
00FA64 1 ; Target $FA6D.
|
|
00FA64 1
|
|
00FA64 1 ; ============================================================================
|
|
00FA64 1 ; $FA64-$FA67
|
|
00FA64 1 ; Write preset control value $90 to pulse channel 2.
|
|
00FA64 1 ; ============================================================================
|
|
00FA64 1
|
|
00FA64 1 ConfigurePulse2ControlPreset: ; $FA64
|
|
00FA64 1 A2 90 ldx #$90 ; $FA64: A2 90
|
|
00FA66 1 D0 0E bne WritePulse2Control ; $FA66: D0 0E
|
|
00FA68 1 ; Target $FA76.
|
|
00FA68 1
|
|
00FA68 1 ; ============================================================================
|
|
00FA68 1 ; $FA68-$FA70
|
|
00FA68 1 ; Write a caller-supplied pulse 1 control value and reset its sweep state.
|
|
00FA68 1 ;
|
|
00FA68 1 ; Entry:
|
|
00FA68 1 ; X = value for $4000
|
|
00FA68 1 ; ============================================================================
|
|
00FA68 1
|
|
00FA68 1 ; ----------------------------------------------------------------------------
|
|
00FA68 1 ; Contract:
|
|
00FA68 1 ; Description: Writes Pulse 1 Sweep And Control.
|
|
00FA68 1 ; Entry: Registers: X, Y
|
|
00FA68 1 ; Returns/products: Registers/clobbers: Y
|
|
00FA68 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FA68 1 ; Memory effects: $4001, $4000
|
|
00FA68 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FA68 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FA68 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00FA68 1 ; ----------------------------------------------------------------------------
|
|
00FA68 1 WritePulse1SweepAndControl: ; $FA68
|
|
00FA68 1 A0 7F ldy #$7F ; $FA68: A0 7F
|
|
00FA6A 1 ; ----------------------------------------------------------------------------
|
|
00FA6A 1 ; Contract:
|
|
00FA6A 1 ; Description: Internal pulse-1 register writer.
|
|
00FA6A 1 ; Entry: Y = sweep value; X = control value.
|
|
00FA6A 1 ; Returns/products: APU $4001/$4000 written.
|
|
00FA6A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FA6A 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FA6A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FA6A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FA6A 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00FA6A 1 ; ----------------------------------------------------------------------------
|
|
00FA6A 1 WritePulse1SweepAndControlFromRegisters:
|
|
00FA6A 1 8C 01 40 sty $4001 ; $FA6A: 8C 01 40
|
|
00FA6D 1
|
|
00FA6D 1 WritePulse1Control: ; $FA6D
|
|
00FA6D 1 8E 00 40 stx $4000 ; $FA6D: 8E 00 40
|
|
00FA70 1 60 rts ; $FA70: 60
|
|
00FA71 1
|
|
00FA71 1 ; ============================================================================
|
|
00FA71 1 ; $FA71-$FA79
|
|
00FA71 1 ; Write a caller-supplied pulse 2 control value and reset its sweep state.
|
|
00FA71 1 ;
|
|
00FA71 1 ; Entry:
|
|
00FA71 1 ; X = value for $4004
|
|
00FA71 1 ; ============================================================================
|
|
00FA71 1
|
|
00FA71 1 ; ----------------------------------------------------------------------------
|
|
00FA71 1 ; Contract:
|
|
00FA71 1 ; Description: Writes Pulse 2 Sweep And Control.
|
|
00FA71 1 ; Entry: Registers: X, Y
|
|
00FA71 1 ; Returns/products: Registers/clobbers: Y
|
|
00FA71 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FA71 1 ; Memory effects: $4005, $4004
|
|
00FA71 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FA71 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FA71 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00FA71 1 ; ----------------------------------------------------------------------------
|
|
00FA71 1 WritePulse2SweepAndControl: ; $FA71
|
|
00FA71 1 A0 7F ldy #$7F ; $FA71: A0 7F
|
|
00FA73 1 ; ----------------------------------------------------------------------------
|
|
00FA73 1 ; Contract:
|
|
00FA73 1 ; Description: Internal pulse-2 register writer.
|
|
00FA73 1 ; Entry: Y = sweep value; X = control value.
|
|
00FA73 1 ; Returns/products: APU $4005/$4004 written.
|
|
00FA73 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FA73 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FA73 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FA73 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FA73 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00FA73 1 ; ----------------------------------------------------------------------------
|
|
00FA73 1 WritePulse2SweepAndControlFromRegisters:
|
|
00FA73 1 8C 05 40 sty $4005 ; $FA73: 8C 05 40
|
|
00FA76 1
|
|
00FA76 1 WritePulse2Control: ; $FA76
|
|
00FA76 1 8E 04 40 stx $4004 ; $FA76: 8E 04 40
|
|
00FA79 1 60 rts ; $FA79: 60
|
|
00FA7A 1
|
|
00FA7A 1 ; ============================================================================
|
|
00FA7A 1 ; $FA7A-$FA85
|
|
00FA7A 1 ; Configure the APU noise channel.
|
|
00FA7A 1 ;
|
|
00FA7A 1 ; Entry:
|
|
00FA7A 1 ; A = volume and envelope value for $400C
|
|
00FA7A 1 ; X = noise period and mode value for $400E
|
|
00FA7A 1 ;
|
|
00FA7A 1 ; Operation:
|
|
00FA7A 1 ; The fixed value $08 is written to $400F to reload the noise channel's
|
|
00FA7A 1 ; length counter.
|
|
00FA7A 1 ; ============================================================================
|
|
00FA7A 1
|
|
00FA7A 1 ; ----------------------------------------------------------------------------
|
|
00FA7A 1 ; Contract:
|
|
00FA7A 1 ; Description: Implements Configure Noise Channel.
|
|
00FA7A 1 ; Entry: Registers: A, X, Y
|
|
00FA7A 1 ; Returns/products: Registers/clobbers: Y
|
|
00FA7A 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FA7A 1 ; Memory effects: $400c, $400e, $400f
|
|
00FA7A 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FA7A 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FA7A 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00FA7A 1 ; ----------------------------------------------------------------------------
|
|
00FA7A 1 ConfigureNoiseChannel: ; $FA7A
|
|
00FA7A 1 8D 0C 40 sta $400C ; $FA7A: 8D 0C 40
|
|
00FA7D 1 ; Noise volume and envelope control.
|
|
00FA7D 1
|
|
00FA7D 1 8E 0E 40 stx $400E ; $FA7D: 8E 0E 40
|
|
00FA80 1 ; Noise mode and period.
|
|
00FA80 1
|
|
00FA80 1 A0 08 ldy #$08 ; $FA80: A0 08
|
|
00FA82 1 8C 0F 40 sty $400F ; $FA82: 8C 0F 40
|
|
00FA85 1 ; Reload the noise length counter.
|
|
00FA85 1
|
|
00FA85 1 60 rts ; $FA85: 60
|
|
00FA86 1
|
|
00FA86 1 ; ============================================================================
|
|
00FA86 1 ; $FA86-$FAA2
|
|
00FA86 1 ; Save audio state and write a timer period to an APU channel.
|
|
00FA86 1 ;
|
|
00FA86 1 ; Entry:
|
|
00FA86 1 ; A = period-table index
|
|
00FA86 1 ; X = audio state or duration value
|
|
00FA86 1 ; Y = value saved in $F0
|
|
00FA86 1 ;
|
|
00FA86 1 ; Behavior:
|
|
00FA86 1 ; 1. Save Y in $F0 and X in $F2.
|
|
00FA86 1 ; 2. If X is zero, write $7F to pulse 1 sweep through $FA6A.
|
|
00FA86 1 ; 3. Load a little-endian timer period from the table at $FA00.
|
|
00FA86 1 ; 4. Write the timer low and high bytes to the selected APU channel.
|
|
00FA86 1 ;
|
|
00FA86 1 ; Default channel:
|
|
00FA86 1 ; X = $00, selecting pulse channel 1 registers $4002/$4003.
|
|
00FA86 1 ;
|
|
00FA86 1 ; Exit:
|
|
00FA86 1 ; Returns immediately if the selected table high byte is zero.
|
|
00FA86 1 ; ============================================================================
|
|
00FA86 1
|
|
00FA86 1 WritePulsePeriodFromTable: ; $FA86
|
|
00FA86 1 84 F0 sty $F0 ; $FA86: 84 F0
|
|
00FA88 1 ; Save caller-selected audio state.
|
|
00FA88 1
|
|
00FA88 1 86 F2 stx $F2 ; $FA88: 86 F2
|
|
00FA8A 1 ; Save duration, mode, or countdown state.
|
|
00FA8A 1
|
|
00FA8A 1 ; ----------------------------------------------------------------------------
|
|
00FA8A 1 ; A nonzero X skips pulse 1 sweep initialization.
|
|
00FA8A 1 ; ----------------------------------------------------------------------------
|
|
00FA8A 1
|
|
00FA8A 1 D0 03 bne WritePulsePeriod_SelectChannel
|
|
00FA8C 1 ; $FA8A: D0 03
|
|
00FA8C 1
|
|
00FA8C 1 ; ----------------------------------------------------------------------------
|
|
00FA8C 1 ; X is zero. Enter the pulse 1 helper at $FA6A, which writes Y=$7F to $4001
|
|
00FA8C 1 ; and then falls through to write X to $4000.
|
|
00FA8C 1 ;
|
|
00FA8C 1 ; This call preserves A, the period-table index.
|
|
00FA8C 1 ; ----------------------------------------------------------------------------
|
|
00FA8C 1
|
|
00FA8C 1 ; ----------------------------------------------------------------------------
|
|
00FA8C 1 ; Contract:
|
|
00FA8C 1 ; Description: Internal period setup after $F0/$F2 were saved.
|
|
00FA8C 1 ; Entry: A = period-table index; X/Y contain saved effect context.
|
|
00FA8C 1 ; Returns/products: Pulse-1 sweep/timer fields initialized.
|
|
00FA8C 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FA8C 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FA8C 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FA8C 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FA8C 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00FA8C 1 ; ----------------------------------------------------------------------------
|
|
00FA8C 1 InitializePulse1PeriodAfterStateSaved:
|
|
00FA8C 1 20 6A FA jsr WritePulse1SweepAndControlFromRegisters ; $FA8C: 20 6A FA
|
|
00FA8F 1
|
|
00FA8F 1 ; ----------------------------------------------------------------------------
|
|
00FA8F 1 ; Select pulse channel 1 timer registers by default:
|
|
00FA8F 1 ;
|
|
00FA8F 1 ; $4002,X = timer low
|
|
00FA8F 1 ; $4003,X = timer high
|
|
00FA8F 1 ; ----------------------------------------------------------------------------
|
|
00FA8F 1
|
|
00FA8F 1 ; ----------------------------------------------------------------------------
|
|
00FA8F 1 ; Contract:
|
|
00FA8F 1 ; Description: Writes Pulse Period Select Channel.
|
|
00FA8F 1 ; Entry: Registers: A; Memory: $fa01, $fa00
|
|
00FA8F 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00FA8F 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FA8F 1 ; Memory effects: $4002, $4003
|
|
00FA8F 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FA8F 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FA8F 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00FA8F 1 ; ----------------------------------------------------------------------------
|
|
00FA8F 1 WritePulsePeriod_SelectChannel: ; $FA8F
|
|
00FA8F 1 A2 00 ldx #$00 ; $FA8F: A2 00
|
|
00FA91 1
|
|
00FA91 1 ; ============================================================================
|
|
00FA91 1 ; $FA91
|
|
00FA91 1 ; Shared timer-table writer.
|
|
00FA91 1 ;
|
|
00FA91 1 ; Alternate callers enter here with:
|
|
00FA91 1 ;
|
|
00FA91 1 ; X=$00 -> pulse 1, $4002/$4003
|
|
00FA91 1 ; X=$04 -> pulse 2, $4006/$4007
|
|
00FA91 1 ; X=$08 -> triangle, $400A/$400B
|
|
00FA91 1 ;
|
|
00FA91 1 ; Entry:
|
|
00FA91 1 ; A = timer-table index
|
|
00FA91 1 ; X = APU channel register offset
|
|
00FA91 1 ; ============================================================================
|
|
00FA91 1
|
|
00FA91 1 WriteApuTimerFromTable: ; $FA91
|
|
00FA91 1 A8 tay ; $FA91: A8
|
|
00FA92 1 ; Y = period-table index.
|
|
00FA92 1
|
|
00FA92 1 ; ----------------------------------------------------------------------------
|
|
00FA92 1 ; Load the timer high byte first.
|
|
00FA92 1 ;
|
|
00FA92 1 ; The table is stored as little-endian words beginning at $FA00:
|
|
00FA92 1 ;
|
|
00FA92 1 ; low byte = $FA00,Y
|
|
00FA92 1 ; high byte = $FA01,Y
|
|
00FA92 1 ; ----------------------------------------------------------------------------
|
|
00FA92 1
|
|
00FA92 1 B9 01 FA lda $FA01,y ; $FA92: B9 01 FA
|
|
00FA95 1 F0 0B beq WriteApuTimerFromTable_Return
|
|
00FA97 1 ; $FA95: F0 0B
|
|
00FA97 1 ; A zero high byte suppresses the write.
|
|
00FA97 1
|
|
00FA97 1 9D 02 40 sta $4002,x ; $FA97: 9D 02 40
|
|
00FA9A 1 ; Write timer low-register address plus X.
|
|
00FA9A 1 ;
|
|
00FA9A 1 ; Despite the table naming, this instruction
|
|
00FA9A 1 ; writes the byte loaded from $FA01,Y first.
|
|
00FA9A 1
|
|
00FA9A 1 ; ----------------------------------------------------------------------------
|
|
00FA9A 1 ; Load the adjacent table byte, set bit three, and write the timer high or
|
|
00FA9A 1 ; length-counter register.
|
|
00FA9A 1 ; ----------------------------------------------------------------------------
|
|
00FA9A 1
|
|
00FA9A 1 B9 00 FA lda $FA00,y ; $FA9A: B9 00 FA
|
|
00FA9D 1 09 08 ora #$08 ; $FA9D: 09 08
|
|
00FA9F 1
|
|
00FA9F 1 9D 03 40 sta $4003,x ; $FA9F: 9D 03 40
|
|
00FAA2 1
|
|
00FAA2 1 WriteApuTimerFromTable_Return: ; $FAA2
|
|
00FAA2 1 60 rts ; $FAA2: 60
|
|
00FAA3 1
|
|
00FAA3 1 ; ============================================================================
|
|
00FAA3 1 ; $FAA3-$FAA9
|
|
00FAA3 1 ; Write a table-selected timer period to pulse channel 2.
|
|
00FAA3 1 ;
|
|
00FAA3 1 ; $FA73 writes $7F to pulse 2 sweep register $4005. The routine then selects
|
|
00FAA3 1 ; register offset $04 and enters the shared timer writer at $FA91.
|
|
00FAA3 1 ; ============================================================================
|
|
00FAA3 1
|
|
00FAA3 1 WritePulse2PeriodFromTable: ; $FAA3
|
|
00FAA3 1 20 73 FA jsr WritePulse2SweepAndControlFromRegisters ; $FAA3: 20 73 FA
|
|
00FAA6 1 ; Write $7F to pulse 2 sweep.
|
|
00FAA6 1
|
|
00FAA6 1 ; ----------------------------------------------------------------------------
|
|
00FAA6 1 ; Contract:
|
|
00FAA6 1 ; Description: Internal pulse-2 timer writer after sweep initialization.
|
|
00FAA6 1 ; Entry: A = timer-table index.
|
|
00FAA6 1 ; Returns/products: APU pulse-2 timer fields written.
|
|
00FAA6 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FAA6 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FAA6 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FAA6 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FAA6 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00FAA6 1 ; ----------------------------------------------------------------------------
|
|
00FAA6 1 WritePulse2PeriodAfterSweep:
|
|
00FAA6 1 A2 04 ldx #$04 ; $FAA6: A2 04
|
|
00FAA8 1 ; Select $4006/$4007.
|
|
00FAA8 1
|
|
00FAA8 1 D0 E7 bne WriteApuTimerFromTable ; $FAA8: D0 E7
|
|
00FAAA 1 ; Always taken.
|
|
00FAAA 1
|
|
00FAAA 1 ; ============================================================================
|
|
00FAAA 1 ; $FAAA-$FAAD
|
|
00FAAA 1 ; Write a table-selected timer period to the triangle channel.
|
|
00FAAA 1 ;
|
|
00FAAA 1 ; Entry:
|
|
00FAAA 1 ; A = period-table index
|
|
00FAAA 1 ; ============================================================================
|
|
00FAAA 1
|
|
00FAAA 1 WriteTrianglePeriodFromTable: ; $FAAA
|
|
00FAAA 1 A2 08 ldx #$08 ; $FAAA: A2 08
|
|
00FAAC 1 ; Select $400A/$400B.
|
|
00FAAC 1
|
|
00FAAC 1 D0 E3 bne WriteApuTimerFromTable ; $FAAC: D0 E3
|
|
00FAAE 1 ; Always taken.
|
|
00FAAE 1 ; ============================================================================
|
|
00FAAE 1 ; $FAAE-$FABF
|
|
00FAAE 1 ; Reduce the value in Y by approximately one thirty-second.
|
|
00FAAE 1 ;
|
|
00FAAE 1 ; Entry:
|
|
00FAAE 1 ; Y = source value
|
|
00FAAE 1 ;
|
|
00FAAE 1 ; Calculation:
|
|
00FAAE 1 ;
|
|
00FAAE 1 ; adjustment = Y >> 5
|
|
00FAAE 1 ;
|
|
00FAAE 1 ; if adjustment == 0:
|
|
00FAAE 1 ; adjustment = 1
|
|
00FAAE 1 ;
|
|
00FAAE 1 ; A = Y - adjustment
|
|
00FAAE 1 ;
|
|
00FAAE 1 ; Exit:
|
|
00FAAE 1 ; A = adjusted value
|
|
00FAAE 1 ; Y = original input value
|
|
00FAAE 1 ; $00 = adjustment value
|
|
00FAAE 1 ;
|
|
00FAAE 1 ; For input values below $20, the routine subtracts one. For values of $20 or
|
|
00FAAE 1 ; greater, it subtracts the input divided by 32.
|
|
00FAAE 1 ; ============================================================================
|
|
00FAAE 1
|
|
00FAAE 1 ReduceValueByOneThirtySecond: ; $FAAE
|
|
00FAAE 1 98 tya ; $FAAE: 98
|
|
00FAAF 1 ; Copy the source value into A.
|
|
00FAAF 1
|
|
00FAAF 1 ; ----------------------------------------------------------------------------
|
|
00FAAF 1 ; Divide A by 32.
|
|
00FAAF 1 ; ----------------------------------------------------------------------------
|
|
00FAAF 1
|
|
00FAAF 1 4A lsr ; $FAAF: 4A
|
|
00FAB0 1 4A lsr ; $FAB0: 4A
|
|
00FAB1 1 4A lsr ; $FAB1: 4A
|
|
00FAB2 1 4A lsr ; $FAB2: 4A
|
|
00FAB3 1 4A lsr ; $FAB3: 4A
|
|
00FAB4 1
|
|
00FAB4 1 85 00 sta $00 ; $FAB4: 85 00
|
|
00FAB6 1 ; Save the calculated adjustment.
|
|
00FAB6 1
|
|
00FAB6 1 ; ----------------------------------------------------------------------------
|
|
00FAB6 1 ; Ensure the adjustment is at least one.
|
|
00FAB6 1 ;
|
|
00FAB6 1 ; If Y was below $20, shifting right five times produced zero.
|
|
00FAB6 1 ; ----------------------------------------------------------------------------
|
|
00FAB6 1
|
|
00FAB6 1 D0 02 bne ReduceValueByOneThirtySecond_Subtract
|
|
00FAB8 1 ; $FAB6: D0 02
|
|
00FAB8 1
|
|
00FAB8 1 E6 00 inc $00 ; $FAB8: E6 00
|
|
00FABA 1 ; Change zero adjustment to one.
|
|
00FABA 1
|
|
00FABA 1 ; ----------------------------------------------------------------------------
|
|
00FABA 1 ; Subtract the adjustment from the original input value.
|
|
00FABA 1 ; ----------------------------------------------------------------------------
|
|
00FABA 1
|
|
00FABA 1 ReduceValueByOneThirtySecond_Subtract: ; $FABA
|
|
00FABA 1 98 tya ; $FABA: 98
|
|
00FABB 1 ; Restore the original source value.
|
|
00FABB 1
|
|
00FABB 1 38 sec ; $FABB: 38
|
|
00FABC 1 E5 00 sbc $00 ; $FABC: E5 00
|
|
00FABE 1
|
|
00FABE 1 60 rts ; $FABE: 60
|
|
00FABF 1
|
|
00FABF 1 ; ============================================================================
|
|
00FABF 1 ; $FABF-$FACE
|
|
00FABF 1 ; Derive an audio lookup-table index from A and the current audio offset in $F6.
|
|
00FABF 1 ;
|
|
00FABF 1 ; Entry:
|
|
00FABF 1 ; A = source value
|
|
00FABF 1 ; C = participates in the initial ROR
|
|
00FABF 1 ; $F6 = base audio-table index
|
|
00FABF 1 ;
|
|
00FABF 1 ; Calculation:
|
|
00FABF 1 ; 1. Save the original A in X.
|
|
00FABF 1 ; 2. Rotate A right once.
|
|
00FABF 1 ; 3. Restore the original A from X.
|
|
00FABF 1 ; 4. Rotate left three times.
|
|
00FABF 1 ; 5. Keep the low three bits.
|
|
00FABF 1 ; 6. Add $F6.
|
|
00FABF 1 ; 7. Use the sum to index the table at $FA4A.
|
|
00FABF 1 ;
|
|
00FABF 1 ; Exit:
|
|
00FABF 1 ; A = selected byte from $FA4A,Y
|
|
00FABF 1 ; X = original input A
|
|
00FABF 1 ; Y = calculated table index
|
|
00FABF 1 ; ============================================================================
|
|
00FABF 1
|
|
00FABF 1 ; ----------------------------------------------------------------------------
|
|
00FABF 1 ; Contract:
|
|
00FABF 1 ; Description: Implements Lookup Audio Control Value.
|
|
00FABF 1 ; Entry: Registers: A, X; Memory: $f6, $fa4a
|
|
00FABF 1 ; Returns/products: Registers/clobbers: A, X, Y; Flags: condition flags may carry result state
|
|
00FABF 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FABF 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FABF 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FABF 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FABF 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 2.
|
|
00FABF 1 ; ----------------------------------------------------------------------------
|
|
00FABF 1 LookupAudioControlValue: ; $FABF
|
|
00FABF 1 AA tax ; $FABF: AA
|
|
00FAC0 1 ; Preserve the original source value in X.
|
|
00FAC0 1
|
|
00FAC0 1 6A ror ; $FAC0: 6A
|
|
00FAC1 1 ; Rotate the source right through carry.
|
|
00FAC1 1 ;
|
|
00FAC1 1 ; The resulting A is not used directly, but
|
|
00FAC1 1 ; this changes carry for the following ROLs.
|
|
00FAC1 1
|
|
00FAC1 1 8A txa ; $FAC1: 8A
|
|
00FAC2 1 ; Restore the original source value.
|
|
00FAC2 1
|
|
00FAC2 1 ; ----------------------------------------------------------------------------
|
|
00FAC2 1 ; Rotate the original value left three times through the carry established by
|
|
00FAC2 1 ; the preceding ROR.
|
|
00FAC2 1 ; ----------------------------------------------------------------------------
|
|
00FAC2 1
|
|
00FAC2 1 2A rol ; $FAC2: 2A
|
|
00FAC3 1 2A rol ; $FAC3: 2A
|
|
00FAC4 1 2A rol ; $FAC4: 2A
|
|
00FAC5 1
|
|
00FAC5 1 ; ----------------------------------------------------------------------------
|
|
00FAC5 1 ; Contract:
|
|
00FAC5 1 ; Description: Internal lookup entry after carry and source value are prepared.
|
|
00FAC5 1 ; Entry: A/X and carry encode lookup offset; $F6 is base index.
|
|
00FAC5 1 ; Returns/products: A = selected control value; X preserves source; Y = table index.
|
|
00FAC5 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FAC5 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FAC5 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FAC5 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FAC5 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00FAC5 1 ; ----------------------------------------------------------------------------
|
|
00FAC5 1 LookupAudioControlValueFinalRotate:
|
|
00FAC5 1 29 07 and #$07 ; $FAC5: 29 07
|
|
00FAC7 1 ; Keep a three-bit table offset.
|
|
00FAC7 1
|
|
00FAC7 1 18 clc ; $FAC7: 18
|
|
00FAC8 1 65 F6 adc $F6 ; $FAC8: 65 F6
|
|
00FACA 1 ; Add the current audio-table base.
|
|
00FACA 1
|
|
00FACA 1 A8 tay ; $FACA: A8
|
|
00FACB 1
|
|
00FACB 1 B9 4A FA lda $FA4A,y ; $FACB: B9 4A FA
|
|
00FACE 1 ; Load the selected audio control value.
|
|
00FACE 1
|
|
00FACE 1 60 rts ; $FACE: 60
|
|
00FACF 1
|
|
00FACF 1 ; ============================================================================
|
|
00FACF 1 ; $FACF-$FAD9
|
|
00FACF 1 ; Configure the first sound-effect preset.
|
|
00FACF 1 ;
|
|
00FACF 1 ; Preset values:
|
|
00FACF 1 ; X = $17
|
|
00FACF 1 ; A = $12
|
|
00FACF 1 ; Y = $84
|
|
00FACF 1 ;
|
|
00FACF 1 ; The common setup helper at $FA86 saves Y in $F0 and X in $F2, then writes an
|
|
00FACF 1 ; APU timer value selected by A.
|
|
00FACF 1 ; ============================================================================
|
|
00FACF 1
|
|
00FACF 1 StartPulse1EffectPreset1: ; $FACF
|
|
00FACF 1 A2 17 ldx #$17 ; $FACF: A2 17
|
|
00FAD1 1 ; Duration or audio-state value.
|
|
00FAD1 1
|
|
00FAD1 1 A9 12 lda #$12 ; $FAD1: A9 12
|
|
00FAD3 1 ; Timer-table index.
|
|
00FAD3 1
|
|
00FAD3 1 20 86 FA jsr WritePulsePeriodFromTable
|
|
00FAD6 1 ; $FAD3: 20 86 FA
|
|
00FAD6 1
|
|
00FAD6 1 ; ----------------------------------------------------------------------------
|
|
00FAD6 1 ; Contract:
|
|
00FAD6 1 ; Description: Internal preset-1 continuation with timer state initialized.
|
|
00FAD6 1 ; Entry: Y initialized to preset control $84.
|
|
00FAD6 1 ; Returns/products: Continues shared pulse-1 preset update.
|
|
00FAD6 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FAD6 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FAD6 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FAD6 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FAD6 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00FAD6 1 ; ----------------------------------------------------------------------------
|
|
00FAD6 1 StartPulse1EffectPreset1FromControl:
|
|
00FAD6 1 A0 84 ldy #$84 ; $FAD6: A0 84
|
|
00FAD8 1 ; Default control or envelope value.
|
|
00FAD8 1
|
|
00FAD8 1 D0 14 bne UpdatePulse1PresetEffect
|
|
00FADA 1 ; $FAD8: D0 14
|
|
00FADA 1 ; Always taken.
|
|
00FADA 1 ; Target $FAEE.
|
|
00FADA 1
|
|
00FADA 1 ; ============================================================================
|
|
00FADA 1 ; $FADA-$FAE4
|
|
00FADA 1 ; Configure the second sound-effect preset.
|
|
00FADA 1 ;
|
|
00FADA 1 ; Preset values:
|
|
00FADA 1 ; X = $1E
|
|
00FADA 1 ; A = $0C
|
|
00FADA 1 ; Y = $85
|
|
00FADA 1 ; ============================================================================
|
|
00FADA 1
|
|
00FADA 1 StartPulse1EffectPreset2: ; $FADA
|
|
00FADA 1 A2 1E ldx #$1E ; $FADA: A2 1E
|
|
00FADC 1
|
|
00FADC 1 A9 0C lda #$0C ; $FADC: A9 0C
|
|
00FADE 1
|
|
00FADE 1 20 86 FA jsr WritePulsePeriodFromTable
|
|
00FAE1 1 ; $FADE: 20 86 FA
|
|
00FAE1 1
|
|
00FAE1 1 ; ----------------------------------------------------------------------------
|
|
00FAE1 1 ; Contract:
|
|
00FAE1 1 ; Description: Internal preset-2 continuation with timer state initialized.
|
|
00FAE1 1 ; Entry: Y initialized to preset control $85.
|
|
00FAE1 1 ; Returns/products: Continues shared pulse-1 preset update.
|
|
00FAE1 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FAE1 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FAE1 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FAE1 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FAE1 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00FAE1 1 ; ----------------------------------------------------------------------------
|
|
00FAE1 1 StartPulse1EffectPreset2FromControl:
|
|
00FAE1 1 A0 85 ldy #$85 ; $FAE1: A0 85
|
|
00FAE3 1
|
|
00FAE3 1 D0 09 bne UpdatePulse1PresetEffect
|
|
00FAE5 1 ; $FAE3: D0 09
|
|
00FAE5 1 ; Always taken.
|
|
00FAE5 1 ; Target $FAEE.
|
|
00FAE5 1
|
|
00FAE5 1 ; ============================================================================
|
|
00FAE5 1 ; $FAE5-$FAED
|
|
00FAE5 1 ; Configure the third sound-effect preset.
|
|
00FAE5 1 ;
|
|
00FAE5 1 ; Preset values:
|
|
00FAE5 1 ; X = $27
|
|
00FAE5 1 ; A = $06
|
|
00FAE5 1 ; Y = $86
|
|
00FAE5 1 ;
|
|
00FAE5 1 ; This entry falls directly into the shared finalization path.
|
|
00FAE5 1 ; ============================================================================
|
|
00FAE5 1
|
|
00FAE5 1 StartPulse1EffectPreset3: ; $FAE5
|
|
00FAE5 1 A2 27 ldx #$27 ; $FAE5: A2 27
|
|
00FAE7 1
|
|
00FAE7 1 A9 06 lda #$06 ; $FAE7: A9 06
|
|
00FAE9 1
|
|
00FAE9 1 20 86 FA jsr WritePulsePeriodFromTable
|
|
00FAEC 1 ; $FAE9: 20 86 FA
|
|
00FAEC 1
|
|
00FAEC 1 ; ----------------------------------------------------------------------------
|
|
00FAEC 1 ; Contract:
|
|
00FAEC 1 ; Description: Internal preset-3 continuation with timer state initialized.
|
|
00FAEC 1 ; Entry: Y initialized to preset control $86.
|
|
00FAEC 1 ; Returns/products: Continues shared pulse-1 preset update.
|
|
00FAEC 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FAEC 1 ; Memory effects: See symbolic operands in the routine body; zero-page scratch roles are documented locally.
|
|
00FAEC 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FAEC 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FAEC 1 ; Validation: Internal-entry contract; call sites: internal entry.
|
|
00FAEC 1 ; ----------------------------------------------------------------------------
|
|
00FAEC 1 StartPulse1EffectPreset3FromControl:
|
|
00FAEC 1 A0 86 ldy #$86 ; $FAEC: A0 86
|
|
00FAEE 1
|
|
00FAEE 1 ; ============================================================================
|
|
00FAEE 1 ; $FAEE-$FB04
|
|
00FAEE 1 ; Finalize one of the three sound-effect presets.
|
|
00FAEE 1 ;
|
|
00FAEE 1 ; The routine selects an alternate Y value when bit three of $00 is set,
|
|
00FAEE 1 ; derives a second control value in X from $F2, then tail-jumps to $FB5A.
|
|
00FAEE 1 ;
|
|
00FAEE 1 ; Entry:
|
|
00FAEE 1 ; Y = preset-specific control value
|
|
00FAEE 1 ; $F2 = duration or sound-state value saved by $FA86
|
|
00FAEE 1 ; ============================================================================
|
|
00FAEE 1
|
|
00FAEE 1 UpdatePulse1PresetEffect: ; $FAEE
|
|
00FAEE 1 A5 00 lda $00 ; $FAEE: A5 00
|
|
00FAF0 1
|
|
00FAF0 1 29 08 and #$08 ; $FAF0: 29 08
|
|
00FAF2 1 F0 02 beq FinalizeSoundEffectPreset_SelectX
|
|
00FAF4 1 ; $FAF2: F0 02
|
|
00FAF4 1
|
|
00FAF4 1 ; ----------------------------------------------------------------------------
|
|
00FAF4 1 ; When bit three of $00 is set, replace the preset-specific Y value with $8D.
|
|
00FAF4 1 ; ----------------------------------------------------------------------------
|
|
00FAF4 1
|
|
00FAF4 1 A0 8D ldy #$8D ; $FAF4: A0 8D
|
|
00FAF6 1
|
|
00FAF6 1 ; ----------------------------------------------------------------------------
|
|
00FAF6 1 ; Select the initial channel/control value.
|
|
00FAF6 1 ; ----------------------------------------------------------------------------
|
|
00FAF6 1
|
|
00FAF6 1 FinalizeSoundEffectPreset_SelectX: ; $FAF6
|
|
00FAF6 1 A2 5A ldx #$5A ; $FAF6: A2 5A
|
|
00FAF8 1
|
|
00FAF8 1 ; ----------------------------------------------------------------------------
|
|
00FAF8 1 ; For $F2 values below $14, derive X from half the value and force bits six and
|
|
00FAF8 1 ; four through OR #$50.
|
|
00FAF8 1 ;
|
|
00FAF8 1 ; For $F2 values $14 or greater, retain X=$5A.
|
|
00FAF8 1 ; ----------------------------------------------------------------------------
|
|
00FAF8 1
|
|
00FAF8 1 A5 F2 lda $F2 ; $FAF8: A5 F2
|
|
00FAFA 1
|
|
00FAFA 1 C9 14 cmp #$14 ; $FAFA: C9 14
|
|
00FAFC 1 B0 04 bcs FinalizeSoundEffectPreset_Apply
|
|
00FAFE 1 ; $FAFC: B0 04
|
|
00FAFE 1
|
|
00FAFE 1 4A lsr ; $FAFE: 4A
|
|
00FAFF 1 09 50 ora #$50 ; $FAFF: 09 50
|
|
00FB01 1 AA tax ; $FB01: AA
|
|
00FB02 1
|
|
00FB02 1 ; ----------------------------------------------------------------------------
|
|
00FB02 1 ; Tail-call the shared sound-effect register updater.
|
|
00FB02 1 ;
|
|
00FB02 1 ; Entry to $FB5A:
|
|
00FB02 1 ; X = calculated control value
|
|
00FB02 1 ; Y = preset or alternate envelope value
|
|
00FB02 1 ; ----------------------------------------------------------------------------
|
|
00FB02 1
|
|
00FB02 1 FinalizeSoundEffectPreset_Apply: ; $FB02
|
|
00FB02 1 4C 5A FB jmp UpdateAudioEffect1_Write ; $FB02: 4C 5A FB
|
|
00FB05 1
|
|
00FB05 1 ; ============================================================================
|
|
00FB05 1 ; $FB05-$FB42
|
|
00FB05 1 ; Main audio-update dispatcher.
|
|
00FB05 1 ;
|
|
00FB05 1 ; Audio state:
|
|
00FB05 1 ; $FF = pending sound-effect flags
|
|
00FB05 1 ; $F0 = active sound-effect state
|
|
00FB05 1 ; $F2 = effect countdown or phase
|
|
00FB05 1 ; $F3 = effect-specific state
|
|
00FB05 1 ; $FA = audio lock or override state
|
|
00FB05 1 ;
|
|
00FB05 1 ; The dispatcher alternates between bits in $F0 and $FF. Each carry-producing
|
|
00FB05 1 ; shift routes to a different sound-effect setup or update handler.
|
|
00FB05 1 ; ============================================================================
|
|
00FB05 1
|
|
00FB05 1 ; ----------------------------------------------------------------------------
|
|
00FB05 1 ; Contract:
|
|
00FB05 1 ; Description: Updates Audio Engine.
|
|
00FB05 1 ; Entry: Registers: A, Y; Memory: $ff, $f0, $fa
|
|
00FB05 1 ; Returns/products: Registers/clobbers: A, X, Y
|
|
00FB05 1 ; Clobbers: A, X, Y, and processor flags as indicated by the instructions below.
|
|
00FB05 1 ; Memory effects: $00, $f0, $f2, $f3
|
|
00FB05 1 ; Flags: Unless explicitly described, flags reflect the final arithmetic,
|
|
00FB05 1 ; comparison, load, or store path and are not a stable API product.
|
|
00FB05 1 ; Validation: Inferred from annotated instructions and call sites; call sites: 1.
|
|
00FB05 1 ; ----------------------------------------------------------------------------
|
|
00FB05 1 UpdateAudioEngine: ; $FB05
|
|
00FB05 1 A4 FF ldy RenderStateFlags ; $FB05: A4 FF
|
|
00FB07 1 84 00 sty $00 ; $FB07: 84 00
|
|
00FB09 1 ; Preserve the original pending-effect flags.
|
|
00FB09 1
|
|
00FB09 1 A5 F0 lda $F0 ; $FB09: A5 F0
|
|
00FB0B 1 ; Active-effect flags or state.
|
|
00FB0B 1
|
|
00FB0B 1 A6 FA ldx $FA ; $FB0B: A6 FA
|
|
00FB0D 1 D0 31 bne UpdateAudioEngine_Finalize
|
|
00FB0F 1 ; $FB0D: D0 31
|
|
00FB0F 1 ; An override or lock skips effect selection.
|
|
00FB0F 1
|
|
00FB0F 1 ; ----------------------------------------------------------------------------
|
|
00FB0F 1 ; Test active-effect bit zero.
|
|
00FB0F 1 ;
|
|
00FB0F 1 ; Carry set transfers directly into the first preset's finalization path at
|
|
00FB0F 1 ; $FAD6, where Y is initialized to $84.
|
|
00FB0F 1 ; ----------------------------------------------------------------------------
|
|
00FB0F 1
|
|
00FB0F 1 4A lsr ; $FB0F: 4A
|
|
00FB10 1 B0 C4 bcs StartPulse1EffectPreset1FromControl ; $FB10: B0 C4
|
|
00FB12 1
|
|
00FB12 1 ; ----------------------------------------------------------------------------
|
|
00FB12 1 ; Test pending-effect bit zero.
|
|
00FB12 1 ; ----------------------------------------------------------------------------
|
|
00FB12 1
|
|
00FB12 1 46 FF lsr RenderStateFlags ; $FB12: 46 FF
|
|
00FB14 1 B0 B9 bcs StartPulse1EffectPreset1 ; $FB14: B0 B9
|
|
00FB16 1
|
|
00FB16 1 ; ----------------------------------------------------------------------------
|
|
00FB16 1 ; Test active-effect bit one.
|
|
00FB16 1 ;
|
|
00FB16 1 ; Target $FAE1 initializes Y=$85 for the second preset.
|
|
00FB16 1 ; ----------------------------------------------------------------------------
|
|
00FB16 1
|
|
00FB16 1 4A lsr ; $FB16: 4A
|
|
00FB17 1 B0 C8 bcs StartPulse1EffectPreset2FromControl ; $FB17: B0 C8
|
|
00FB19 1
|
|
00FB19 1 ; ----------------------------------------------------------------------------
|
|
00FB19 1 ; Test pending-effect bit one.
|
|
00FB19 1 ; ----------------------------------------------------------------------------
|
|
00FB19 1
|
|
00FB19 1 46 FF lsr RenderStateFlags ; $FB19: 46 FF
|
|
00FB1B 1 B0 BD bcs StartPulse1EffectPreset2 ; $FB1B: B0 BD
|
|
00FB1D 1
|
|
00FB1D 1 ; ----------------------------------------------------------------------------
|
|
00FB1D 1 ; Test active-effect bit two.
|
|
00FB1D 1 ;
|
|
00FB1D 1 ; Target $FAEC initializes Y=$86 for the third preset.
|
|
00FB1D 1 ; ----------------------------------------------------------------------------
|
|
00FB1D 1
|
|
00FB1D 1 4A lsr ; $FB1D: 4A
|
|
00FB1E 1 B0 CC bcs StartPulse1EffectPreset3FromControl ; $FB1E: B0 CC
|
|
00FB20 1
|
|
00FB20 1 ; ----------------------------------------------------------------------------
|
|
00FB20 1 ; Test pending-effect bit two.
|
|
00FB20 1 ; ----------------------------------------------------------------------------
|
|
00FB20 1
|
|
00FB20 1 46 FF lsr RenderStateFlags ; $FB20: 46 FF
|
|
00FB22 1 B0 C1 bcs StartPulse1EffectPreset3 ; $FB22: B0 C1
|
|
00FB24 1
|
|
00FB24 1 ; ----------------------------------------------------------------------------
|
|
00FB24 1 ; Discard the next active and pending bits.
|
|
00FB24 1 ; ----------------------------------------------------------------------------
|
|
00FB24 1
|
|
00FB24 1 4A lsr ; $FB24: 4A
|
|
00FB25 1 46 FF lsr RenderStateFlags ; $FB25: 46 FF
|
|
00FB27 1
|
|
00FB27 1 ; ----------------------------------------------------------------------------
|
|
00FB27 1 ; Test the next active-effect bit.
|
|
00FB27 1 ; ----------------------------------------------------------------------------
|
|
00FB27 1
|
|
00FB27 1 4A lsr ; $FB27: 4A
|
|
00FB28 1 B0 20 bcs UpdatePulse1DescendingEffect ; $FB28: B0 20
|
|
00FB2A 1 ; Target $FB4A.
|
|
00FB2A 1
|
|
00FB2A 1 ; ----------------------------------------------------------------------------
|
|
00FB2A 1 ; Test the corresponding pending-effect bit.
|
|
00FB2A 1 ; ----------------------------------------------------------------------------
|
|
00FB2A 1
|
|
00FB2A 1 46 FF lsr RenderStateFlags ; $FB2A: 46 FF
|
|
00FB2C 1 B0 15 bcs StartPulse1DescendingEffect ; $FB2C: B0 15
|
|
00FB2E 1 ; Target $FB43.
|
|
00FB2E 1
|
|
00FB2E 1 ; ----------------------------------------------------------------------------
|
|
00FB2E 1 ; Test the next active-effect bit.
|
|
00FB2E 1 ; ----------------------------------------------------------------------------
|
|
00FB2E 1
|
|
00FB2E 1 4A lsr ; $FB2E: 4A
|
|
00FB2F 1 B0 3A bcs UpdatePulse1StateChangeEffect ; $FB2F: B0 3A
|
|
00FB31 1 ; Target $FB6B.
|
|
00FB31 1
|
|
00FB31 1 ; ----------------------------------------------------------------------------
|
|
00FB31 1 ; Test the corresponding pending-effect bit.
|
|
00FB31 1 ; ----------------------------------------------------------------------------
|
|
00FB31 1
|
|
00FB31 1 46 FF lsr RenderStateFlags ; $FB31: 46 FF
|
|
00FB33 1 B0 2E bcs StartPulse1StateChangeEffect ; $FB33: B0 2E
|
|
00FB35 1 ; Target $FB63.
|
|
00FB35 1
|
|
00FB35 1 ; ----------------------------------------------------------------------------
|
|
00FB35 1 ; No recognized effect remains.
|
|
00FB35 1 ;
|
|
00FB35 1 ; Reset pulse channel 1 and clear the primary effect state.
|
|
00FB35 1 ; ----------------------------------------------------------------------------
|
|
00FB35 1
|
|
00FB35 1 ClearPrimaryAudioEffect: ; $FB35
|
|
00FB35 1 20 60 FA jsr ConfigurePulse1ControlPreset
|
|
00FB38 1 ; $FB35: 20 60 FA
|
|
00FB38 1
|
|
00FB38 1 A9 00 lda #$00 ; $FB38: A9 00
|
|
00FB3A 1 85 F0 sta $F0 ; $FB3A: 85 F0
|
|
00FB3C 1 85 F2 sta $F2 ; $FB3C: 85 F2
|
|
00FB3E 1 85 F3 sta $F3 ; $FB3E: 85 F3
|
|
00FB40 1
|
|
00FB40 1 ; ----------------------------------------------------------------------------
|
|
00FB40 1 ; Continue to the common audio finalization path at $FBFF.
|
|
00FB40 1 ; ----------------------------------------------------------------------------
|
|
00FB40 1
|
|
00FB40 1 UpdateAudioEngine_Finalize: ; $FB40
|
|
00FB40 1 4C FF FB jmp UpdateSecondaryEffects ; $FB40: 4C FF FB
|
|
00FB43 1
|
|
00FB43 1 ; ============================================================================
|
|
00FB43 1 ; $FB43-$FB49
|
|
00FB43 1 ; Start audio effect 1.
|
|
00FB43 1 ;
|
|
00FB43 1 ; Preset:
|
|
00FB43 1 ; X = $14
|
|
00FB43 1 ; A = $26
|
|
00FB43 1 ;
|
|
00FB43 1 ; The period helper stores X in $F2 and writes the selected pulse period.
|
|
00FB43 1 ; Execution then falls through to the effect-update path at $FB4A.
|
|
00FB43 1 ; ============================================================================
|
|
00FB43 1
|
|
00FB43 1 StartPulse1DescendingEffect: ; $FB43
|
|
00FB43 1 A2 14 ldx #$14 ; $FB43: A2 14
|
|
00FB45 1 A9 26 lda #$26 ; $FB45: A9 26
|
|
00FB47 1
|
|
00FB47 1 20 86 FA jsr WritePulsePeriodFromTable
|
|
00FB4A 1 ; $FB47: 20 86 FA
|
|
00FB4A 1
|
|
00FB4A 1 ; ============================================================================
|
|
00FB4A 1 ; $FB4A-$FB62
|
|
00FB4A 1 ; Update audio effect 1.
|
|
00FB4A 1 ;
|
|
00FB4A 1 ; The effect changes pulse channel 1 control as $F2 counts down. Values below
|
|
00FB4A 1 ; $10 derive the control register dynamically; larger values use preset $98.
|
|
00FB4A 1 ; ============================================================================
|
|
00FB4A 1
|
|
00FB4A 1 UpdatePulse1DescendingEffect: ; $FB4A
|
|
00FB4A 1 A2 98 ldx #$98 ; $FB4A: A2 98
|
|
00FB4C 1 ; Default pulse control.
|
|
00FB4C 1
|
|
00FB4C 1 A0 84 ldy #$84 ; $FB4C: A0 84
|
|
00FB4E 1 ; Default sweep or effect state.
|
|
00FB4E 1
|
|
00FB4E 1 A5 F2 lda $F2 ; $FB4E: A5 F2
|
|
00FB50 1 C9 10 cmp #$10 ; $FB50: C9 10
|
|
00FB52 1 B0 06 bcs UpdateAudioEffect1_Write
|
|
00FB54 1 ; $FB52: B0 06
|
|
00FB54 1
|
|
00FB54 1 ; ----------------------------------------------------------------------------
|
|
00FB54 1 ; Final effect phase.
|
|
00FB54 1 ;
|
|
00FB54 1 ; Use alternate state $8D and derive the control byte from half the countdown.
|
|
00FB54 1 ; ----------------------------------------------------------------------------
|
|
00FB54 1
|
|
00FB54 1 A0 8D ldy #$8D ; $FB54: A0 8D
|
|
00FB56 1
|
|
00FB56 1 4A lsr ; $FB56: 4A
|
|
00FB57 1 09 90 ora #$90 ; $FB57: 09 90
|
|
00FB59 1 AA tax ; $FB59: AA
|
|
00FB5A 1
|
|
00FB5A 1 ; ----------------------------------------------------------------------------
|
|
00FB5A 1 ; Write pulse channel 1 sweep and control.
|
|
00FB5A 1 ; ----------------------------------------------------------------------------
|
|
00FB5A 1
|
|
00FB5A 1 UpdateAudioEffect1_Write: ; $FB5A
|
|
00FB5A 1 20 6A FA jsr WritePulse1SweepAndControlFromRegisters ; $FB5A: 20 6A FA
|
|
00FB5D 1 ; Write Y to $4001 and X to $4000.
|
|
00FB5D 1
|
|
00FB5D 1 ; ----------------------------------------------------------------------------
|
|
00FB5D 1 ; Count the effect down.
|
|
00FB5D 1 ;
|
|
00FB5D 1 ; When it expires, clear the primary effect state at $FB35. Otherwise continue
|
|
00FB5D 1 ; through the common audio finalizer at $FB40.
|
|
00FB5D 1 ; ----------------------------------------------------------------------------
|
|
00FB5D 1
|
|
00FB5D 1 C6 F2 dec $F2 ; $FB5D: C6 F2
|
|
00FB5F 1 F0 D4 beq ClearPrimaryAudioEffect ; $FB5F: F0 D4
|
|
00FB61 1
|
|
00FB61 1 D0 DD bne UpdateAudioEngine_Finalize
|
|
00FB63 1 ; $FB61: D0 DD
|
|
00FB63 1 ; Always taken while $F2 is nonzero.
|
|
00FB63 1
|
|
00FB63 1 ; ============================================================================
|
|
00FB63 1 ; $FB63-$FB6A
|
|
00FB63 1 ; Start audio effect 2.
|
|
00FB63 1 ;
|
|
00FB63 1 ; The caller reached this path because the corresponding pending-effect bit was
|
|
00FB63 1 ; set. Y still contains the original pending flags loaded at $FB05.
|
|
00FB63 1 ; ============================================================================
|
|
00FB63 1
|
|
00FB63 1 StartPulse1StateChangeEffect: ; $FB63
|
|
00FB63 1 84 F0 sty $F0 ; $FB63: 84 F0
|
|
00FB65 1 ; Save the active effect state.
|
|
00FB65 1
|
|
00FB65 1 A0 9D ldy #$9D ; $FB65: A0 9D
|
|
00FB67 1 ; Initial pulse sweep/control value.
|
|
00FB67 1
|
|
00FB67 1 A9 30 lda #$30 ; $FB67: A9 30
|
|
00FB69 1 ; Initial timer or pitch value.
|
|
00FB69 1
|
|
00FB69 1 D0 2C bne UpdateAudioEffect2_Trigger
|
|
00FB6B 1 ; $FB69: D0 2C
|
|
00FB6B 1 ; Always taken to $FB97.
|
|
00FB6B 1
|
|
00FB6B 1 ; ============================================================================
|
|
00FB6B 1 ; $FB6B-$FBA0
|
|
00FB6B 1 ; Update audio effect 2.
|
|
00FB6B 1 ;
|
|
00FB6B 1 ; This handler uses bit six of the original pending flags, the countdown in
|
|
00FB6B 1 ; $F2, and the previous state in $F3 to choose pulse control and pitch values.
|
|
00FB6B 1 ; ============================================================================
|
|
00FB6B 1
|
|
00FB6B 1 UpdatePulse1StateChangeEffect: ; $FB6B
|
|
00FB6B 1 46 FF lsr RenderStateFlags ; $FB6B: 46 FF
|
|
00FB6D 1
|
|
00FB6D 1 90 C6 bcc ClearPrimaryAudioEffect ; $FB6D: 90 C6
|
|
00FB6F 1 ; End the effect when the shifted bit is clear.
|
|
00FB6F 1
|
|
00FB6F 1 ; ----------------------------------------------------------------------------
|
|
00FB6F 1 ; Test bit six of the original pending-effect flags saved at $00.
|
|
00FB6F 1 ; ----------------------------------------------------------------------------
|
|
00FB6F 1
|
|
00FB6F 1 A5 00 lda $00 ; $FB6F: A5 00
|
|
00FB71 1 29 40 and #$40 ; $FB71: 29 40
|
|
00FB73 1 D0 0A bne UpdateAudioEffect2_CheckState
|
|
00FB75 1 ; $FB73: D0 0A
|
|
00FB75 1
|
|
00FB75 1 ; ----------------------------------------------------------------------------
|
|
00FB75 1 ; Without bit six set, wait until the countdown reaches exactly $C0.
|
|
00FB75 1 ; ----------------------------------------------------------------------------
|
|
00FB75 1
|
|
00FB75 1 A5 F2 lda $F2 ; $FB75: A5 F2
|
|
00FB77 1 C9 C0 cmp #$C0 ; $FB77: C9 C0
|
|
00FB79 1 D0 21 bne UpdateAudioEffect2_CountDown
|
|
00FB7B 1 ; $FB79: D0 21
|
|
00FB7B 1
|
|
00FB7B 1 A0 9E ldy #$9E ; $FB7B: A0 9E
|
|
00FB7D 1
|
|
00FB7D 1 D0 11 bne UpdateAudioEffect2_WriteSweep
|
|
00FB7F 1 ; $FB7D: D0 11
|
|
00FB7F 1
|
|
00FB7F 1 ; ----------------------------------------------------------------------------
|
|
00FB7F 1 ; Bit six is set. Toggle or compare the saved effect state in $F3.
|
|
00FB7F 1 ; ----------------------------------------------------------------------------
|
|
00FB7F 1
|
|
00FB7F 1 UpdateAudioEffect2_CheckState: ; $FB7F
|
|
00FB7F 1 A4 F3 ldy $F3 ; $FB7F: A4 F3
|
|
00FB81 1
|
|
00FB81 1 85 F3 sta $F3 ; $FB81: 85 F3
|
|
00FB83 1 ; Save A=$40 in $F3.
|
|
00FB83 1
|
|
00FB83 1 98 tya ; $FB83: 98
|
|
00FB84 1 45 F3 eor $F3 ; $FB84: 45 F3
|
|
00FB86 1 F0 14 beq UpdateAudioEffect2_CountDown
|
|
00FB88 1 ; $FB86: F0 14
|
|
00FB88 1
|
|
00FB88 1 ; ----------------------------------------------------------------------------
|
|
00FB88 1 ; The state changed. Use sweep/control value $A5.
|
|
00FB88 1 ; ----------------------------------------------------------------------------
|
|
00FB88 1
|
|
00FB88 1 A0 A5 ldy #$A5 ; $FB88: A0 A5
|
|
00FB8A 1
|
|
00FB8A 1 A5 F2 lda $F2 ; $FB8A: A5 F2
|
|
00FB8C 1 C9 A8 cmp #$A8 ; $FB8C: C9 A8
|
|
00FB8E 1 90 05 bcc UpdateAudioEffect2_SelectPitch
|
|
00FB90 1 ; $FB8E: 90 05
|
|
00FB90 1
|
|
00FB90 1 ; ----------------------------------------------------------------------------
|
|
00FB90 1 ; For countdown values at least $A8, write the selected sweep value directly.
|
|
00FB90 1 ; ----------------------------------------------------------------------------
|
|
00FB90 1
|
|
00FB90 1 UpdateAudioEffect2_WriteSweep: ; $FB90
|
|
00FB90 1 8C 01 40 sty $4001 ; $FB90: 8C 01 40
|
|
00FB93 1
|
|
00FB93 1 D0 07 bne UpdateAudioEffect2_CountDown
|
|
00FB95 1 ; $FB93: D0 07
|
|
00FB95 1 ; Expected to be taken because the selected Y
|
|
00FB95 1 ; values are nonzero.
|
|
00FB95 1
|
|
00FB95 1 ; ----------------------------------------------------------------------------
|
|
00FB95 1 ; Select pitch value $48 and channel control $B3.
|
|
00FB95 1 ; ----------------------------------------------------------------------------
|
|
00FB95 1
|
|
00FB95 1 UpdateAudioEffect2_SelectPitch: ; $FB95
|
|
00FB95 1 A9 48 lda #$48 ; $FB95: A9 48
|
|
00FB97 1
|
|
00FB97 1 UpdateAudioEffect2_Trigger: ; $FB97
|
|
00FB97 1 A2 B3 ldx #$B3 ; $FB97: A2 B3
|
|
00FB99 1
|
|
00FB99 1 20 8C FA jsr InitializePulse1PeriodAfterStateSaved ; $FB99: 20 8C FA
|
|
00FB9C 1 ; Initialize pulse period/control using A and X.
|
|
00FB9C 1
|
|
00FB9C 1 ; ----------------------------------------------------------------------------
|
|
00FB9C 1 ; Decrement the effect timer, then continue through the later audio sequencer
|
|
00FB9C 1 ; at $FC94.
|
|
00FB9C 1 ; ----------------------------------------------------------------------------
|
|
00FB9C 1
|
|
00FB9C 1 UpdateAudioEffect2_CountDown: ; $FB9C
|
|
00FB9C 1 C6 F2 dec $F2 ; $FB9C: C6 F2
|
|
00FB9E 1
|
|
00FB9E 1 4C 94 FC jmp UpdateMusicSequencer ; $FB9E: 4C 94 FC
|
|
00FBA1 1
|
|
00FBA1 1 ; ============================================================================
|
|
00FBA1 1 ; $FBA1-$FBD2
|
|
00FBA1 1 ; Pulse effect controlled by the phase counter in $F4.
|
|
00FBA1 1 ; ============================================================================
|
|
00FBA1 1
|
|
00FBA1 1 StartPulse2PhaseEffect: ; $FBA1
|
|
00FBA1 1 84 F1 sty $F1 ; $FBA1: 84 F1
|
|
00FBA3 1
|
|
00FBA3 1 A9 20 lda #$20 ; $FBA3: A9 20
|
|
00FBA5 1 85 F4 sta $F4 ; $FBA5: 85 F4
|
|
00FBA7 1
|
|
00FBA7 1 D0 06 bne PulseEffectF4_Phase18 ; $FBA7: D0 06
|
|
00FBA9 1
|
|
00FBA9 1 UpdatePulse2PhaseEffect: ; $FBA9
|
|
00FBA9 1 A5 F4 lda $F4 ; $FBA9: A5 F4
|
|
00FBAB 1
|
|
00FBAB 1 C9 18 cmp #$18 ; $FBAB: C9 18
|
|
00FBAD 1 D0 04 bne PulseEffectF4_Phase10 ; $FBAD: D0 04
|
|
00FBAF 1
|
|
00FBAF 1 PulseEffectF4_Phase18: ; $FBAF
|
|
00FBAF 1 A9 08 lda #$08 ; $FBAF: A9 08
|
|
00FBB1 1 D0 06 bne PulseEffectF4_WriteTimer
|
|
00FBB3 1 ; $FBB1: D0 06
|
|
00FBB3 1
|
|
00FBB3 1 PulseEffectF4_Phase10: ; $FBB3
|
|
00FBB3 1 C9 10 cmp #$10 ; $FBB3: C9 10
|
|
00FBB5 1 D0 05 bne PulseEffectF4_Configure ; $FBB5: D0 05
|
|
00FBB7 1
|
|
00FBB7 1 A9 2E lda #$2E ; $FBB7: A9 2E
|
|
00FBB9 1
|
|
00FBB9 1 PulseEffectF4_WriteTimer: ; $FBB9
|
|
00FBB9 1 20 A6 FA jsr WritePulse2PeriodAfterSweep ; $FBB9: 20 A6 FA
|
|
00FBBC 1
|
|
00FBBC 1 PulseEffectF4_Configure: ; $FBBC
|
|
00FBBC 1 A2 9D ldx #$9D ; $FBBC: A2 9D
|
|
00FBBE 1 A0 83 ldy #$83 ; $FBBE: A0 83
|
|
00FBC0 1
|
|
00FBC0 1 A5 F4 lda $F4 ; $FBC0: A5 F4
|
|
00FBC2 1
|
|
00FBC2 1 C9 0C cmp #$0C ; $FBC2: C9 0C
|
|
00FBC4 1 B0 02 bcs PulseEffectF4_CheckUpper
|
|
00FBC6 1 ; $FBC4: B0 02
|
|
00FBC6 1
|
|
00FBC6 1 A0 84 ldy #$84 ; $FBC6: A0 84
|
|
00FBC8 1
|
|
00FBC8 1 PulseEffectF4_CheckUpper: ; $FBC8
|
|
00FBC8 1 C9 1A cmp #$1A ; $FBC8: C9 1A
|
|
00FBCA 1 B0 04 bcs PulseEffectF4_Apply ; $FBCA: B0 04
|
|
00FBCC 1
|
|
00FBCC 1 4A lsr ; $FBCC: 4A
|
|
00FBCD 1 09 90 ora #$90 ; $FBCD: 09 90
|
|
00FBCF 1 AA tax ; $FBCF: AA
|
|
00FBD0 1
|
|
00FBD0 1 PulseEffectF4_Apply: ; $FBD0
|
|
00FBD0 1 4C 55 FC jmp WritePulse2PhaseRegisters
|
|
00FBD3 1 ; $FBD0: 4C 55 FC
|
|
00FBD3 1
|
|
00FBD3 1 ; ============================================================================
|
|
00FBD3 1 ; $FBD3-$FBFE
|
|
00FBD3 1 ; Alternate pulse effect using the same shared register writer.
|
|
00FBD3 1 ; ============================================================================
|
|
00FBD3 1
|
|
00FBD3 1 StartAlternatePulse2PhaseEffect: ; $FBD3
|
|
00FBD3 1 84 F1 sty $F1 ; $FBD3: 84 F1
|
|
00FBD5 1
|
|
00FBD5 1 A9 1C lda #$1C ; $FBD5: A9 1C
|
|
00FBD7 1 85 F4 sta $F4 ; $FBD7: 85 F4
|
|
00FBD9 1
|
|
00FBD9 1 A9 12 lda #$12 ; $FBD9: A9 12
|
|
00FBDB 1 A2 98 ldx #$98 ; $FBDB: A2 98
|
|
00FBDD 1 A0 96 ldy #$96 ; $FBDD: A0 96
|
|
00FBDF 1
|
|
00FBDF 1 20 A3 FA jsr WritePulse2PeriodFromTable
|
|
00FBE2 1 ; $FBDF: 20 A3 FA
|
|
00FBE2 1
|
|
00FBE2 1 D0 74 bne CountDownPulse2PhaseEffect ; $FBE2: D0 74
|
|
00FBE4 1
|
|
00FBE4 1 UpdateAlternatePulse2PhaseEffect: ; $FBE4
|
|
00FBE4 1 A2 9C ldx #$9C ; $FBE4: A2 9C
|
|
00FBE6 1 A0 96 ldy #$96 ; $FBE6: A0 96
|
|
00FBE8 1
|
|
00FBE8 1 A5 F4 lda $F4 ; $FBE8: A5 F4
|
|
00FBEA 1 C9 18 cmp #$18 ; $FBEA: C9 18
|
|
00FBEC 1 B0 0A bcs PulseEffectAlternate_TestOdd
|
|
00FBEE 1 ; $FBEC: B0 0A
|
|
00FBEE 1
|
|
00FBEE 1 A0 86 ldy #$86 ; $FBEE: A0 86
|
|
00FBF0 1
|
|
00FBF0 1 4A lsr ; $FBF0: 4A
|
|
00FBF1 1 B0 08 bcs PulseEffectAlternate_Use90
|
|
00FBF3 1 ; $FBF1: B0 08
|
|
00FBF3 1
|
|
00FBF3 1 09 90 ora #$90 ; $FBF3: 09 90
|
|
00FBF5 1 AA tax ; $FBF5: AA
|
|
00FBF6 1
|
|
00FBF6 1 D0 5D bne WritePulse2PhaseRegisters
|
|
00FBF8 1 ; $FBF6: D0 5D
|
|
00FBF8 1
|
|
00FBF8 1 PulseEffectAlternate_TestOdd: ; $FBF8
|
|
00FBF8 1 4A lsr ; $FBF8: 4A
|
|
00FBF9 1 90 5A bcc WritePulse2PhaseRegisters
|
|
00FBFB 1 ; $FBF9: 90 5A
|
|
00FBFB 1
|
|
00FBFB 1 PulseEffectAlternate_Use90: ; $FBFB
|
|
00FBFB 1 A2 90 ldx #$90 ; $FBFB: A2 90
|
|
00FBFD 1 D0 56 bne WritePulse2PhaseRegisters
|
|
00FBFF 1 ; $FBFD: D0 56
|
|
00FBFF 1
|
|
00FBFF 1 ; ============================================================================
|
|
00FBFF 1 ; $FBFF-$FC1D
|
|
00FBFF 1 ; Secondary audio-effect dispatcher.
|
|
00FBFF 1 ; ============================================================================
|
|
00FBFF 1
|
|
00FBFF 1 UpdateSecondaryEffects: ; $FBFF
|
|
00FBFF 1 A4 FE ldy PendingAudioFlags ; $FBFF: A4 FE
|
|
00FC01 1 84 00 sty $00 ; $FC01: 84 00
|
|
00FC03 1
|
|
00FC03 1 A5 F1 lda $F1 ; $FC03: A5 F1
|
|
00FC05 1
|
|
00FC05 1 A6 FB ldx $FB ; $FC05: A6 FB
|
|
00FC07 1 D0 57 bne DispatchMusicAndNoise ; $FC07: D0 57
|
|
00FC09 1
|
|
00FC09 1 4A lsr ; $FC09: 4A
|
|
00FC0A 1 B0 9D bcs UpdatePulse2PhaseEffect ; $FC0A: B0 9D
|
|
00FC0C 1
|
|
00FC0C 1 46 FE lsr PendingAudioFlags ; $FC0C: 46 FE
|
|
00FC0E 1 B0 91 bcs StartPulse2PhaseEffect ; $FC0E: B0 91
|
|
00FC10 1
|
|
00FC10 1 4A lsr ; $FC10: 4A
|
|
00FC11 1 B0 D1 bcs UpdateAlternatePulse2PhaseEffect
|
|
00FC13 1 ; $FC11: B0 D1
|
|
00FC13 1
|
|
00FC13 1 46 FE lsr PendingAudioFlags ; $FC13: 46 FE
|
|
00FC15 1 B0 BC bcs StartAlternatePulse2PhaseEffect
|
|
00FC17 1 ; $FC15: B0 BC
|
|
00FC17 1
|
|
00FC17 1 4A lsr ; $FC17: 4A
|
|
00FC18 1 B0 19 bcs UpdateTrianglePitchSweep
|
|
00FC1A 1 ; $FC18: B0 19
|
|
00FC1A 1
|
|
00FC1A 1 46 FE lsr PendingAudioFlags ; $FC1A: 46 FE
|
|
00FC1C 1 90 42 bcc DispatchMusicAndNoise ; $FC1C: 90 42
|
|
00FC1E 1
|
|
00FC1E 1 ; ============================================================================
|
|
00FC1E 1 ; $FC1E-$FC32
|
|
00FC1E 1 ; Start the triangle sweep effect.
|
|
00FC1E 1 ; ============================================================================
|
|
00FC1E 1
|
|
00FC1E 1 StartTrianglePitchSweep: ; $FC1E
|
|
00FC1E 1 84 F1 sty $F1 ; $FC1E: 84 F1
|
|
00FC20 1
|
|
00FC20 1 A9 05 lda #$05 ; $FC20: A9 05
|
|
00FC22 1 85 F4 sta $F4 ; $FC22: 85 F4
|
|
00FC24 1
|
|
00FC24 1 A2 3F ldx #$3F ; $FC24: A2 3F
|
|
00FC26 1
|
|
00FC26 1 EE FD 07 inc $07FD ; $FC26: EE FD 07
|
|
00FC29 1
|
|
00FC29 1 AD FD 07 lda $07FD ; $FC29: AD FD 07
|
|
00FC2C 1 4A lsr ; $FC2C: 4A
|
|
00FC2D 1 90 02 bcc StartTriangleSweep_Save ; $FC2D: 90 02
|
|
00FC2F 1
|
|
00FC2F 1 A2 50 ldx #$50 ; $FC2F: A2 50
|
|
00FC31 1
|
|
00FC31 1 StartTriangleSweep_Save: ; $FC31
|
|
00FC31 1 86 F5 stx $F5 ; $FC31: 86 F5
|
|
00FC33 1
|
|
00FC33 1 ; ============================================================================
|
|
00FC33 1 ; $FC33-$FC5F
|
|
00FC33 1 ; Update the triangle sweep and shared pulse registers.
|
|
00FC33 1 ; ============================================================================
|
|
00FC33 1
|
|
00FC33 1 UpdateTrianglePitchSweep: ; $FC33
|
|
00FC33 1 A5 F5 lda $F5 ; $FC33: A5 F5
|
|
00FC35 1
|
|
00FC35 1 4A lsr ; $FC35: 4A
|
|
00FC36 1 4A lsr ; $FC36: 4A
|
|
00FC37 1 4A lsr ; $FC37: 4A
|
|
00FC38 1
|
|
00FC38 1 65 F5 adc $F5 ; $FC38: 65 F5
|
|
00FC3A 1 85 F5 sta $F5 ; $FC3A: 85 F5
|
|
00FC3C 1
|
|
00FC3C 1 0A asl ; $FC3C: 0A
|
|
00FC3D 1 0A asl ; $FC3D: 0A
|
|
00FC3E 1 8D 06 40 sta $4006 ; $FC3E: 8D 06 40
|
|
00FC41 1
|
|
00FC41 1 2A rol ; $FC41: 2A
|
|
00FC42 1 29 03 and #$03 ; $FC42: 29 03
|
|
00FC44 1 8D 07 40 sta $4007 ; $FC44: 8D 07 40
|
|
00FC47 1
|
|
00FC47 1 A0 81 ldy #$81 ; $FC47: A0 81
|
|
00FC49 1 A2 50 ldx #$50 ; $FC49: A2 50
|
|
00FC4B 1
|
|
00FC4B 1 A5 F4 lda $F4 ; $FC4B: A5 F4
|
|
00FC4D 1 C9 04 cmp #$04 ; $FC4D: C9 04
|
|
00FC4F 1 90 04 bcc WritePulse2PhaseRegisters
|
|
00FC51 1 ; $FC4F: 90 04
|
|
00FC51 1
|
|
00FC51 1 18 clc ; $FC51: 18
|
|
00FC52 1 69 4F adc #$4F ; $FC52: 69 4F
|
|
00FC54 1 AA tax ; $FC54: AA
|
|
00FC55 1
|
|
00FC55 1 WritePulse2PhaseRegisters: ; $FC55
|
|
00FC55 1 20 73 FA jsr WritePulse2SweepAndControlFromRegisters ; $FC55: 20 73 FA
|
|
00FC58 1
|
|
00FC58 1 CountDownPulse2PhaseEffect: ; $FC58
|
|
00FC58 1 C6 F4 dec $F4 ; $FC58: C6 F4
|
|
00FC5A 1 D0 04 bne DispatchMusicAndNoise ; $FC5A: D0 04
|
|
00FC5C 1
|
|
00FC5C 1 A9 00 lda #$00 ; $FC5C: A9 00
|
|
00FC5E 1 85 F1 sta $F1 ; $FC5E: 85 F1
|
|
00FC60 1
|
|
00FC60 1 ; ============================================================================
|
|
00FC60 1 ; $FC60-$FC99
|
|
00FC60 1 ; Dispatch miscellaneous audio events.
|
|
00FC60 1 ; ============================================================================
|
|
00FC60 1
|
|
00FC60 1 DispatchMusicAndNoise: ; $FC60
|
|
00FC60 1 A5 EF lda GameplaySuspended ; $FC60: A5 EF
|
|
00FC62 1 D0 30 bne UpdateMusicSequencer ; $FC62: D0 30
|
|
00FC64 1
|
|
00FC64 1 A4 00 ldy $00 ; $FC64: A4 00
|
|
00FC66 1 30 2F bmi UpdateNoiseEffectSequence ; $FC66: 30 2F
|
|
00FC68 1
|
|
00FC68 1 AD F5 07 lda $07F5 ; $FC68: AD F5 07
|
|
00FC6B 1
|
|
00FC6B 1 0A asl ; $FC6B: 0A
|
|
00FC6C 1 30 3A bmi UpdateDmcOutputEffect ; $FC6C: 30 3A
|
|
00FC6E 1
|
|
00FC6E 1 06 00 asl $00 ; $FC6E: 06 00
|
|
00FC70 1 30 28 bmi StartTriangleEffectShort ; $FC70: 30 28
|
|
00FC72 1
|
|
00FC72 1 0A asl ; $FC72: 0A
|
|
00FC73 1 30 5A bmi ContinueTimedAudioEffect ; $FC73: 30 5A
|
|
00FC75 1
|
|
00FC75 1 06 00 asl $00 ; $FC75: 06 00
|
|
00FC77 1 30 3B bmi StartTriangleEffectMedium ; $FC77: 30 3B
|
|
00FC79 1
|
|
00FC79 1 0A asl ; $FC79: 0A
|
|
00FC7A 1 30 68 bmi UpdateTriangleEffectLong ; $FC7A: 30 68
|
|
00FC7C 1
|
|
00FC7C 1 06 00 asl $00 ; $FC7C: 06 00
|
|
00FC7E 1 30 56 bmi StartTriangleEffectLong ; $FC7E: 30 56
|
|
00FC80 1
|
|
00FC80 1 0A asl ; $FC80: 0A
|
|
00FC81 1 30 7E bmi UpdateTriangleEffectAlternate ; $FC81: 30 7E
|
|
00FC83 1
|
|
00FC83 1 06 00 asl $00 ; $FC83: 06 00
|
|
00FC85 1 30 6C bmi StartTriangleEffectAlternate ; $FC85: 30 6C
|
|
00FC87 1
|
|
00FC87 1 ResetTimedAudioEvents: ; $FC87
|
|
00FC87 1 A9 00 lda #$00 ; $FC87: A9 00
|
|
00FC89 1
|
|
00FC89 1 8D FA 07 sta $07FA ; $FC89: 8D FA 07
|
|
00FC8C 1 8D F5 07 sta $07F5 ; $FC8C: 8D F5 07
|
|
00FC8F 1
|
|
00FC8F 1 A9 10 lda #$10 ; $FC8F: A9 10
|
|
00FC91 1 8D 0C 40 sta $400C ; $FC91: 8D 0C 40
|
|
00FC94 1
|
|
00FC94 1 UpdateMusicSequencer: ; $FC94
|
|
00FC94 1 4C 2A FD jmp UpdateMusicEngine ; $FC94: 4C 2A FD
|
|
00FC97 1
|
|
00FC97 1 UpdateNoiseEffectSequence: ; $FC97
|
|
00FC97 1 4C 14 FD jmp UpdateNoiseEnvelopeSequence ; $FC97: 4C 14 FD
|
|
00FC9A 1
|
|
00FC9A 1 ; ============================================================================
|
|
00FC9A 1 ; $FC9A-$FCA7
|
|
00FC9A 1 ; Audio event 2.
|
|
00FC9A 1 ; ============================================================================
|
|
00FC9A 1
|
|
00FC9A 1 StartTriangleEffectShort: ; $FC9A
|
|
00FC9A 1 8C F5 07 sty $07F5 ; $FC9A: 8C F5 07
|
|
00FC9D 1
|
|
00FC9D 1 A9 09 lda #$09 ; $FC9D: A9 09
|
|
00FC9F 1 8D F8 07 sta $07F8 ; $FC9F: 8D F8 07
|
|
00FCA2 1
|
|
00FCA2 1 A9 35 lda #$35 ; $FCA2: A9 35
|
|
00FCA4 1 A0 1C ldy #$1C ; $FCA4: A0 1C
|
|
00FCA6 1
|
|
00FCA6 1 D0 18 bne ConfigureTimedTriangleEffect ; $FCA6: D0 18
|
|
00FCA8 1
|
|
00FCA8 1 ; ============================================================================
|
|
00FCA8 1 ; $FCA8-$FCB3
|
|
00FCA8 1 ; Audio event 1.
|
|
00FCA8 1 ; ============================================================================
|
|
00FCA8 1
|
|
00FCA8 1 UpdateDmcOutputEffect: ; $FCA8
|
|
00FCA8 1 AD FF 07 lda $07FF ; $FCA8: AD FF 07
|
|
00FCAB 1
|
|
00FCAB 1 18 clc ; $FCAB: 18
|
|
00FCAC 1 69 10 adc #$10 ; $FCAC: 69 10
|
|
00FCAE 1 8D FF 07 sta $07FF ; $FCAE: 8D FF 07
|
|
00FCB1 1
|
|
00FCB1 1 4C CF FC jmp CountDownTimedAudioEffect ; $FCB1: 4C CF FC
|
|
00FCB4 1
|
|
00FCB4 1 ; ============================================================================
|
|
00FCB4 1 ; $FCB4-$FCD5
|
|
00FCB4 1 ; Audio event 4 and shared triangle-channel configuration.
|
|
00FCB4 1 ; ============================================================================
|
|
00FCB4 1
|
|
00FCB4 1 StartTriangleEffectMedium: ; $FCB4
|
|
00FCB4 1 8C F5 07 sty $07F5 ; $FCB4: 8C F5 07
|
|
00FCB7 1
|
|
00FCB7 1 A9 08 lda #$08 ; $FCB7: A9 08
|
|
00FCB9 1 8D F8 07 sta $07F8 ; $FCB9: 8D F8 07
|
|
00FCBC 1
|
|
00FCBC 1 A9 54 lda #$54 ; $FCBC: A9 54
|
|
00FCBE 1 A0 0A ldy #$0A ; $FCBE: A0 0A
|
|
00FCC0 1
|
|
00FCC0 1 ConfigureTimedTriangleEffect: ; $FCC0
|
|
00FCC0 1 8D 0A 40 sta $400A ; $FCC0: 8D 0A 40
|
|
00FCC3 1
|
|
00FCC3 1 A2 08 ldx #$08 ; $FCC3: A2 08
|
|
00FCC5 1 8E 0B 40 stx $400B ; $FCC5: 8E 0B 40
|
|
00FCC8 1
|
|
00FCC8 1 8C 08 40 sty $4008 ; $FCC8: 8C 08 40
|
|
00FCCB 1
|
|
00FCCB 1 A9 00 lda #$00 ; $FCCB: A9 00
|
|
00FCCD 1 85 F0 sta $F0 ; $FCCD: 85 F0
|
|
00FCCF 1
|
|
00FCCF 1 CountDownTimedAudioEffect: ; $FCCF
|
|
00FCCF 1 CE F8 07 dec $07F8 ; $FCCF: CE F8 07
|
|
00FCD2 1 F0 B3 beq ResetTimedAudioEvents ; $FCD2: F0 B3
|
|
00FCD4 1
|
|
00FCD4 1 D0 BE bne UpdateMusicSequencer ; $FCD4: D0 BE
|
|
00FCD6 1
|
|
00FCD6 1 ; ============================================================================
|
|
00FCD6 1 ; $FCD6-$FCE3
|
|
00FCD6 1 ; Initialize audio event 6.
|
|
00FCD6 1 ;
|
|
00FCD6 1 ; This event:
|
|
00FCD6 1 ; - saves the current event flags in $07F5
|
|
00FCD6 1 ; - initializes a countdown of $12 in $07F8
|
|
00FCD6 1 ; - selects triangle linear-counter value $06
|
|
00FCD6 1 ; - selects timer value $3F
|
|
00FCD6 1 ; - enters the shared triangle-channel configuration at $FCC0
|
|
00FCD6 1 ; ============================================================================
|
|
00FCD6 1
|
|
00FCD6 1 StartTriangleEffectLong: ; $FCD6
|
|
00FCD6 1 8C F5 07 sty $07F5 ; $FCD6: 8C F5 07
|
|
00FCD9 1 ; Preserve the active event flags.
|
|
00FCD9 1
|
|
00FCD9 1 A9 12 lda #$12 ; $FCD9: A9 12
|
|
00FCDB 1 8D F8 07 sta $07F8 ; $FCDB: 8D F8 07
|
|
00FCDE 1 ; Initialize the event countdown.
|
|
00FCDE 1
|
|
00FCDE 1 A0 06 ldy #$06 ; $FCDE: A0 06
|
|
00FCE0 1 ; Triangle linear-counter value.
|
|
00FCE0 1
|
|
00FCE0 1 A9 3F lda #$3F ; $FCE0: A9 3F
|
|
00FCE2 1 ; Triangle timer-low value.
|
|
00FCE2 1
|
|
00FCE2 1 D0 DC bne ConfigureTimedTriangleEffect ; $FCE2: D0 DC
|
|
00FCE4 1 ; Always taken.
|
|
00FCE4 1 ; Target $FCC0.
|
|
00FCE4 1
|
|
00FCE4 1 ; ============================================================================
|
|
00FCE4 1 ; $FCE4-$FCF2
|
|
00FCE4 1 ; Update audio event 5.
|
|
00FCE4 1 ;
|
|
00FCE4 1 ; The handler modifies the triangle-channel parameters at two countdown
|
|
00FCE4 1 ; thresholds:
|
|
00FCE4 1 ;
|
|
00FCE4 1 ; $07F8 = $0E:
|
|
00FCE4 1 ; use timer $3F and linear-counter value $06
|
|
00FCE4 1 ;
|
|
00FCE4 1 ; $07F8 = $0A:
|
|
00FCE4 1 ; use timer $3F and linear-counter value $20
|
|
00FCE4 1 ;
|
|
00FCE4 1 ; Other countdown values continue through the common countdown path at $FCCF.
|
|
00FCE4 1 ; ============================================================================
|
|
00FCE4 1
|
|
00FCE4 1 UpdateTriangleEffectLong: ; $FCE4
|
|
00FCE4 1 AD F8 07 lda $07F8 ; $FCE4: AD F8 07
|
|
00FCE7 1
|
|
00FCE7 1 C9 0E cmp #$0E ; $FCE7: C9 0E
|
|
00FCE9 1 F0 F3 beq AudioEvent_6_Configure ; $FCE9: F0 F3
|
|
00FCEB 1 ; Target $FCDE.
|
|
00FCEB 1
|
|
00FCEB 1 C9 0A cmp #$0A ; $FCEB: C9 0A
|
|
00FCED 1 D0 E0 bne CountDownTimedAudioEffect ; $FCED: D0 E0
|
|
00FCEF 1 ; Target $FCCF.
|
|
00FCEF 1
|
|
00FCEF 1 ; ----------------------------------------------------------------------------
|
|
00FCEF 1 ; At countdown $0A, use a larger triangle linear-counter value.
|
|
00FCEF 1 ; ----------------------------------------------------------------------------
|
|
00FCEF 1
|
|
00FCEF 1 A0 20 ldy #$20 ; $FCEF: A0 20
|
|
00FCF1 1
|
|
00FCF1 1 D0 ED bne AudioEvent_5_SetTimer ; $FCF1: D0 ED
|
|
00FCF3 1 ; Always taken.
|
|
00FCF3 1 ; Target $FCE0.
|
|
00FCF3 1
|
|
00FCF3 1 ; ----------------------------------------------------------------------------
|
|
00FCF3 1 ; Internal entry shared with StartTriangleEffectLong.
|
|
00FCF3 1 ; ----------------------------------------------------------------------------
|
|
00FCF3 1
|
|
00FCF3 1 AudioEvent_6_Configure = $FCDE
|
|
00FCF3 1 AudioEvent_5_SetTimer = $FCE0
|
|
00FCF3 1
|
|
00FCF3 1 ; ============================================================================
|
|
00FCF3 1 ; $FCF3-$FD00
|
|
00FCF3 1 ; Initialize audio event 8.
|
|
00FCF3 1 ;
|
|
00FCF3 1 ; This event:
|
|
00FCF3 1 ; - saves the current event flags
|
|
00FCF3 1 ; - initializes a countdown of $14
|
|
00FCF3 1 ; - selects triangle linear-counter value $18
|
|
00FCF3 1 ; - selects timer value $6A
|
|
00FCF3 1 ; - enters the shared triangle-channel configuration at $FCC0
|
|
00FCF3 1 ; ============================================================================
|
|
00FCF3 1
|
|
00FCF3 1 StartTriangleEffectAlternate: ; $FCF3
|
|
00FCF3 1 8C F5 07 sty $07F5 ; $FCF3: 8C F5 07
|
|
00FCF6 1
|
|
00FCF6 1 A9 14 lda #$14 ; $FCF6: A9 14
|
|
00FCF8 1 8D F8 07 sta $07F8 ; $FCF8: 8D F8 07
|
|
00FCFB 1
|
|
00FCFB 1 A0 18 ldy #$18 ; $FCFB: A0 18
|
|
00FCFD 1
|
|
00FCFD 1 AudioEvent_8_SetTimer: ; $FCFD
|
|
00FCFD 1 A9 6A lda #$6A ; $FCFD: A9 6A
|
|
00FCFF 1
|
|
00FCFF 1 D0 BF bne ConfigureTimedTriangleEffect ; $FCFF: D0 BF
|
|
00FD01 1 ; Always taken.
|
|
00FD01 1 ; Target $FCC0.
|
|
00FD01 1
|
|
00FD01 1 ; ============================================================================
|
|
00FD01 1 ; $FD01-$FD0B
|
|
00FD01 1 ; Update audio event 7.
|
|
00FD01 1 ;
|
|
00FD01 1 ; At countdown value $08, the triangle linear-counter value changes to $10
|
|
00FD01 1 ; while retaining timer value $6A.
|
|
00FD01 1 ;
|
|
00FD01 1 ; All other countdown values use the common countdown path at $FCCF.
|
|
00FD01 1 ; ============================================================================
|
|
00FD01 1
|
|
00FD01 1 UpdateTriangleEffectAlternate: ; $FD01
|
|
00FD01 1 AD F8 07 lda $07F8 ; $FD01: AD F8 07
|
|
00FD04 1
|
|
00FD04 1 C9 08 cmp #$08 ; $FD04: C9 08
|
|
00FD06 1 D0 C7 bne CountDownTimedAudioEffect ; $FD06: D0 C7
|
|
00FD08 1 ; Target $FCCF.
|
|
00FD08 1
|
|
00FD08 1 A0 10 ldy #$10 ; $FD08: A0 10
|
|
00FD0A 1
|
|
00FD0A 1 D0 F1 bne AudioEvent_8_SetTimer ; $FD0A: D0 F1
|
|
00FD0C 1 ; Always taken.
|
|
00FD0C 1 ; Target $FCFD.
|
|
00FD0C 1
|
|
00FD0C 1 ; ============================================================================
|
|
00FD0C 1 ; Existing target definition.
|
|
00FD0C 1 ;
|
|
00FD0C 1 ; ContinueTimedAudioEffect is the shared countdown path itself. The dispatcher branch at
|
|
00FD0C 1 ; $FC73 intentionally enters at $FCCF.
|
|
00FD0C 1 ; ============================================================================
|
|
00FD0C 1
|
|
00FD0C 1 ContinueTimedAudioEffect = CountDownTimedAudioEffect
|
|
00FD0C 1
|
|
00FD0C 1 ; ============================================================================
|
|
00FD0C 1 ; $FD0C-$FD13
|
|
00FD0C 1 ; Eight-entry audio lookup table.
|
|
00FD0C 1 ;
|
|
00FD0C 1 ; The routine beginning at $FD14 derives a three-bit index and uses it to load
|
|
00FD0C 1 ; one of these values.
|
|
00FD0C 1 ; ============================================================================
|
|
00FD0C 1
|
|
00FD0C 1 NoiseEnvelopeSequence: ; $FD0C
|
|
00FD0C 1 12 13 14 15 .byte $12,$13,$14,$15
|
|
00FD10 1 15 14 13 13 .byte $15,$14,$13,$13
|
|
00FD14 1
|
|
00FD14 1 ; ============================================================================
|
|
00FD14 1 ; $FD14-$FD29
|
|
00FD14 1 ; Update a table-driven noise or effect value from the sequence counter $07FA.
|
|
00FD14 1 ;
|
|
00FD14 1 ; The high five bits of $07FA select one of eight entries in the table at
|
|
00FD14 1 ; $FD0C. The selected value is passed to ConfigureNoiseChannel at $FA7A with
|
|
00FD14 1 ; X=$0E.
|
|
00FD14 1 ;
|
|
00FD14 1 ; Exit:
|
|
00FD14 1 ; $07FA incremented
|
|
00FD14 1 ; ============================================================================
|
|
00FD14 1
|
|
00FD14 1 UpdateNoiseEnvelopeSequence: ; $FD14
|
|
00FD14 1 AD FA 07 lda $07FA ; $FD14: AD FA 07
|
|
00FD17 1
|
|
00FD17 1 4A lsr ; $FD17: 4A
|
|
00FD18 1 4A lsr ; $FD18: 4A
|
|
00FD19 1 4A lsr ; $FD19: 4A
|
|
00FD1A 1 4A lsr ; $FD1A: 4A
|
|
00FD1B 1 4A lsr ; $FD1B: 4A
|
|
00FD1C 1
|
|
00FD1C 1 29 07 and #$07 ; $FD1C: 29 07
|
|
00FD1E 1 A8 tay ; $FD1E: A8
|
|
00FD1F 1
|
|
00FD1F 1 B9 0C FD lda NoiseEnvelopeSequence,y
|
|
00FD22 1 ; $FD1F: B9 0C FD
|
|
00FD22 1
|
|
00FD22 1 A2 0E ldx #$0E ; $FD22: A2 0E
|
|
00FD24 1
|
|
00FD24 1 20 7A FA jsr ConfigureNoiseChannel ; $FD24: 20 7A FA
|
|
00FD27 1
|
|
00FD27 1 EE FA 07 inc $07FA ; $FD27: EE FA 07
|
|
00FD2A 1
|
|
00FD2A 1 ; ============================================================================
|
|
00FD2A 1 ; $FD2A-$FD66
|
|
00FD2A 1 ; Initialize a music or note-sequence stream when required.
|
|
00FD2A 1 ;
|
|
00FD2A 1 ; State:
|
|
00FD2A 1 ; $FD = sequence request or selector
|
|
00FD2A 1 ; $FC = selected sequence bank
|
|
00FD2A 1 ; $FA/$FB = channel stream cursors
|
|
00FD2A 1 ; $F6-$FA = five-byte stream descriptor loaded from the table at $FE40
|
|
00FD2A 1 ; $07F0-$07F2 = per-channel countdowns
|
|
00FD2A 1 ; ============================================================================
|
|
00FD2A 1
|
|
00FD2A 1 UpdateMusicEngine: ; $FD2A
|
|
00FD2A 1 A5 FD lda $FD ; $FD2A: A5 FD
|
|
00FD2C 1 D0 06 bne StartMusicSequence ; $FD2C: D0 06
|
|
00FD2E 1
|
|
00FD2E 1 AD F4 07 lda $07F4 ; $FD2E: AD F4 07
|
|
00FD31 1 D0 34 bne UpdatePulse1MusicChannel ; $FD31: D0 34
|
|
00FD33 1
|
|
00FD33 1 60 rts ; $FD33: 60
|
|
00FD34 1
|
|
00FD34 1 ; ----------------------------------------------------------------------------
|
|
00FD34 1 ; Convert the sequence selector in A into a bank index in Y.
|
|
00FD34 1 ;
|
|
00FD34 1 ; The loop shifts A left until carry becomes set, decrementing Y for each
|
|
00FD34 1 ; unsuccessful shift.
|
|
00FD34 1 ; ----------------------------------------------------------------------------
|
|
00FD34 1
|
|
00FD34 1 StartMusicSequence: ; $FD34
|
|
00FD34 1 A0 07 ldy #$07 ; $FD34: A0 07
|
|
00FD36 1
|
|
00FD36 1 InitializeMusicSequence_FindBank: ; $FD36
|
|
00FD36 1 0A asl ; $FD36: 0A
|
|
00FD37 1 B0 03 bcs InitializeMusicSequence_BankFound
|
|
00FD39 1 ; $FD37: B0 03
|
|
00FD39 1
|
|
00FD39 1 88 dey ; $FD39: 88
|
|
00FD3A 1 D0 FA bne InitializeMusicSequence_FindBank
|
|
00FD3C 1 ; $FD3A: D0 FA
|
|
00FD3C 1
|
|
00FD3C 1 ; ----------------------------------------------------------------------------
|
|
00FD3C 1 ; Mark that a sequence is active and save the selected bank.
|
|
00FD3C 1 ; ----------------------------------------------------------------------------
|
|
00FD3C 1
|
|
00FD3C 1 InitializeMusicSequence_BankFound: ; $FD3C
|
|
00FD3C 1 EE F4 07 inc $07F4 ; $FD3C: EE F4 07
|
|
00FD3F 1
|
|
00FD3F 1 84 FC sty $FC ; $FD3F: 84 FC
|
|
00FD41 1
|
|
00FD41 1 ; ----------------------------------------------------------------------------
|
|
00FD41 1 ; Bank one is remapped to bank zero.
|
|
00FD41 1 ; ----------------------------------------------------------------------------
|
|
00FD41 1
|
|
00FD41 1 C0 01 cpy #$01 ; $FD41: C0 01
|
|
00FD43 1 D0 04 bne InitializeMusicSequence_LoadPointer
|
|
00FD45 1 ; $FD43: D0 04
|
|
00FD45 1
|
|
00FD45 1 A9 00 lda #$00 ; $FD45: A9 00
|
|
00FD47 1 85 FC sta $FC ; $FD47: 85 FC
|
|
00FD49 1
|
|
00FD49 1 ; ----------------------------------------------------------------------------
|
|
00FD49 1 ; The table at $FE40 contains an outer pointer/index byte followed by a five-byte
|
|
00FD49 1 ; stream descriptor. The first lookup maps the selected bank to the descriptor
|
|
00FD49 1 ; offset.
|
|
00FD49 1 ; ----------------------------------------------------------------------------
|
|
00FD49 1
|
|
00FD49 1 InitializeMusicSequence_LoadPointer: ; $FD49
|
|
00FD49 1 B9 40 FE lda $FE40,y ; $FD49: B9 40 FE
|
|
00FD4C 1 A8 tay ; $FD4C: A8
|
|
00FD4D 1
|
|
00FD4D 1 A2 00 ldx #$00 ; $FD4D: A2 00
|
|
00FD4F 1 86 FB stx $FB ; $FD4F: 86 FB
|
|
00FD51 1
|
|
00FD51 1 ; ----------------------------------------------------------------------------
|
|
00FD51 1 ; Copy five bytes from the selected descriptor into $F6-$FA.
|
|
00FD51 1 ; ----------------------------------------------------------------------------
|
|
00FD51 1
|
|
00FD51 1 InitializeMusicSequence_CopyDescriptor: ; $FD51
|
|
00FD51 1 B9 40 FE lda $FE40,y ; $FD51: B9 40 FE
|
|
00FD54 1 95 F6 sta $F6,x ; $FD54: 95 F6
|
|
00FD56 1
|
|
00FD56 1 C8 iny ; $FD56: C8
|
|
00FD57 1 E8 inx ; $FD57: E8
|
|
00FD58 1
|
|
00FD58 1 E0 05 cpx #$05 ; $FD58: E0 05
|
|
00FD5A 1 D0 F5 bne InitializeMusicSequence_CopyDescriptor
|
|
00FD5C 1 ; $FD5A: D0 F5
|
|
00FD5C 1
|
|
00FD5C 1 ; ----------------------------------------------------------------------------
|
|
00FD5C 1 ; Initialize all three channel countdowns to one so each channel fetches its
|
|
00FD5C 1 ; first command immediately.
|
|
00FD5C 1 ; ----------------------------------------------------------------------------
|
|
00FD5C 1
|
|
00FD5C 1 A9 01 lda #$01 ; $FD5C: A9 01
|
|
00FD5E 1
|
|
00FD5E 1 8D F0 07 sta $07F0 ; $FD5E: 8D F0 07
|
|
00FD61 1 8D F1 07 sta $07F1 ; $FD61: 8D F1 07
|
|
00FD64 1 8D F2 07 sta $07F2 ; $FD64: 8D F2 07
|
|
00FD67 1
|
|
00FD67 1 ; ============================================================================
|
|
00FD67 1 ; $FD67-$FDB8
|
|
00FD67 1 ; Update the first music channel.
|
|
00FD67 1 ;
|
|
00FD67 1 ; $FA is the channel stream cursor. $07F1 is its countdown.
|
|
00FD67 1 ; ============================================================================
|
|
00FD67 1
|
|
00FD67 1 UpdatePulse1MusicChannel: ; $FD67
|
|
00FD67 1 A4 FA ldy $FA ; $FD67: A4 FA
|
|
00FD69 1 F0 4E beq UpdatePulse2MusicChannel ; $FD69: F0 4E
|
|
00FD6B 1
|
|
00FD6B 1 ; ----------------------------------------------------------------------------
|
|
00FD6B 1 ; For sequence bank zero, reset pulse 1 when the countdown reaches two.
|
|
00FD6B 1 ; ----------------------------------------------------------------------------
|
|
00FD6B 1
|
|
00FD6B 1 A5 FC lda $FC ; $FD6B: A5 FC
|
|
00FD6D 1 D0 0A bne UpdateMusicChannel1_Decrement
|
|
00FD6F 1 ; $FD6D: D0 0A
|
|
00FD6F 1
|
|
00FD6F 1 AD F1 07 lda $07F1 ; $FD6F: AD F1 07
|
|
00FD72 1 C9 02 cmp #$02 ; $FD72: C9 02
|
|
00FD74 1 D0 03 bne UpdateMusicChannel1_Decrement
|
|
00FD76 1 ; $FD74: D0 03
|
|
00FD76 1
|
|
00FD76 1 20 60 FA jsr ConfigurePulse1ControlPreset
|
|
00FD79 1 ; $FD76: 20 60 FA
|
|
00FD79 1
|
|
00FD79 1 ; ----------------------------------------------------------------------------
|
|
00FD79 1 ; Count down the current note duration.
|
|
00FD79 1 ; ----------------------------------------------------------------------------
|
|
00FD79 1
|
|
00FD79 1 UpdateMusicChannel1_Decrement: ; $FD79
|
|
00FD79 1 CE F1 07 dec $07F1 ; $FD79: CE F1 07
|
|
00FD7C 1 D0 3B bne UpdatePulse2MusicChannel ; $FD7C: D0 3B
|
|
00FD7E 1
|
|
00FD7E 1 ; ----------------------------------------------------------------------------
|
|
00FD7E 1 ; Fetch the next stream command.
|
|
00FD7E 1 ; ----------------------------------------------------------------------------
|
|
00FD7E 1
|
|
00FD7E 1 E6 FA inc $FA ; $FD7E: E6 FA
|
|
00FD80 1
|
|
00FD80 1 B1 F7 lda ($F7),y ; $FD80: B1 F7
|
|
00FD82 1 10 0C bpl UpdateMusicChannel1_HaveNote
|
|
00FD84 1 ; $FD82: 10 0C
|
|
00FD84 1
|
|
00FD84 1 ; ----------------------------------------------------------------------------
|
|
00FD84 1 ; Negative bytes are extended commands. Decode the duration/control value and
|
|
00FD84 1 ; fetch the following note byte.
|
|
00FD84 1 ; ----------------------------------------------------------------------------
|
|
00FD84 1
|
|
00FD84 1 20 C5 FA jsr LookupAudioControlValueFinalRotate ; $FD84: 20 C5 FA
|
|
00FD87 1 8D F3 07 sta $07F3 ; $FD87: 8D F3 07
|
|
00FD8A 1
|
|
00FD8A 1 A4 FA ldy $FA ; $FD8A: A4 FA
|
|
00FD8C 1 E6 FA inc $FA ; $FD8C: E6 FA
|
|
00FD8E 1
|
|
00FD8E 1 B1 F7 lda ($F7),y ; $FD8E: B1 F7
|
|
00FD90 1
|
|
00FD90 1 ; ----------------------------------------------------------------------------
|
|
00FD90 1 ; Convert the note value through the audio period helper at $FA8F.
|
|
00FD90 1 ; ----------------------------------------------------------------------------
|
|
00FD90 1
|
|
00FD90 1 UpdateMusicChannel1_HaveNote: ; $FD90
|
|
00FD90 1 20 8F FA jsr WritePulsePeriod_SelectChannel ; $FD90: 20 8F FA
|
|
00FD93 1
|
|
00FD93 1 D0 04 bne UpdateMusicChannel1_SelectControl
|
|
00FD95 1 ; $FD93: D0 04
|
|
00FD95 1
|
|
00FD95 1 A2 10 ldx #$10 ; $FD95: A2 10
|
|
00FD97 1 D0 17 bne UpdateMusicChannel1_Write
|
|
00FD99 1 ; $FD97: D0 17
|
|
00FD99 1
|
|
00FD99 1 ; ----------------------------------------------------------------------------
|
|
00FD99 1 ; Select pulse control according to sequence bank, duration, and channel state.
|
|
00FD99 1 ; ----------------------------------------------------------------------------
|
|
00FD99 1
|
|
00FD99 1 UpdateMusicChannel1_SelectControl: ; $FD99
|
|
00FD99 1 A2 5A ldx #$5A ; $FD99: A2 5A
|
|
00FD9B 1
|
|
00FD9B 1 A5 FC lda $FC ; $FD9B: A5 FC
|
|
00FD9D 1 F0 11 beq UpdateMusicChannel1_Write
|
|
00FD9F 1 ; $FD9D: F0 11
|
|
00FD9F 1
|
|
00FD9F 1 A2 46 ldx #$46 ; $FD9F: A2 46
|
|
00FDA1 1
|
|
00FDA1 1 AD F3 07 lda $07F3 ; $FDA1: AD F3 07
|
|
00FDA4 1 C9 08 cmp #$08 ; $FDA4: C9 08
|
|
00FDA6 1 B0 02 bcs UpdateMusicChannel1_CheckAlt
|
|
00FDA8 1 ; $FDA6: B0 02
|
|
00FDA8 1
|
|
00FDA8 1 A2 42 ldx #$42 ; $FDA8: A2 42
|
|
00FDAA 1
|
|
00FDAA 1 UpdateMusicChannel1_CheckAlt: ; $FDAA
|
|
00FDAA 1 A5 F9 lda $F9 ; $FDAA: A5 F9
|
|
00FDAC 1 D0 02 bne UpdateMusicChannel1_Write
|
|
00FDAE 1 ; $FDAC: D0 02
|
|
00FDAE 1
|
|
00FDAE 1 A2 86 ldx #$86 ; $FDAE: A2 86
|
|
00FDB0 1
|
|
00FDB0 1 ; ----------------------------------------------------------------------------
|
|
00FDB0 1 ; Write pulse channel 1 sweep/control and reload the note countdown.
|
|
00FDB0 1 ; ----------------------------------------------------------------------------
|
|
00FDB0 1
|
|
00FDB0 1 UpdateMusicChannel1_Write: ; $FDB0
|
|
00FDB0 1 20 68 FA jsr WritePulse1SweepAndControl ; $FDB0: 20 68 FA
|
|
00FDB3 1
|
|
00FDB3 1 AD F3 07 lda $07F3 ; $FDB3: AD F3 07
|
|
00FDB6 1 8D F1 07 sta $07F1 ; $FDB6: 8D F1 07
|
|
00FDB9 1
|
|
00FDB9 1 ; ============================================================================
|
|
00FDB9 1 ; $FDB9-$FE04
|
|
00FDB9 1 ; Update the second music channel.
|
|
00FDB9 1 ;
|
|
00FDB9 1 ; $FB is the channel stream cursor. $07F0 is its countdown.
|
|
00FDB9 1 ; ============================================================================
|
|
00FDB9 1
|
|
00FDB9 1 UpdatePulse2MusicChannel: ; $FDB9
|
|
00FDB9 1 A5 FC lda $FC ; $FDB9: A5 FC
|
|
00FDBB 1 D0 0A bne UpdateMusicChannel2_Decrement
|
|
00FDBD 1 ; $FDBB: D0 0A
|
|
00FDBD 1
|
|
00FDBD 1 AD F0 07 lda $07F0 ; $FDBD: AD F0 07
|
|
00FDC0 1 C9 02 cmp #$02 ; $FDC0: C9 02
|
|
00FDC2 1 D0 03 bne UpdateMusicChannel2_Decrement
|
|
00FDC4 1 ; $FDC2: D0 03
|
|
00FDC4 1
|
|
00FDC4 1 20 64 FA jsr ConfigurePulse2ControlPreset
|
|
00FDC7 1 ; $FDC4: 20 64 FA
|
|
00FDC7 1
|
|
00FDC7 1 UpdateMusicChannel2_Decrement: ; $FDC7
|
|
00FDC7 1 CE F0 07 dec $07F0 ; $FDC7: CE F0 07
|
|
00FDCA 1 D0 39 bne UpdateTriangleMusicChannel ; $FDCA: D0 39
|
|
00FDCC 1
|
|
00FDCC 1 ; ----------------------------------------------------------------------------
|
|
00FDCC 1 ; Fetch the next byte from the second channel stream.
|
|
00FDCC 1 ; ----------------------------------------------------------------------------
|
|
00FDCC 1
|
|
00FDCC 1 A4 FB ldy $FB ; $FDCC: A4 FB
|
|
00FDCE 1 E6 FB inc $FB ; $FDCE: E6 FB
|
|
00FDD0 1
|
|
00FDD0 1 B1 F7 lda ($F7),y ; $FDD0: B1 F7
|
|
00FDD2 1 D0 0B bne UpdateMusicChannel2_HaveCommand
|
|
00FDD4 1 ; $FDD2: D0 0B
|
|
00FDD4 1
|
|
00FDD4 1 ; ----------------------------------------------------------------------------
|
|
00FDD4 1 ; A zero byte terminates the complete music sequence.
|
|
00FDD4 1 ; ----------------------------------------------------------------------------
|
|
00FDD4 1
|
|
00FDD4 1 85 FB sta $FB ; $FDD4: 85 FB
|
|
00FDD6 1 85 FA sta $FA ; $FDD6: 85 FA
|
|
00FDD8 1 8D F4 07 sta $07F4 ; $FDD8: 8D F4 07
|
|
00FDDB 1
|
|
00FDDB 1 20 60 FA jsr ConfigurePulse1ControlPreset
|
|
00FDDE 1 ; $FDDB: 20 60 FA
|
|
00FDDE 1
|
|
00FDDE 1 60 rts ; $FDDE: 60
|
|
00FDDF 1
|
|
00FDDF 1 ; ----------------------------------------------------------------------------
|
|
00FDDF 1 ; Decode the command and write the pulse 2 period/control.
|
|
00FDDF 1 ; ----------------------------------------------------------------------------
|
|
00FDDF 1
|
|
00FDDF 1 UpdateMusicChannel2_HaveCommand: ; $FDDF
|
|
00FDDF 1 20 BF FA jsr LookupAudioControlValue ; $FDDF: 20 BF FA
|
|
00FDE2 1 8D F0 07 sta $07F0 ; $FDE2: 8D F0 07
|
|
00FDE5 1
|
|
00FDE5 1 8A txa ; $FDE5: 8A
|
|
00FDE6 1 29 3E and #$3E ; $FDE6: 29 3E
|
|
00FDE8 1
|
|
00FDE8 1 20 A6 FA jsr WritePulse2PeriodAfterSweep ; $FDE8: 20 A6 FA
|
|
00FDEB 1
|
|
00FDEB 1 D0 04 bne UpdateMusicChannel2_SelectControl
|
|
00FDED 1 ; $FDEB: D0 04
|
|
00FDED 1
|
|
00FDED 1 A2 90 ldx #$90 ; $FDED: A2 90
|
|
00FDEF 1 D0 11 bne UpdateMusicChannel2_Write
|
|
00FDF1 1 ; $FDEF: D0 11
|
|
00FDF1 1
|
|
00FDF1 1 UpdateMusicChannel2_SelectControl: ; $FDF1
|
|
00FDF1 1 A2 9D ldx #$9D ; $FDF1: A2 9D
|
|
00FDF3 1
|
|
00FDF3 1 A5 FC lda $FC ; $FDF3: A5 FC
|
|
00FDF5 1 F0 0B beq UpdateMusicChannel2_Write
|
|
00FDF7 1 ; $FDF5: F0 0B
|
|
00FDF7 1
|
|
00FDF7 1 A2 86 ldx #$86 ; $FDF7: A2 86
|
|
00FDF9 1
|
|
00FDF9 1 AD F0 07 lda $07F0 ; $FDF9: AD F0 07
|
|
00FDFC 1 C9 08 cmp #$08 ; $FDFC: C9 08
|
|
00FDFE 1 B0 02 bcs UpdateMusicChannel2_Write
|
|
00FE00 1 ; $FDFE: B0 02
|
|
00FE00 1
|
|
00FE00 1 A2 82 ldx #$82 ; $FE00: A2 82
|
|
00FE02 1
|
|
00FE02 1 UpdateMusicChannel2_Write: ; $FE02
|
|
00FE02 1 20 71 FA jsr WritePulse2SweepAndControl ; $FE02: 20 71 FA
|
|
00FE05 1
|
|
00FE05 1 ; ============================================================================
|
|
00FE05 1 ; $FE05-$FE3F
|
|
00FE05 1 ; Update the triangle music channel.
|
|
00FE05 1 ;
|
|
00FE05 1 ; $F9 is the stream cursor and $07F2 is the countdown.
|
|
00FE05 1 ; ============================================================================
|
|
00FE05 1
|
|
00FE05 1 UpdateTriangleMusicChannel: ; $FE05
|
|
00FE05 1 A4 F9 ldy $F9 ; $FE05: A4 F9
|
|
00FE07 1 F0 36 beq UpdateMusicSequence_Return
|
|
00FE09 1 ; $FE07: F0 36
|
|
00FE09 1
|
|
00FE09 1 AD F2 07 lda $07F2 ; $FE09: AD F2 07
|
|
00FE0C 1 C9 02 cmp #$02 ; $FE0C: C9 02
|
|
00FE0E 1 D0 05 bne UpdateMusicChannel3_Decrement
|
|
00FE10 1 ; $FE0E: D0 05
|
|
00FE10 1
|
|
00FE10 1 A9 00 lda #$00 ; $FE10: A9 00
|
|
00FE12 1 8D 08 40 sta $4008 ; $FE12: 8D 08 40
|
|
00FE15 1
|
|
00FE15 1 UpdateMusicChannel3_Decrement: ; $FE15
|
|
00FE15 1 CE F2 07 dec $07F2 ; $FE15: CE F2 07
|
|
00FE18 1 D0 25 bne UpdateMusicSequence_Return
|
|
00FE1A 1 ; $FE18: D0 25
|
|
00FE1A 1
|
|
00FE1A 1 ; ----------------------------------------------------------------------------
|
|
00FE1A 1 ; Fetch and decode the next triangle-channel command.
|
|
00FE1A 1 ; ----------------------------------------------------------------------------
|
|
00FE1A 1
|
|
00FE1A 1 E6 F9 inc $F9 ; $FE1A: E6 F9
|
|
00FE1C 1
|
|
00FE1C 1 B1 F7 lda ($F7),y ; $FE1C: B1 F7
|
|
00FE1E 1 20 BF FA jsr LookupAudioControlValue ; $FE1E: 20 BF FA
|
|
00FE21 1
|
|
00FE21 1 8D F2 07 sta $07F2 ; $FE21: 8D F2 07
|
|
00FE24 1
|
|
00FE24 1 ; ----------------------------------------------------------------------------
|
|
00FE24 1 ; Select the triangle linear-counter value.
|
|
00FE24 1 ; ----------------------------------------------------------------------------
|
|
00FE24 1
|
|
00FE24 1 A0 38 ldy #$38 ; $FE24: A0 38
|
|
00FE26 1
|
|
00FE26 1 18 clc ; $FE26: 18
|
|
00FE27 1 69 FF adc #$FF ; $FE27: 69 FF
|
|
00FE29 1
|
|
00FE29 1 C9 0E cmp #$0E ; $FE29: C9 0E
|
|
00FE2B 1 B0 03 bcs UpdateMusicChannel3_CheckBank
|
|
00FE2D 1 ; $FE2B: B0 03
|
|
00FE2D 1
|
|
00FE2D 1 0A asl ; $FE2D: 0A
|
|
00FE2E 1 0A asl ; $FE2E: 0A
|
|
00FE2F 1 A8 tay ; $FE2F: A8
|
|
00FE30 1
|
|
00FE30 1 UpdateMusicChannel3_CheckBank: ; $FE30
|
|
00FE30 1 A5 FC lda $FC ; $FE30: A5 FC
|
|
00FE32 1 D0 02 bne UpdateMusicChannel3_WriteLinear
|
|
00FE34 1 ; $FE32: D0 02
|
|
00FE34 1
|
|
00FE34 1 A0 88 ldy #$88 ; $FE34: A0 88
|
|
00FE36 1
|
|
00FE36 1 UpdateMusicChannel3_WriteLinear: ; $FE36
|
|
00FE36 1 8C 08 40 sty $4008 ; $FE36: 8C 08 40
|
|
00FE39 1
|
|
00FE39 1 ; ----------------------------------------------------------------------------
|
|
00FE39 1 ; Use the command byte preserved in X by LookupAudioControlValue to select the
|
|
00FE39 1 ; triangle timer period.
|
|
00FE39 1 ; ----------------------------------------------------------------------------
|
|
00FE39 1
|
|
00FE39 1 8A txa ; $FE39: 8A
|
|
00FE3A 1 29 3E and #$3E ; $FE3A: 29 3E
|
|
00FE3C 1
|
|
00FE3C 1 20 AA FA jsr WriteTrianglePeriodFromTable
|
|
00FE3F 1 ; $FE3C: 20 AA FA
|
|
00FE3F 1
|
|
00FE3F 1 UpdateMusicSequence_Return: ; $FE3F
|
|
00FE3F 1 60 rts ; $FE3F: 60
|
|
00FE40 1
|
|
00FE40 1 ; ============================================================================
|
|
00FE40 1 ; $FE40-$FFCF
|
|
00FE40 1 ; Music sequence, note, duration, envelope, and instrument data.
|
|
00FE40 1 ;
|
|
00FE40 1 ; This region is consumed by the sequence engine decoded at $FD14-$FE3F.
|
|
00FE40 1 ; It includes:
|
|
00FE40 1 ;
|
|
00FE40 1 ; - sequence descriptor records
|
|
00FE40 1 ; - note and duration command streams
|
|
00FE40 1 ; - channel-control values
|
|
00FE40 1 ; - instrument and envelope sequences
|
|
00FE40 1 ; - pointers or offsets into the surrounding audio data
|
|
00FE40 1 ;
|
|
00FE40 1 ; Preserve the bytes exactly. Several streams use zero bytes, negative command
|
|
00FE40 1 ; bytes, and compact variable-length records, so speculative instruction
|
|
00FE40 1 ; decoding would incorrectly interpret data as executable code.
|
|
00FE40 1 ; ============================================================================
|
|
00FE40 1
|
|
00FE40 1 MusicSequenceData: ; $FE40
|
|
00FE40 1 08 08 0D 17 .byte $08,$08,$0D,$17,$12,$1C,$21,$26
|
|
00FE44 1 12 1C 21 26
|
|
00FE48 1 08 6B FE 15 .byte $08,$6B,$FE,$15,$20,$08,$20,$FF
|
|
00FE4C 1 20 08 20 FF
|
|
00FE50 1 28 0C 00 D9 .byte $28,$0C,$00,$D9,$FF,$00,$00,$00
|
|
00FE54 1 FF 00 00 00
|
|
00FE58 1 51 FF 6E 2A .byte $51,$FF,$6E,$2A,$08,$02,$FF,$0E
|
|
00FE5C 1 08 02 FF 0E
|
|
00FE60 1
|
|
00FE60 1 MusicSequenceData_FE60: ; $FE60
|
|
00FE60 1 00 08 EA FE .byte $00,$08,$EA,$FE,$0C,$00,$08,$A5
|
|
00FE64 1 0C 00 08 A5
|
|
00FE68 1 FE 1A 2A 18 .byte $FE,$1A,$2A,$18,$04,$18,$18,$58
|
|
00FE6C 1 04 18 18 58
|
|
00FE70 1 A0 58 20 04 .byte $A0,$58,$20,$04,$20,$20,$60,$A6
|
|
00FE74 1 20 20 60 A6
|
|
00FE78 1 60 26 04 26 .byte $60,$26,$04,$26,$26,$66,$87,$00
|
|
00FE7C 1 26 66 87 00
|
|
00FE80 1
|
|
00FE80 1 MusicSequenceData_FE80: ; $FE80
|
|
00FE80 1 45 45 45 98 .byte $45,$45,$45,$98,$78,$18,$04,$18
|
|
00FE84 1 78 18 04 18
|
|
00FE88 1 18 58 A7 85 .byte $18,$58,$A7,$85,$04,$82,$18,$81
|
|
00FE8C 1 04 82 18 81
|
|
00FE90 1 38 80 18 04 .byte $38,$80,$18,$04,$18,$18,$81,$18
|
|
00FE94 1 18 18 81 18
|
|
00FE98 1 82 20 81 18 .byte $82,$20,$81,$18,$80,$20,$04,$20
|
|
00FE9C 1 80 20 04 20
|
|
00FEA0 1
|
|
00FEA0 1 MusicSequenceData_FEA0: ; $FEA0
|
|
00FEA0 1 20 81 20 86 .byte $20,$81,$20,$86,$20,$10,$12,$10
|
|
00FEA4 1 20 10 12 10
|
|
00FEA8 1 12 02 10 12 .byte $12,$02,$10,$12,$02,$10,$12,$10
|
|
00FEAC 1 02 10 12 10
|
|
00FEB0 1 12 02 10 12 .byte $12,$02,$10,$12,$02,$10,$12,$10
|
|
00FEB4 1 02 10 12 10
|
|
00FEB8 1 12 02 06 0A .byte $12,$02,$06,$0A,$0C,$C6,$00,$58
|
|
00FEBC 1 0C C6 00 58
|
|
00FEC0 1
|
|
00FEC0 1 MusicSequenceData_FEC0: ; $FEC0
|
|
00FEC0 1 04 18 B8 58 .byte $04,$18,$B8,$58,$04,$18,$B8,$58
|
|
00FEC4 1 04 18 B8 58
|
|
00FEC8 1 1C 1E 20 26 .byte $1C,$1E,$20,$26,$2A,$26,$C6,$80
|
|
00FECC 1 2A 26 C6 80
|
|
00FED0 1 3C 18 18 18 .byte $3C,$18,$18,$18,$3C,$3C,$3C,$18
|
|
00FED4 1 3C 3C 3C 18
|
|
00FED8 1 3C 18 18 18 .byte $3C,$18,$18,$18,$3C,$3C,$3C,$18
|
|
00FEDC 1 3C 3C 3C 18
|
|
00FEE0 1
|
|
00FEE0 1 MusicSequenceData_FEE0: ; $FEE0
|
|
00FEE0 1 18 3C 3A 38 .byte $18,$3C,$3A,$38,$36,$38,$3A,$3C
|
|
00FEE4 1 36 38 3A 3C
|
|
00FEE8 1 83 1C 98 21 .byte $83,$1C,$98,$21,$E3,$67,$26,$26
|
|
00FEEC 1 E3 67 26 26
|
|
00FEF0 1 6A 6E 6A 6E .byte $6A,$6E,$6A,$6E,$C6,$00,$98,$B8
|
|
00FEF4 1 C6 00 98 B8
|
|
00FEF8 1 58 78 78 78 .byte $58,$78,$78,$78,$58,$60,$58,$60
|
|
00FEFC 1 58 60 58 60
|
|
00FF00 1
|
|
00FF00 1 MusicSequenceData_FF00: ; $FF00
|
|
00FF00 1 A6 F8 58 18 .byte $A6,$F8,$58,$18,$18,$60,$20,$20
|
|
00FF04 1 18 60 20 20
|
|
00FF08 1 66 26 26 6C .byte $66,$26,$26,$6C,$2C,$2C,$C6,$00
|
|
00FF0C 1 2C 2C C6 00
|
|
00FF10 1 58 18 18 78 .byte $58,$18,$18,$78,$38,$38,$58,$18
|
|
00FF14 1 38 38 58 18
|
|
00FF18 1 18 78 38 38 .byte $18,$78,$38,$38,$58,$18,$18,$98
|
|
00FF1C 1 58 18 18 98
|
|
00FF20 1
|
|
00FF20 1 MusicSequenceData_FF20: ; $FF20
|
|
00FF20 1 C7 2F C7 0D .byte $C7,$2F,$C7,$0D,$CF,$13,$CF,$8C
|
|
00FF24 1 CF 13 CF 8C
|
|
00FF28 1 88 C6 C4 00 .byte $88,$C6,$C4,$00,$87,$2A,$84,$26
|
|
00FF2C 1 87 2A 84 26
|
|
00FF30 1 87 22 18 38 .byte $87,$22,$18,$38,$34,$18,$38,$34
|
|
00FF34 1 34 18 38 34
|
|
00FF38 1 3C 38 32 3C .byte $3C,$38,$32,$3C,$38,$32,$84,$18
|
|
00FF3C 1 38 32 84 18
|
|
00FF40 1
|
|
00FF40 1 MusicSequenceData_FF40: ; $FF40
|
|
00FF40 1 87 38 38 3A .byte $87,$38,$38,$3A,$3C,$82,$18,$18
|
|
00FF44 1 3C 82 18 18
|
|
00FF48 1 C5 84 98 B8 .byte $C5,$84,$98,$B8,$A6,$9C,$D8,$98
|
|
00FF4C 1 A6 9C D8 98
|
|
00FF50 1 98 6B E9 67 .byte $98,$6B,$E9,$67,$E5,$2B,$E7,$25
|
|
00FF54 1 E5 2B E7 25
|
|
00FF58 1 E1 DD 85 DB .byte $E1,$DD,$85,$DB,$1D,$DF,$A0,$86
|
|
00FF5C 1 1D DF A0 86
|
|
00FF60 1
|
|
00FF60 1 MusicSequenceData_FF60: ; $FF60
|
|
00FF60 1 AE AA 2F E7 .byte $AE,$AA,$2F,$E7,$3D,$E1,$DD,$85
|
|
00FF64 1 3D E1 DD 85
|
|
00FF68 1 FD 19 DD 60 .byte $FD,$19,$DD,$60,$44,$A0,$64,$44
|
|
00FF6C 1 44 A0 64 44
|
|
00FF70 1 A4 E7 85 DD .byte $A4,$E7,$85,$DD,$1B,$DD,$66,$44
|
|
00FF74 1 1B DD 66 44
|
|
00FF78 1 66 44 00 85 .byte $66,$44,$00,$85,$44,$87,$42,$85
|
|
00FF7C 1 44 87 42 85
|
|
00FF80 1
|
|
00FF80 1 MusicSequenceData_FF80: ; $FF80
|
|
00FF80 1 40 87 3E 84 .byte $40,$87,$3E,$84,$02,$87,$16,$84
|
|
00FF84 1 02 87 16 84
|
|
00FF88 1 14 87 12 87 .byte $14,$87,$12,$87,$10,$85,$04,$87
|
|
00FF8C 1 10 85 04 87
|
|
00FF90 1 04 12 02 84 .byte $04,$12,$02,$84,$40,$87,$12,$12
|
|
00FF94 1 40 87 12 12
|
|
00FF98 1 40 12 84 02 .byte $40,$12,$84,$02,$86,$0C,$04,$08
|
|
00FF9C 1 86 0C 04 08
|
|
00FFA0 1
|
|
00FFA0 1 MusicSequenceData_FFA0: ; $FFA0
|
|
00FFA0 1 16 84 3E 87 .byte $16,$84,$3E,$87,$12,$12,$16,$12
|
|
00FFA4 1 12 12 16 12
|
|
00FFA8 1 84 14 87 16 .byte $84,$14,$87,$16,$81,$02,$04,$82
|
|
00FFAC 1 81 02 04 82
|
|
00FFB0 1 02 81 3E 04 .byte $02,$81,$3E,$04,$82,$02,$87,$16
|
|
00FFB4 1 82 02 87 16
|
|
00FFB8 1 85 04 81 2E .byte $85,$04,$81,$2E,$04,$2E,$04,$09
|
|
00FFBC 1 04 2E 04 09
|
|
00FFC0 1
|
|
00FFC0 1 MusicSequenceData_FFC0: ; $FFC0
|
|
00FFC0 1 DD 9C 2B FB .byte $DD,$9C,$2B,$FB,$BA,$9C,$BA,$DC
|
|
00FFC4 1 BA 9C BA DC
|
|
00FFC8 1 98 A6 86 98 .byte $98,$A6,$86,$98,$A6,$9C,$A6,$88
|
|
00FFCC 1 A6 9C A6 88
|
|
00FFD0 1
|
|
00FFD0 1 ; ============================================================================
|
|
00FFD0 1 ; $FFD0-$FFE9
|
|
00FFD0 1 ; Final music/audio sequence data.
|
|
00FFD0 1 ; ============================================================================
|
|
00FFD0 1
|
|
00FFD0 1 MusicSequenceData_FFD0: ; $FFD0
|
|
00FFD0 1 07 D9 86 09 .byte $07,$D9,$86,$09,$DD,$88,$E6,$A6
|
|
00FFD4 1 DD 88 E6 A6
|
|
00FFD8 1 B8 02 12 02 .byte $B8,$02,$12,$02,$12,$02,$12,$02
|
|
00FFDC 1 12 02 12 02
|
|
00FFE0 1 52 00 .byte $52,$00
|
|
00FFE2 1
|
|
00FFE2 1 ; ============================================================================
|
|
00FFE2 1 ; $FFE2-$FFF9
|
|
00FFE2 1 ; Unused/padding bytes.
|
|
00FFE2 1 ;
|
|
00FFE2 1 ; The first two bytes, $52,$00, complete the audio data above. The remaining
|
|
00FFE2 1 ; bytes through $FFF9 are $FF padding.
|
|
00FFE2 1 ; ============================================================================
|
|
00FFE2 1
|
|
00FFE2 1 UnusedRomPadding: ; $FFE2
|
|
00FFE2 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
|
00FFE6 1 FF FF FF FF
|
|
00FFEA 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
|
00FFEE 1 FF FF FF FF
|
|
00FFF2 1 FF FF FF FF .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
|
00FFF6 1 FF FF FF FF
|
|
00FFFA 1
|
|
00FFFA 1 ; ============================================================================
|
|
00FFFA 1 ; $FFFA-$FFFF
|
|
00FFFA 1 ; 6502 interrupt vectors.
|
|
00FFFA 1 ;
|
|
00FFFA 1 ; Each vector is stored little-endian:
|
|
00FFFA 1 ;
|
|
00FFFA 1 ; NMI: $C046
|
|
00FFFA 1 ; RESET: $C40B
|
|
00FFFA 1 ; IRQ: $C43E
|
|
00FFFA 1 ; ============================================================================
|
|
00FFFA 1
|
|
00FFFA 1 InterruptVectors: ; $FFFA
|
|
00FFFA 1
|
|
00FFFA 1 NmiVectorWord: ; $FFFA
|
|
00FFFA 1 46 C0 .word $C046 ; $FFFA: 46 C0
|
|
00FFFC 1
|
|
00FFFC 1 ResetVectorWord: ; $FFFC
|
|
00FFFC 1 0B C4 .word $C40B ; $FFFC: 0B C4
|
|
00FFFE 1
|
|
00FFFE 1 IrqBrkVectorWord: ; $FFFE
|
|
00FFFE 1 3E C4 .word $C43E ; $FFFE: 3E C4
|
|
010000 1
|
|
010000 1 ; ============================================================================
|
|
010000 1 ; End of 16 KB PRG-ROM.
|
|
010000 1 ;
|
|
010000 1 ; CPU range completed: $C000-$FFFF
|
|
010000 1 ; ROM range completed: $0000-$3FFF
|
|
010000 1 ; ============================================================================
|
|
010000 1
|