This UberASM will scroll layer 3 up and down when L/R are pressed (L = up, R = down). This is meant to be used with tides: if you override the layer 3 settings, make sure the vertical scroll is set to None. Also, the code disables L/R scrolling to not interfere with this.
In the asm file you can customize the min and max position you can scroll to, and the speed (set in 256th of a pixel per frame, to allow for more fine-tuned speeds). It requires 1 byte of freeram.
Works as intended, so, accepted. However, the default value for "!MaxYPosition" caused a single pixel of cutoff with the status bar when using tides, so I tweaked this and edited the corresponding comment. Other layer 3, such as the underground rocks, move further up and will still be cut off with the default value, so you will need to either change the default value depending on the layer 3 type, or use a patch solution, such as Remove Status Bar or Sprite Status Bar.
One oddity to be aware of is that after layer 3 gets nuked by message boxes (vanilla behaviour), it is possible to restore layer 3 to the screen with L/R, but the layer 3 horizontal scrolling will be gone (e.g. tides not moving left).