Hm, I was completely misremembering MoveCameraY. You are correct, it can move faster than 16 pixels/frame in S3&K. The exact conditions being:
- very high speed in Y direction (17 pixels/frame or more);
- either:
- being on the ground and having a high ground speed*;
- or being on air and far from the "butter zone" near the center of the screen.
* There is a flag for faster Y motion that some objects set; you don't have any control on those cases, however.
Lets do some math.
The buffer is effectively $500 bytes wide ($480 bytes from the actual buffer plus $80 for a buffer right after it used for some special effects, such as per-cell vertical scroll in some places). It holds two control words per line fragment or column fragment, and a sequence of patter names; worst case scenario, one plane can need $320 bytes ((64 pattern names per row * 2 bytes per pattern name + 2 words per row fragment * 2 fragments per line) * 4 lines + (32 pattern names per column * 2 bytes per pattern name + 2 words per column fragment) * 4 columns). In most S3&K levels, plane B is never reloaded in X direction (with only hscroll affecting its motion, and plane B simply looping every 512 pixels), and the motion in X or Y is never as fast for plane B as for plane A on the cases where it does move (being usually half the speed or less). So the buffer is more than enough for most cases.
However, those places where plane B is scrolled as foreground (MGZ2 rising terrain, FBZ2 rising platform, SOZ2 rising sand), the buffer might be insufficient: it would need to be $640 bytes so that everything would fit in the absolute worst case scenario. For MGZ2, the game does Y scroll before X scroll when drawing, so the buffer might fill up to $530 bytes before the X data would come in. Meaning the last $30 bytes of plane rows, and the entire data for plane columns, would be relevant in the worst case scenario. And the occasional control words. Part of plane B does scroll on X at 3/16ths of the speed of the speed of the FG, so it gets harder to cause issues.
As is, in the worst case scenario, you can royally mess everything from F600 to F73F; this includes the Nemesis decompression queue, which can mess up the game state even more.
Hm. Lets examine the possibilities:
- 5400-57ff : jump to FF0000: in MGZ2, there is a sequence of $0400 words at that address, followed by $007E $047F at $FF00C0. Each pair of $0400 words will become "subi.b #$400, d0". When PC reaches $FF00C0, it will be $007E $047F, which is an ori.w with an invalid addressing mode, resulting in an illegal instruction.
- 5cff-5fff : RTS to address at FFFE00: That is incorrect: the long that is read as an address is $2F016100, which results in a jump to $016100 as the 68k only has 24-bit address bus. This is the "ori" right before label loc_16106 in Tails' tails code, and will end up with the game stuck in a loop of jumping there, return after DrawSprite, and jump there again.
- 64ff-67ff, 7800-7bff : jump to FFC000: These are a bit more interesting: it jumps to the middle of object RAM. Specifically, to offset $1A of the $37th object slot. If this is a multi-sprite, this would be the y position of the first subsprite; for more normal sprites, this would be y speed, which is generally unused and left at 0 ("ori.b #XXX, d0", where the XXX is whatever word is at $FFC002).
Almost all other possibilities $54 or higher result in either illegal instructions or address errors. One jumps to the VDP data port, which will cause a lock up; and one jumps after the ROM ($4760EC), which will likely cause a lock up. The possibilities $50 and lower would not be useful — except maybe for $1C-$1F, $24-$27 or $28-$2B, all of which lead to level select.
Lets see: MGZ2 has $358 tiles, so it is impossible to write $64-$67, $E4-$E7, $1C-$1F, $9C-$9F, $24-$27 or $A4-$A7 to $F600. It would, however, theoretically be possible to write the following:
- $78-$7B or $F8-$FB: corresponding to a tile flipped on X and Y, on palette line 3 and with priority clear or set. Palette line 3 is used only for the background tiles, not for the foreground (including rising terrain); so one of the columns being drawn would have to draw a BG tile (any of them) to F600. In the rising terrain, there is a relative lack of objects; even losing 32 rings left object slot $37 clear. So in all likelihood, the game would go on executing "ori.b #0, d0" until reaching super stars/hyper trails, Tails' tails, or the dust controller object.
- $28-$2B or $A8-$AB: corresponding to a tile flipped on X (but not on Y), on palette line 1 and with priority clear or set. This is impossible, as planes A and B use only palette lines 2 and 3. Together with what I said above, this means no level select.
I have class now, so I will look up later what would happens for super stars/hyper trails, Tails' tails, or the dust controller object.