Zanac (NES)/ROM map

From Data Crystal
< Zanac (NES)
Revision as of 06:39, 11 June 2019 by ManxomeBromide (talk | contribs) (Initial draft based on discoveries made during sprite-ripping)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Zanac uses the UNROM PCB with 8 banks. To convert ROM offsets into addresses, subtract 0x10 (16 decimal) and then divide by 0x4000. This will give you the bank number from 0-7, with the remainder (a value from 0x0000 to 0x3FFF) as the offset into that bank. To turn that offset into a pointer in RAM, add 0xC000 to it if it is in bank 7 and 0x8000 to it otherwise.

Banks 0-3

The lower four banks are completely empty. Zanac is a 64KB game with a 128KB ROM chip.

Bank 4

Bank 4 (ROM offsets 10010-1400F) hold most of the pattern data for the entire game in a run-length-encoded format. A table of two-byte pointers at 10040-1004D points to seven tables of pattern data:

  • 0: All sprite data except for the 8 sprites reserved for the "status box": 8x16 sprites, loaded into PPU RAM at 0000-0F7F.
  • 1: Alternate graphics for the player's ship, accessible with a cheat code (hold A and B while pressing start).
  • 2: Title screen tiles, including two fonts and the title logo.
  • 3: Ground features and enemy bases common to all levels. Loaded into PPU RAM at 17F0-1FFF.
  • 4: Rocky maps.
  • 5: Techno and Bio maps.
  • 6: Other Techno maps.

The RLE-encoded data has the following format:

  • The first two bytes are control codes that appear nowhere in the actual data. The second controls features of the decompressor that are not used by Bank 4 data and may be ignored; the second will be called "the control code."
  • In uncompressed mode (where decoding starts), bytes are simply copied to the output until the control code is encountered.
  • In compressed mode, bytes are read two at a time, with the first byte being the byte to copy and the second being the number of times to copy it. This continues until the control code is reached.
  • The control code toggles between compressed and uncompressed mode.
  • Two copies of the control code back to back end the data block.

Bank 5

To be discovered. Has an obvious pointer table 48 bytes in, just like bank 4, but the data seems to be encoded differently.

Bank 6

Supplementary code and data. 18010-18039 hold some kind of vector table, as if there is a set of routines that are being "exported" from the ROM bank in a portable or switchable way.

A table at 189C1-189DC holds the remainder of the sprite pattern data. Each valid entry in this table describes 128 bytes of data to fill the tiles at PPU offsets 0F80-0FFF, and is generally a transient part of the UI:

  • 0: Illegal data, never used
  • 1: AREA
  • 2: TIME
  • 3: GAME OVER
  • 4: BONUS
  • 5: PONY INC logo
  • 6: Empty sprite

The routine that does the copy here checks for any value between 06 and FF and will set all such values to 6. 0 does not seem to have this protection.

The graphics data is encoded in the same manner as the data in bank 4. The table, however, has four bytes per entry instead of two. The meaning of the remaining two bytes in each entry is presently unknown.

Bank 7

Core code section, including the main loop and all reset and interrupt vectors.

  • 1C010-1C0A2 holds a table of "exported functions" much like bank 6.
  • 1C108-1C10F are the memory locations used by the bankswitching logic to prevent UNROM bus conflicts and should not be touched.
  • 2000A-2000F are the master interrupt vectors for the program as a whole.