Extending the demo: Layer Section II (Saturn)
Prototype stages, a model viewer, and more
Today we’re looking at Layer Section II, also known as RayStorm. The Saturn port came out in Japan in 1997, but it wasn’t released in North America or Europe (the PlayStation version was available worldwide, however).
There’s a demo disc for the Saturn version called Layer Section II Taikenban. It’s a fairly generous sample – it lets you play two full levels, a quarter of the game. But what’s interesting about it is that:
It’s based on a prototype build from two weeks before the final game (1997-08-06 versus 1997-08-20).
It’s got files for all the stages, not just the first two.
It has a debug menu that’s not in the final game with a cool 3D model viewer.
I made a patch to let you explore this build – get it from SegaXtreme!
Here’s a video of the patched version in action:
The 3D model viewer
When a RAM snapshot from this demo is analyzed in Ghidra, a few interesting strings present themselves:
0604ade8 "Round-00 Game Start"
0604adfc "Model Checker"
0604ae0c "Rotate-BG Test"
0604ae1c "Sound Checker"These turn out to be from an unused debug menu, which isn’t in the final game’s code:
The first item doesn’t really work — you can choose your starting stage and ship, but the game won’t actually start The second item, Model Checker, does work, however:
You can switch which model is displayed with L and R. You can zoom in and out with A and B, rotate with the D-pad, and move around by holding X and using the D-pad.
The Rotate-BG Test doesn’t seem to do anything. The Sound Checker does roughly what you would expect:
I replaced the Options menu with this screen by changing this pointer:
0609bcac 0604c234 # Point to the debug menuPatching Normal mode
The function at 060167b4 runs at the end of a stage. At the bottom of it is a bit of code that increments a value and then compares it to a literal 2. That value is at address 060810bc, and it’s what determines which stage loads next. The result of the comparison determines whether the demo ends.
Here’s my annotation of the code:
06016be4 mov.w @r11,r1 # Read the stage target from memory
06016be6 mov #0x2,r2 # Read a literal 2
06016be8 add 0x1,r1 # Increment the stage target
06016bea mov.w r1,@r11 # Write the incremented value to memory
06016bec exts.w r1,r1 # Extend the sign of the incremented value
06016bee cmp/gt r2,r1 # Compare the incremented value to 2
06016bf0 bf 0x06016bf6 # If it's not bigger, continue
06016bf2 bra 0x06016d18 # If it is bigger, end the demo
06016bf4 _nopTo proceed past stage 2, we can just skip the bra (branch) instruction at the bottom:
06016bf2 nop # Replace the branch with a null operationWith that change, stage 3 loads normally, and you can play all the way to the end of the game!
Patching Attack mode
Attack Mode lets you choose between stages 1 and 2. Comparing memory snapshots shows that your choice affects the address at 060810d4. This turns out to be the stage target, and altering it lets us choose the additional ones:
Setting write breakpoints for that address shows how the demo restrictions work: if the stage target goes beyond the value at 0607fb7f, it gets reset. We’ll call this the “stage limit.” If we replace reads to that address with a static value, we’ll be able to select everything:
0609af3a mov #0x8,r2
0609ad3c mov #0x8,r2The final battle doesn’t have title graphics, so it looks corrupt in the menu. It works, however:
Outro
I recently mentioned Layer Section II in my What you can’t say in a Saturn game article. That post has now been very nicely adapted into a magazine article by Dan at Sega Saturn SHIRO! Here’s a preview:
Check out SHIRO! Patreon page to get access to the full issue.

Thanks for reading Rings of Saturn. I’ll be back with more articles like this soon. You can subscribe here on Substack to get the next one delivered to your e-mail inbox as soon as it’s available.








