Promotes Lunar Pool
This commit is contained in:
1 parent
837007843d
commit
62866563ba
53 files changed
+115746
-4100
No files matched your search
@@ -0,0 +1,152 @@
|
||||
# Pass 1 compressed and packed-data parser audit
|
||||
|
||||
## Summary
|
||||
|
||||
Four distinct packed-data consumers are confirmed. Only one is a general
|
||||
run-length decoder. The others are pointer-selected sprite/object lists or
|
||||
cell-code interpreters.
|
||||
|
||||
## 1. `$CBEA`: pointer-selected OAM sprite-list parser
|
||||
|
||||
Inputs:
|
||||
|
||||
- `$15` selects a sprite-list variant.
|
||||
- `$16 == 4` selects the pointer tables at `$CC3E/$CC44`; other values select
|
||||
`$CC24/$CC31`.
|
||||
- `$33` is added to the generated OAM X coordinate.
|
||||
- X is the destination OAM-shadow offset.
|
||||
|
||||
Format:
|
||||
|
||||
- One source byte per sprite.
|
||||
- `$FF` terminates the list early.
|
||||
- A hard limit of `$15` (21) source entries prevents runaway parsing.
|
||||
- The source byte is both the CHR tile index and the index into coordinate
|
||||
tables `$CC4A` and `$CC5F`.
|
||||
|
||||
Output record at `$0200,X`:
|
||||
|
||||
- byte 0: `$88 + table_CC5F[tile]` (Y)
|
||||
- byte 1: source byte (tile)
|
||||
- byte 2: `$00` (attributes)
|
||||
- byte 3: `$33 + table_CC4A[tile]` (X)
|
||||
|
||||
This is a compact sprite-layout parser, not RLE compression.
|
||||
|
||||
## 2. `$DD78-$DE39`: primary course-map RLE decoder
|
||||
|
||||
Pointer selection:
|
||||
|
||||
- `$2B` is the zero-based hole index.
|
||||
- `$E6C3,Y` and `$E6D5,Y` form the source pointer in `$04/$05`.
|
||||
- Destination begins at `$0300` through `$06/$07`.
|
||||
|
||||
Header:
|
||||
|
||||
- First three source bytes are copied to `$19-$1B`.
|
||||
- Source pointer then advances by three bytes.
|
||||
|
||||
Commands:
|
||||
|
||||
- `$FF`: end primary stream.
|
||||
- `$00-$0F`: emit header byte 0, `(low_nibble + 1)` times.
|
||||
- `$10-$1F`: emit header byte 1, `(low_nibble + 1)` times.
|
||||
- `$20-$2F`: emit header byte 2, `(low_nibble + 1)` times.
|
||||
- `$A0-$AF`: emit `(low_nibble + 1)` values cycling through `$AB-$AD` using
|
||||
state byte `$8D`.
|
||||
- `$30-$9F` and `$B0-$FE`: emit the command byte literally.
|
||||
|
||||
Output is divided into 16-byte units. After each unit, `$04/$05` advances by
|
||||
`$1C` consumed source bytes and `$06/$07` advances by `$10` destination bytes.
|
||||
|
||||
### Hole 2 / Hole 3 length correction
|
||||
|
||||
The decoder does not enforce a 480-byte limit. RAM `$0300-$04FF` is cleared
|
||||
before decoding, providing a 512-byte destination area. Therefore the measured
|
||||
outputs are valid:
|
||||
|
||||
- Hole 2: 482 bytes
|
||||
- Hole 3: 483 bytes
|
||||
- Other currently measured streams: 480 bytes
|
||||
|
||||
The earlier 480-byte expectation came from the common case of 30 16-byte
|
||||
units, not from a decoder bound. Both longer streams remain within the 512-byte
|
||||
course buffer and do not indicate malformed pointers or an incorrect opcode
|
||||
model.
|
||||
|
||||
## 3. `$DE3B-$DE5D`: optional auxiliary block parser
|
||||
|
||||
After the primary `$FF`, the decoder advances the source pointer past the
|
||||
primary stream and examines the next byte.
|
||||
|
||||
- `$55` is a sentinel meaning the optional block is absent.
|
||||
- Otherwise, records are copied in four-byte groups from the source into
|
||||
`$0104+`.
|
||||
- X begins at `$04` and increases by four per record.
|
||||
- After each group, `$D4F2` advances the corresponding destination/object
|
||||
bookkeeping.
|
||||
- Parsing ends when X reaches `$44`, allowing at most 16 four-byte groups.
|
||||
- `$04/$05` is then advanced by the number of consumed source bytes.
|
||||
|
||||
This is a bounded fixed-record block, not a terminator-scanned RLE stream.
|
||||
|
||||
## 4. `$DE5E-$DF52`: per-hole OAM/object package parser
|
||||
|
||||
The parser begins at the source position following the optional auxiliary
|
||||
block.
|
||||
|
||||
### Fixed setup record
|
||||
|
||||
The first bytes initialize OAM-shadow entries beginning at `$0298` and setup
|
||||
fields `$65-$66`, `$57`, `$1A-$1B`. Tables at `$E37D-$E3DE` expand one compact
|
||||
source selector into multiple sprite records.
|
||||
|
||||
### Variable object list
|
||||
|
||||
At `$DF03`, each object record begins with:
|
||||
|
||||
- byte 0: object/shape selector, or `$FF` terminator
|
||||
- byte 1: X/base-position adjustment
|
||||
- byte 2: Y/base-position adjustment
|
||||
|
||||
The selector indexes span tables at `$E283/$E284`, then source tables at
|
||||
`$E2EB`, `$E2A2`, and `$E334`. One compact three-byte object record expands to
|
||||
one or more four-byte OAM entries.
|
||||
|
||||
- `$FF` terminates the variable object list.
|
||||
- Values at or above table position `$2B` select OAM attribute `$42`; lower
|
||||
positions select `$02` through the intentional overlapping-instruction idiom
|
||||
at `$DF3A/$DF3B`.
|
||||
- The parser resumes at the next source record using `$1C` as the consumed-byte
|
||||
offset.
|
||||
|
||||
This is a table-expanded object/sprite list, not a byte-run compressor.
|
||||
|
||||
## 5. `$D72D-$D7FF`: course-cell code interpreter
|
||||
|
||||
This routine reads one byte through `($19),Y` from the generated course map. It
|
||||
is not a stream decompressor. It interprets cell codes for collision or terrain
|
||||
response:
|
||||
|
||||
- `$EF` and `$FD` are special sentinels.
|
||||
- Other values index the property table at `$D80D`.
|
||||
- Property values `$10`, `$20`, `$40`, and `$FF` select distinct collision or
|
||||
response paths.
|
||||
- Fine X/Y bits are converted into a bit mask and tested against the selected
|
||||
property byte.
|
||||
|
||||
The `$FF` comparison at `$D74D` belongs to this cell-property dispatch and must
|
||||
not be mistaken for a compressed-stream terminator.
|
||||
|
||||
## Parser-boundary conclusions
|
||||
|
||||
- `$CBEA` sprite layouts are bounded by `$FF` or 21 entries.
|
||||
- Primary hole streams are bounded by their first `$FF` and decode into a
|
||||
512-byte RAM area, not a fixed 480-byte area.
|
||||
- Optional auxiliary blocks are bounded by `$55` or 16 four-byte groups.
|
||||
- Per-hole object lists are bounded by a secondary `$FF` and expand through
|
||||
fixed lookup tables.
|
||||
- `$D72D` is a map-cell interpreter, not another compressed-data parser.
|
||||
|
||||
No remaining `$FF` comparison in reachable code has been found that represents
|
||||
an unclassified compressed-stream parser.
|
||||
Reference in new issue
Block a user