Sonic the Hedgehog 2 (Master System)
From Sonic Retro
(Original content by Hivebrain)
Contents
ROM Contents
Offset | Description |
---|---|
A4C-DEA | Level select text (plain ASCII format) |
E1C-E4B | Level select level pointers |
28F0 | Pointers for title card mappings (16-bit, little endian) |
2904-2FA7 | Mappings for title cards & act results screens |
55E5 | Pointers for level headers (16-bit, little endian) |
5635-585A | Level headers |
10000 | Uncompressed art - Sonic |
13800 | Compressed Art - bubble (ALZ) |
13930 | Compressed Art - jumping pig enemy (GMZ) |
13BD0 | Compressed Art - small yellow numbers (unused) |
13CF8 | Compressed Art - spinning turtle enemy (SHZ/SEZ/CEZ) |
14000 | Uncompressed art - Sonic gliding (SHZ) |
15E00 | Uncompressed art - Sonic riding a minecart (UGZ/GMZ) |
18000 | Uncompressed art - Sonic runnning round a loop (ALZ/GHZ) |
1BC00 | Compressed Art - spinning wheel (CEZ) |
1BE60 | Compressed Art - block (CEZ) |
1C000 | Compressed Art - numbers, lives icon |
1C2CA | Compressed Art - collected ring sparkles |
1C306 | Compressed Art - invincibility sparkles |
1C332 | Compressed Art - explosion |
1C462 | Compressed Art - monitor (generic) |
1C608 | Uncompressed art - monitors (specific) |
1CCC8 | Compressed Art - rings (dropped when Sonic gets hit) |
1CE98 | Compressed Art - moving platform (GHZ) |
1CF92 | Compressed Art - glider (SHZ) |
1D20E | Uncompressed art - prison capsule |
1DACE | Uncompressed art - animals |
1E0CE | Compressed Art - cloud & tree from scrolling text on title cards |
1E124 | Uncompressed art - end of act signpost |
1EDA4 | Compressed Art - minecart (UGZ/GMZ) |
1EE48 | Uncompressed art - minecart wheel (UGZ/GMZ) |
1EEC8 | Compressed Art - minecart wheel (UGZ/GMZ) |
1F040 | Compressed Art - broken minecart (UGZ/GMZ) |
1F0EA | Uncompressed art - Silver Sonic (SEZ) |
1F96A | Compressed Art - log (SHZ) |
1F9B4 | Compressed Art - moving platform (SHZ) |
1FAB4 | Empty |
20000 | Compressed Art - circle & floor from intro sequence |
206A0 | Compressed Art - beta title screen (unused) |
213B0 | 32x32 mappings - intro sequence |
216E0 | 32x32 mappings - title screen |
21A32 | Level layout - intro sequence (uncompressed) |
21AB2 | Level layout - title screen (uncompressed) |
21B32 | Uncompressed art - mini Sonic from intro sequence |
22832 | Compressed Art - scenery from intro sequence |
229A2 | Compressed Art - Sonic's hand from title screen |
22C32 | Compressed Art - Tails' face from title screen |
22DA2 | Mappings for title screen |
2307C | Unknown |
23C72 | Empty |
24000 | Code |
2411F | Palette - unknown (4 shades of grey) |
2412F | Palette - unknown |
2413F | Palette - unknown |
2414F | Palette - title cards |
2415F | Palette - Sonic (GHZ) |
2416F | Palette - Sonic (SHZ1/3) |
2417F | Palette - Sonic (SHZ2) |
2418F | Palette - Sonic (ALZ1/3) |
2419F | Palette - Sonic (ALZ2) |
241AF | Palette - Sonic (UGZ) |
241BF | Palette - Sonic (GMZ) |
241CF | Palette - Sonic (SEZ) |
241DF | Palette - Sonic (CEZ1/2) |
241EF | Palette - Sonic (CEZ3) |
241FF | Palette - UGZ |
2420F | Palette - SHZ1/3 |
2421F | Palette - SHZ2 |
2422F | Palette - ALZ1/3 |
2423F | Palette - ALZ2 |
2424F | Palette - GHZ |
2425F | Palette - GMZ |
2426F | Palette - SEZ |
2427F | Palette - CEZ1/2 |
2428F | Palette - CEZ3 |
2429F | Palette - intro sequence |
242AF | Palette - title screen |
242BF | Palette - intro sequence |
242CF | Palette - title screen |
242DF | Palette - unknown |
242EF | Palettes (7) - title cards (UGZ, SHZ, ALZ, GHZ, GMZ, SEZ, CEZ) |
2435F | Palette - unknown |
2436F | Palette - Sonic (ending) |
2437F | Palette - unknown |
2438F | Palettes (8) - ending (gradually changes from day to night) |
2440F | Palette - blank |
2441F | Loop XY motion data (ALZ/GHZ) |
24D1E | Compressed Art - level select text |
2511E | Compressed Art - text from title cards |
260A4 | Compressed Art - UGZ level tiles |
270DC | Compressed Art - yellow bird (SHZ) |
2715C | Compressed Art - spears (ALZ) |
2724E | Compressed Art - moving platform (GMZ) |
2724E | Compressed Art - moving platform (SEZ) |
273E8 | Compressed Art - newtron (UGZ/SHZ/GHZ) |
27654 | Compressed Art - bomb enemy (GMZ/SEZ) |
27782 | Compressed Art - moving platform (UGZ) |
27870 | Compressed Art - crab (UGZ/ALZ/GHZ/SEZ/CEZ) |
27B90 | Compressed Art - splash (ALZ) |
27BE0 | Compressed Art - water (ALZ) |
27C10 | Compressed Art - falling spike (UGZ) |
27CB0 | Compressed Art - falling spike (GMZ) |
27D50 | Compressed Art - bubble (ALZ) |
27E51 | Empty |
28000 | Compressed Art - SHZ1/3 level tiles |
291DC | Compressed Art - SHZ2 level tiles |
2A2AC | Compressed Art - GMZ level tiles |
2B2E2 | Compressed Art - text from ending sequence |
2B812 | Empty |
2C000 | 32x32 mappings - SHZ1/3 |
2D8C0 | 32x32 mappings - SHZ2 |
2F080 | Level layout - CEZ1 (compressed) |
2FA48 | Empty |
30000 | 32x32 mappings - GHZ |
316C0 | 32x32 mappings - ALZ |
32F80 | Level layout - SHZ3 (compressed) |
33716 | Level layout - GMZ3 (compressed) |
34000 | Level layout - GHZ1 (compressed) |
34C6B | Level layout - GHZ2 (compressed) |
35884 | Level layout - GHZ3 (compressed) |
36429 | Level layout - SHZ1 (compressed) |
370D8 | Level layout - SHZ2 (compressed) |
38000 | Level layout - ALZ1 (compressed) |
38F68 | Level layout - ALZ2 (compressed) |
39DFF | Level layout - ALZ3 (compressed) |
3ADBB | Level layout - UGZ1 (compressed) |
3C000 | 32x32 mappings - ALZ2 |
3DD80 | 32x32 mappings - UGZ |
3F380 | Compressed Art - "Game Over" text |
3F75A | Compressed Art - numbers 0 to 9 in scrolling GHZ style |
3FB7E | Mappings for Game Over screen |
3FC5E | Empty |
40000 | Uncompressed art - Sonic (mirrored) |
43680 | Compressed Art - little wavy lines (?) |
436C0 | Compressed Art - fireball (UGZ) |
43722 | Compressed Art - mini flame (UGZ) |
43740 | Compressed Art - lobster enemy (ALZ) |
439A0 | Compressed Art - burrobot (GMZ) |
43C82 | Compressed Art - moto bug (UGZ/GHZ) |
43E28 | Compressed Art - fish enemy (CEZ) |
43EDA | Empty |
44000 | Uncompressed art - Sonic gliding (mirrored) |
45E00 | Uncompressed art - Sonic riding a minecart (mirrored) |
48000 | Uncompressed art - Sonic running round a loop (mirrored) |
4BC00 | Compressed Art - block (SEZ) |
4BC80 | Compressed Art - moving platform (CEZ) |
4BD46 | Compressed Art - levitating spiked rock (CEZ) |
4C000 | Level layout - GMZ1 (compressed) |
4CC68 | Level layout - GMZ2 (compressed) |
4DA91 | Level layout - SEZ1 (compressed) |
4E9C9 | Level layout - SEZ2 (compressed) |
4F76E | Compressed Art - Tails & Eggman from intro sequence |
4FC2A | Empty |
50000 | Compressed Art - SEZ1/3 level tiles |
5102A | Compressed Art - SEZ2 level tiles |
52102 | Uncompressed art - UGZ boss |
52E42 | Compressed Art - "END" from ending sequence |
53002 | Compressed Art - Tails running in ending sequence |
53850 | Compressed Art - Tails looking up in ending sequence |
53960 | Uncompressed art - chaos emeralds |
54000 | Compressed Art - ALZ1/3 level tiles |
550F0 | Compressed Art - ALZ2 level tiles |
56116 | Compressed Art - CEZ1/2 level tiles |
56E7E | Compressed Art - CEZ3 level tiles |
58000 | 32x32 mappings - GMZ |
59960 | 32x32 mappings - SEZ1/3 |
5AF20 | 32x32 mappings - ending sequence / original GHZ |
5B900 | Empty |
5C000 | 32x32 mappings - SEZ2 |
5D760 | 32x32 mappings - CEZ3 |
5E000 | Compressed Art - GHZ level tiles |
5F11B | Level layout - UGZ2 (compressed) |
60000 | 32x32 mappings - CEZ1/2 |
61600 | Compressed Art - title screen |
6299A | Compressed Art - Eggman final boss (CEZ3) |
6339C | Compressed Art - cloud (CEZ3) |
633CC | Empty |
64000 | Compressed Art - UGZ title card pic |
649A0 | Compressed Art - SHZ title card pic |
65410 | Compressed Art - ALZ title card pic |
65DC0 | Compressed Art - GHZ title card pic |
66446 | Compressed Art - GMZ title card pic |
66C26 | Compressed Art - SEZ title card pic |
670A6 | Compressed Art - CEZ title card pic |
67806 | Mappings for title card pics |
67F06 | Empty |
68000 | Uncompressed art - GMZ boss |
68980 | Uncompressed art - SHZ boss |
69740 | Uncompressed art - ALZ boss |
6A0C0 | Uncompressed art - GHZ boss |
6B340 | Compressed Art - rock (SHZ) |
6B460 | Compressed Art - fragment of a smashed block (all zones) |
6B4EA | Uncompressed art - Tails (CEZ3) |
6C000 | Level layout - UGZ3 (compressed) |
6C6D3 | Level layout - SEZ3 (compressed) |
6D1F5 | Level layout - CEZ2 (compressed) |
6DE81 | Level layout - CEZ3 (compressed) |
6DFD7 | Level layout - good ending sequence (compressed) |
6E151 | Level layout - bad ending sequence (compressed) |
6E2C2 | Compressed Art - original GHZ level tiles from ending sequence |
6F719 | Empty |
70000 | Unknown |
75C00 | Uncompressed art - rings (UGZ) |
75F00 | Uncompressed art - rings (SHZ1/3) |
76200 | Uncompressed art - rings (SHZ2) |
76500 | Uncompressed art - rings (ALZ) |
76800 | Uncompressed art - rings (GHZ) |
76B00 | Uncompressed art - rings (GMZ) |
76E00 | Uncompressed art - rings (SEZ) |
77100 | Uncompressed art - rings (CEZ) |
77400 | Unknown |
77552 | Credits (plain ASCII format) |
77732 | Empty |
78000 | Unknown |
78135 | Pointers for sprite layouts (16-bit, little endian) |
78173 | Sprite layout - UGZ1 |
782C1 | Sprite layout - UGZ2 |
7840F | Sprite layout - UGZ3 |
7848E | Sprite layout - SHZ1 |
784E9 | Sprite layout - SHZ2 |
78568 | Sprite layout - SHZ3 |
78584 | Sprite layout - ALZ1 |
78666 | Sprite layout - ALZ2 |
787BD | Sprite layout - ALZ3 |
787F4 | Sprite layout - GHZ1 |
788C4 | Sprite layout - GHZ2 |
78970 | Sprite layout - GHZ3 |
78983 | Sprite layout - GMZ1 |
78A4A | Sprite layout - GMZ2 |
78AFF | Sprite layout - GMZ3 |
78B24 | Sprite layout - SEZ1 |
78BE2 | Sprite layout - SEZ2 |
78C7C | Sprite layout - SEZ3 |
78C8F | Sprite layout - CEZ1 |
78D20 | Sprite layout - CEZ2 |
78D8D | Sprite layout - CEZ3 |
78D97 | Unknown |
7AF41-7AF49 | Cycling palette - UGZ lava |
7AF4A-7AF52 | Cycling palette - SHZ2 rain |
7AF53-7AF5B | Cycling palette - ALZ water |
7AF5C-7AF64 | Cycling palette - GMZ wheels and conveyor belts |
7AF9F-7AFCE | Cycling palette - CEZ3 lightning |
Level headers
Each level header consists of 22 bytes:
AA BBBB CC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL
- AA = 32x32 mapping bank number
- BBBB = 32x32 mappings pointer
- CC = Level layout bank number
- DDDD = Level layout pointer
- EEEE = Level width in mapping blocks
- FFFF = 2's complement level width in blocks
- GGGG = Vertical offset into layout data. This is always 7 * EEEE.
- HHHH = Minimum camera x coordinate
- IIII = Minimum camera y coordinate
- JJJJ = Maximum camera x coordinate
- KKKK = Maximum camera y coordinate
- LLLL = Pointer to table of multiples of level width.
The EEEE and FFFF words are used by collision detection routines to move backwards and forwards in the level data array, whole rows at a time (e.g. for checking collisions above and below an object). The LLLL field is used to calculate the address of any given row of mappings in the level data array.
ROM addresses for the level headers:
Offset | Level |
---|---|
5635, 564B, 5661 | GHZ1/2/3 |
5677, 568D, 56A3 | SHZ1/2/3 |
56B9, 56CF, 56E5 | ALZ1/2/3 |
56FB, 5711, 5727 | UGZ1/2/3 |
573D, 5753, 5769 | GMZ1/2/3 |
577F, 5795, 57AB | SEZ1/2/3 |
57C1, 57D7, 57ED | CEZ1/2/3 |
5803 | Bad Ending |
5819 | Good Ending |
582F | Intro |
5845 | Title Screen |
Level select pointers
The pointers define which level the game goes to for each item on the level select. Each pointer consists of two bytes: one for the zone number, and one for the act number. The level numbers are as follows:
Value | Zone |
---|---|
00?? | Underground |
01?? | Sky High |
02?? | Aqua Lake |
03?? | Green Hills |
04?? | Gimmick Mt. |
05?? | Scrambled Egg |
06?? | Crystal Egg |
0700 | Bad Ending Sequence |
0701 | Good Ending Sequence |
0900 | Intro Sequence |
0901 | Title Screen |
The act numbers are just 00, 01 and 02. There are a total of 18 entries in the pointer array.
Title card mappings
The title cards are built up with rows of 8x8 tiles. Mappings define which tiles are pulled from the VRAM and displayed on the screen. Each 8x8 tile is given a 2-byte, little endian value based on where it appears in the VRAM:
So, the letter A would mapped like so:
0111 | 0211 |
0C11 | 0D11 |
Spaces not containing any letters are 7011. Here are the ROM addresses for each title card:
Offset | Level |
---|---|
2904 | GREEN HILLS |
298C | ZONE |
29C4 | AQUA LAKE |
2A34 | UNDERGROUND |
2AA4 | SKY HIGH |
2B14 | GIMMICK MT. |
2B84 | MOUNTAIN |
2BF4 | SCRAMBLED EGG |
2C64 | CRYSTAL EGG |
2CE4 | SONIC HAS |
2D54 | PASSED |
2D98 | RING |
2DAC | TIME |
2DC0 | SCORE |
2DD6 | 100X |
2DE5 | 00 |
2DF6 | 00 |
2E04 | ACT 1 |
2E90 | ACT 2 |
2F1C | ACT 3 |
Palettes
Master System palettes contain 16 colours, and each colour is defined by a single byte. Although you might think this means the colour format is 8-bit, it's actually only 6-bit, which gives a total of 64 possible colours. The colours are stored in the ROM as a value between 00 and 3F:
32x32 Mappings
First of all, the mappings begin with an offset index containing 256 16-bit, little endian pointers. The pointers are relative to a fixed position in the ROM, which varies depending on which set of mappings you're looking at. Immediately after the offset index is the mappings data itself. Each 32x32 tile is composed of 16 8x8 tiles. A 16-bit, little endian value is used to define which 8x8 tile is pulled from the VRAM, and also how that 8x8 tile is displayed. Adding certain amounts to the value cause the 8x8 tile to be flipped/mirrored:
Value added | Effect |
---|---|
+0000 | None |
+0002 | Flip horizontally |
+0004 | Flip vertically |
+0006 | Flip both ways |
Level layout and compression
Each byte in the level layout represents a 32x32 tile. The level is composed of many 32x32 tiles. In a savestate, the level is easy to edit because it's simple and uncompressed. However, in the ROM it's usually compressed.
Uncompressed: 2020 2020 2020 |
---> | Compressed: FD06 20 |
FD means compression has occurred. 06 is the number of times a byte has been repeated. 20 is the byte which has been repeated.
Strangely, 1515 (for example) appears in the ROM as FD02 15, which wastes space. Repeated strings of bytes can be used in the ROM, and will appear correctly in the game. Compression is entirely optional, given that there is enough space in the ROM for the data.
Object Layout
The properties of each object is determined by 9 bytes, which follow this format:
TT XXXX YYYY ZZ SS VVWW (FF)
- TT = object type
- XXXX = horizontal position
- YYYY = vertical position
- ZZ = per-object flags
- SS = object parameters
- VV = tiles to read from the VRAM
- WW = tiles to read from the VRAM when the object is reversed
- FF = end of sprite list (only appears once)
Object types and parameters:
TT SS | Description |
---|---|
00 | Nothing |
01 | Sonic |
02 | Collected ring sparkle |
03 | Power Sneakers stars |
04 | Fragment of a smashed block |
05 | Invincibility stars |
06 | Special object to hide ring counter & timer |
07 | Fragment of smashed block (different logic to 04) |
08 | Dropped ring |
09 | Air timer countdown |
0A | Bubbles (ALZ) |
0B | Splash of water (ALZ) |
0D-0E | Fireball (UGZ) |
0F | Explosion |
10 | Monitors:
|
11-14 | Chaos emerald |
15-18 | End level signpost |
19 | Falling spike with wrong mappings |
1A | Unknown |
1B | Falling spike (UGZ) |
1C | Clouds (intro sequence) |
1D | Clouds & cycling palette (intro sequence) |
1E | Tree (intro sequence) |
1F | Invalid object |
20 | Platforms:
|
21 | Platforms:
|
22 XX | Platform: moves side-to-side, XX = distance moved |
23 | Crab enemy |
24 | Fireballs that the crab enemy spits out |
25 | Yellow bird (SHZ) |
26 | Spears (ALZ):
|
27 | Glider (SHZ) |
28 | Flywheel (GMZ) |
29 | Minecart:
|
2A XX | Flywheel: moves side-to-side, XX = distance moved (CEZ) |
2B | Spiked crystal (CEZ) |
2C | Falling block (CEZ) |
2D | Falling log (SHZ) |
2E | Unknown |
2F | Unknown |
30 | Makes Sonic flash |
31 | Makes Sonic flash |
32 | Spinning turtle enemy (SHZ) |
33 | Lobster enemy (ALZ) |
34 | Moto bug enemy |
35 | Newtron enemy |
36 | SHZ boss - mini robot birds |
37 | Fish enemy (CEZ) |
38 | Burrobot enemy (GMZ) |
39 | Bomb enemy |
3A | Pig enemy (GMZ) |
3B-3F | Unknown |
40 | Prison capsule |
41 | Animals |
42 | GHZ boss - sumo robot |
43 | Unknown |
44 | GMZ boss - pig robot |
45 | GMZ boss - falling rocks |
46 | SHZ boss - mini robot birds |
47 | SHZ boss - eggs |
48 | SHZ boss - big bird robot |
49 | SHZ boss - fireball |
4A | ALZ boss - seal robot |
4B | UGZ boss - Eggman |
4C | UGZ boss - cannonball |
4D | UGZ boss - pincers thing |
4E | SEZ boss - Silver Sonic |
4F | ALZ boss - orange bouncing ball |
50 | Sonic's hand (title screen) |
51 | Tails' face (title screen) |
52 | Unknown |
53 | CEZ boss - floating cluster of yellow balls |
54 | CEZ boss - zigzag thing that crawls across the floor |
55 | CEZ boss - Eggman |
56-5C | Unknown |
5D | Tails (CEZ) |
5E | Unknown |
5F | Tails & Eggman (intro sequence) |
Loop XY motion data
When Sonic hits a loop in either Aqua Lake or Green Hills Zone, you're momentarily unable to control him. The loop motion data determines how Sonic moves vertically and horizontally when he reaches a loop. By default, he moves in a large circle. Modifying the loop data could allow Sonic to move around virtually any shape.
Little endian things
This means 1234 becomes 3412, and 5500 becomes 0055. It's a feature of Master System ROMs which makes hacking them slightly more confusing. Pointers have to be read backwards.