Welcome to Data Crystal's new home! Data Crystal is now part of the TCRF family (sort of).
The wiki has recently moved; please report any issues in Discord. Pardon the dust.

Pipe Dream (NES)/RAM map

From Data Crystal
Jump to navigation Jump to search

Chip tiny.png The following article is a RAM map for Pipe Dream (NES).

Conventions: unless otherwise specified:

  • all multi-byte integers are little-endian
  • addresses are hex
  • sizes are decimal
  • x coordinates are 0..9
  • y coordinates are 0..7. 0 represents the top row.


Address     Size    Description
-------     ----    -----------
  0a          1     Read index for background queue (see description at address 0200)
  0b          1     Write index for background queue (see description at address 0200)
  0e          1     Input from player 1's controller
  0f          1     Input from player 2's controller
  67          3     Bonus score
  6a          3     One component of bonus score
  79         10     Data related to current pipe drop(s) in progress
                    Player 1    Player 2
                       79          7a       ?
                       7b          7c       ?
                       7d          7e       ?
                       7f          80       x coordinate
                       81          82       y coordinate
  8b          1     Current player. 0 = player 1, 1 = player 2. (Note that both players play at the same time, so this changes frequently and interleaves which player's actions are being calculated.)
  8c          4     x,y coordinates in sprite coordinate system
                    Player 1    Player 2
                       8c          8d     x coordinate. Value = 65 + 16 * (x coordinate in 0..9 representation)
                       8e          8f     y coordinate. Value = 76 + 16 * (y coordinate in 0..7 representation)
  92          1     High score index (0..4) - for example, if you get the number 4 highest score for your game (A, B, or C), this would be 3 (=4-1).
  98          3     Score
  a0          1     Current pipe for player 1
  a1          1     Current pipe for player 2
  a6          2     Commonly used temp variable for background address in PPU memory. Typically $2000 + something. May have high bit set (which is stripped off before using it as address). See address 0200 for more info.
  a8          4     x,y coordinates
                    Player 1    Player 2
                       a8          a9       y coordinate
                       aa          ab       x coordinate
  b7          1     Current flooz direction, when flooz is flowing. Up = 1, Down = 2, Left = 4, Right = 8
  b8          2     Position of flooz, when flowing. (b8 = y, b9 = x)
  d9          1     Time required for flooz to fill the current square (unknown units). 8 for most pipes, 20 for reservoirs.
  fa          1     Active. Set to 0xff (active) when level starts and to 0 (inactive) when flooz is done flowing and system is still calculating score and waiting for button.
0200        256     Background message queue. Code that changes the background queues up messages here and they're dispatched during vblank.
                    Message format is:
                         PPU address (big endian, 2 bytes), with flags in 0x80 and 0x40 positions of high byte
                             0x40 bit controls direction for increments: 0 = horizontal, 1 = vertical
                    If high bit is set (0x80)
                         ROM pointer (2 bytes)
                         Length (1 byte)
                    Otherwise
                         Length      (1 byte)
                         Data        (Length bytes)
                    The code keeps a running index of where to put the next byte (stored at 0b). During vblank, these are read using the index at 0a, then 0b and 0a are reset to 0.
0441          1     Number of wrenches/lives
0442          1     Number of players
0444          1     Level (1-16)
0445          1     Sublevel (1-4)
0447          1     Remaining distance of pipe to be filled. Displays as "Dist" in the game.
044b          2     Position of flooz source (044b = x, 044c = y)
0450          1     Level/Sublevel encoded in a single byte for high score format: ((Level - 1) << 4) | (Sublevel - 1)
0451          1     Game type. 0 = "A", 1 = "B", 2 = "C"
0453          3     Initials for high score
048c          6     Scores. (048c, 048e, 0490) = Player 1 score; (048d, 048f, 0491) = Player 2 score.
0495        105     High score table. 3 arrays of 5 slots of 7 bytes:
                       Initials (3 bytes)
                       Level/sublevel (1 byte) see 0450 for encoding
                       Score (3 bytes)
052e          5     Player 1 upcoming pipes. 052e is bottom pipe, 0532 is top pipe.
0533          5     Player 2 upcoming pipes. Analogous order.
055a          1     Current flooz pipe connection. Upper nibble = input, Lower nibble = output. See b7 for directions within each nibble.
0560         80     Board. Array of 10 x 8 of pipe. Each byte may be ORed with 0x80 if flooz flows through it or 0x40 if flooz flows through both horizontally and vertically.
0650         10     Bits showing if player 2 filled the given board spot. Each byte represents one x position, and the bits represent the y position (1 << y represents row y). Bit value = 1 for player 2.
065a         10     Tunnels. 
                    Position 065a + x has 0xF0 bits set if there's a vertical tunnel at position x.
                    Position 065a + y has 0x0F bits set if there's a horizontal tunnel at position y.
0665         25     Array[5][5] of bytes that tells whether the given position is occupied. 
                    Each byte corresponds to 2 rows and two columns worth of cells.
                    Upper row = lower nibble, lower row = upper nibble.
                    0x01 represents left cell occupied, 0x04 represents right cell occupied.
                    First row of array has 0x0F set. Last row has 0xF0 set.
067e         25     Buffer of tile values to be set in the background message queue at 0200 (used in various print routines)
0697         16     Character buffer used to print things to string, which are then converted to tiles (067e) and stored in the background.
0700        256     Sprite page, transferred via DMA during vblank. This game makes relatively little use of sprites, so most y positions are 0xF0, i.e., off screen.

Pipes and specials are represented by the following (hex) values:

Value    Description
-----    -----------
01       Up/Down/Left/Right pipe
02       Left/Right pipe
03       Up/Down pipe
04       Up/Left pipe
05       Up/Right pipe
06       Down/Right pipe
07       Down/Left pipe
08       One-way Right pipe
09       One-way Left pipe
0a       One-way Down pipe
0b       One-way Up pipe
0c       Up source
0d       Left source
0e       Right source
0f       Down source
10       <unused>
11       <unused>
12       Up/Down reservoir
13       Left/Right reservoir
14       Up/Down pump
15       Left/Right pump
16       Up sink
17       Left sink
18       Right sink
19       Down sink

Additionally, the 80 bit is set when the pipe is filled with flooz, and the 40 bit is set when an Up/Down/Left/Right pipe is filled in both horizontal and vertical directions.