Waitdraw isn't required to be called, but it is recommended. Global Scripts can be split into 3 parts: Initialization (before the main while loop), Pre-Waitdraw (inside the while loop, before Waitdraw()), and Post-Waitdraw (inside the while loop, after Waitdraw() and before Waitframe()). If you don't call Waitdraw(), it will be handled by Waitframe() and the code inside the while loop will be entirely Pre-Waitdraw().
Waitdraw() essentially handles movements, inputs, and the likes (basically all engine-based movement), while Waitframe() draws the result. If you want to cancel an input, you do so Pre-Waitdraw, or else it won't do anything. If you want to move Link manually, you want to do so Post-Waitdraw, or else you'll get some janky effects with the engine moving Link after you move Link (of course, there's some exceptions; sometimes you want to move Link before something occurs at Waitdraw).
Moosh's header relies on some functions being called after Waitdraw, so you'll want to make sure you have that.
(Emphasis, mine.)
I'm pretty sure that's completely wrong.
As I recall, without an explicit call to Waitdraw() all instructions occur after drawing by default. I might need to verify this, but that's what I understand to be true:
The call to Waitdraw() ensures that your instructions are enqueued to run prior to engine drawing, and it's absolutely needed if you are doing things that affect collision, and making solidity checks.
Drawing occurs immediately after Waitdraw(), not Waitframe(). The Waitframe() call syncs the loop with the internal advance_frame() in the main() loop in ZC. Waitdraw() is, IIRC, the internal variable global_wait.
I'm pretty sure that it's mandatory to assure correct system timing.
It'd probably be best to check this using Link->Dir, based on when it is set.
//================================================== =====
//--- Instruction Processing Order and General Timing ---
================================================== =======
1. Instructions in Global script Init (if starting a new game)
2. Instructions in Global Script OnContinue (is resuming a game)
3. Instructions from FFCs that run on screen init, excluding draw instructions.
Note: Instructions are handled on a per-ffc basis, in ID order; so a script on ffc ID 1 runs,
then a script on ffc ID 2, up to ffc ID 32. If an ffc has no script, it is skipped.
4. Instructions immediately inside the run() function of a global active script, if the game has just loaded.
5. Instructions in the global active script's infinite loop prior to Waitdraw,
6. Instructions from an ffc script positioned after (an illegal)
Waitdraw() instruction in that script from the previous frame.
Note: Requires being on at least the second frame of a game session.
7. Screen bitmap drawing.
8. Enqueued Script Drawing from the global active script, (and from ffcs on the previous frame).
9. Drawing Instructions in the global active script prior to Waitdraw().
10. Instructions in an ffc script, excluding draw commands.
Note: Instructions are handled on a per-ffc basis, in ID order; so a script on ffc ID 1 runs,
then a script on ffc ID 2, up to ffc ID 32. If an ffc has no script, it is skipped.
11. Screen Scrolling (2.50.2, or later)
12. Waitdraw() in a global active script.
13. Engine writing to Link->Dir and Link->Tile.
14. FFCs enqueue draws for the next frame.
Note: Instructions are handled on a per-ffc basis, in ID order; so a script on ffc ID 1 runs,
then a script on ffc ID 2, up to ffc ID 32. If an ffc has no script, it is skipped.
15. Instructions from item action scripts.
16. Instructions from item collect scripts.
17. Instructions in the global active script, called after Waitdraw()
17(b). Screen Scrolling ( 2.50.0, and 2.50.1 )]
18. Instructions in an OnExit script, if the game is exiting.
19. Return to (3).