Well since everyone else is in the game, I may as well join in, I have a fix for a bug that you cannot cause very easily in the original Sonic 1 game, but if one were to do something like a special cut-scene involving the screen moving to the right somewhere away from Sonic, and then letting the engine move the screen back to Sonic, then they would probably see this bug in action.
The engine that allows the screen to follow Sonic has the responsibility of ensuring that the screen does not move more than 10 (hex) pixels any direction at one time, this is to allow the draw code to draw the lines of 16x16 blocks correctly without skipping any lines, this means that if Sonic is away from the screen's "central box" position by less than 10 (hex) pixels, then the screen's "central box" will move directly to Sonic, if however, Sonic is further than that, the screen will move at a maximum of 10 (hex) pixels in the direction it is suppose to be moving to. The routine "ScrollVertical:" handles this for moving the screen up and down, "ScrollHoriz:" on the other hand (or should I say "ScrollHoriz2:") handles this for the screen moving right, but
not when moving left.
Observe the code for right movement:
loc_65CC:
cmpi.w #$10,d0 ; <- Restriction
bcs.s loc_65D6 ; <- Restriction
move.w #$10,d0 ; <- Restriction
loc_65D6:
add.w ($FFFFF700).w,d0
cmp.w ($FFFFF72A).w,d0
blt.s loc_65E4
move.w ($FFFFF72A).w,d0
As you can see by the code marked "Restriction", this is to prevent the screen from moving right by 10 pixels, thereas if we look at the code for left movement:
loc_65F6:
add.w ($FFFFF700).w,d0
cmp.w ($FFFFF728).w,d0
bgt.s loc_65E4
move.w ($FFFFF728).w,d0
bra.s loc_65E4
The "Restriction" does not exist, the fix is moderately simple:
loc_65F6:
cmpi.w #$FFF0,d0 ; has the screen moved more than 10 pixels left?
bcc.s Left_NoMax ; if not, branch
move.w #$FFF0,d0 ; set the maximum move distance to 10 pixels left
Left_NoMax:
add.w ($FFFFF700).w,d0
cmp.w ($FFFFF728).w,d0
bgt.s loc_65E4
move.w ($FFFFF728).w,d0
bra.s loc_65E4
There is another bug related to this which funnily enough is also related to the good old "screen wrapping vertically" bug in Sonic 2 and up, but this is to do with horizontal rather than vertical, at routing "ScrollHoriz2:" we have:
ScrollHoriz2: ; XREF: ScrollHoriz
move.w ($FFFFD008).w,d0
sub.w ($FFFFF700).w,d0
subi.w #$90,d0
bcs.s loc_65F6
subi.w #$10,d0
bcc.s loc_65CC
clr.w ($FFFFF73A).w
rts
bcc and bcs are unsigned branches, the problem here is that if Sonic is behind the screen (I.e. to the left), the result will be negative (I.e. a value from 8000 to FFFF), but with the unsigned branches it will obviously treat 8000 to FFFF as positive and higher than 7FFF, thus it believes it has to move right rather than left, the fix is also simple, change the unsigned branch conditions with signed branch conditions:
ScrollHoriz2: ; XREF: ScrollHoriz
move.w ($FFFFD008).w,d0
sub.w ($FFFFF700).w,d0
subi.w #$90,d0
bmi.s loc_65F6 ; cs to mi (for negative)
subi.w #$10,d0
bpl.s loc_65CC ; cc to pl (for negative)
clr.w ($FFFFF73A).w
rts
The cc to pl should not matter, but it's best to be safe.