According to the VDP of the Sonic sprites when the game has crashed, the locator indicates that he is not rolling, but rather crouching still. The sprite indicators still say he's offscreen, but the limiters for the sprite stop him from falling off the stage. That, and also the game would have rather killed Sonic than throwing the ILLEGAL INSTRUCTION exception then. My guess is that the pallettes collide in Sonic 1's underwater pointers, and therefore tries to pallete switch. and then crashes
I diagnosed that crash recently while making Sonic 1 Upside Down, because the crash would happen as soon as the signpost art would load unless I'd jump, and I documented the fix on the wiki. The problem is much more subtle than what you're describing: the game is in the middle of decompressing the signpost art when the VBlank interrupt is raised. VBlank tries to resume Nemesis decompression, but the information necessary to do so is inconsistent at that point; the original game indicates that there's a decompression in progress that should be continued in VBlank BEFORE decompressing a part of the art, but some information is only set AFTER decompressing that part. If VBlank occurs DURING the decompression, the game crashes. This situation is easier to trigger when the water surface is higher on the screen, which was the case in my hack because the water was actually at the top rather than at the bottom. Concerning your observations, Sonic is most likely crouching instead of rolling because he hit the right level boundary (there's a boundary not too far offscreen). However, Sonic isn't falling off; if he was, you'd see the camera move to follow him.
Hmm, someone should fix that wiki on the glitches in Sonic 1, They say he appears to be "Falling off." So the theory there is debatable, but this code explains it all. This was a useful find, I see what you mean with the Vblank, but why does the VDP int register as 0C in the VDP status? Normally it would register as 00.
I fixed that part. Maybe that thought was inspired by the camera panning down, but that's just because Sonic is looking down/crouching. Sonic's Y position (the word at $FFD00C, if you want to check) doesn't indicate that he's falling. Huh? What are you looking at, exactly?
Huh? What are you looking at, exactly? I am looking at the M68000 Debug in Gens Rerecording. The last line in the VDP status shows something called VDP int. It makes sense now that you mention the last two numbers in the word register, that's what it picks up in the VDP int.
It's not the same 0C as in $FFD00C. I looked quickly Gens's source code, and all I think it means is that both VBlank and HBlank are waiting to be triggered (4 for HBlank, 8 for VBlank). The value is 04 in other levels, which don't use HBlank, so I guess it makes sense... Anyway, neither interrupt is triggered when the game is showing an error because it disables interrupts just before showing the error. In other words, neither the VBlank nor the HBlank interrupt handler routine run when the game is showing an error.
Interesting... No wonder the H and V blanks show as 0 then. This is an interesting find for me, thanks