GetControlPad(), WaitVBL(), or WaitIO() instead of polling.
Busy waiting is a bad programming practice because it consumes one of the system's most valuable resources: CPU time. It may cause a video you are streaming in to grind to a halt. In a cable television environment it may cause the picture-in-picture display the user was keeping an eye on to become jerky and out of sync. This will make your program very unpopular. 
/*
**    BAD, NASTY, EVIL BUSY WAITNG CODE!!
**    Wait for the user to make a selection, then press start
*/
do {
    userInput = ReadControlPad (JOYMOVE + JOYBUTTON)
    switch (userInput) {
        case JOYUP
            MoveSelectionUp();
            break;
        case JOYDOWN
            MoveSelectionDown();
    }
} while (userInput != JOYSTART);
or
/*
**    BAD, NASTY, EVIL BUSY WAITNG CODE!!
**    Pause for about half a second.
*/
for (waitLoop = 0; waitLoop < ABOUT_HALF_A_SECOND; waitloop++)
Consider the two examples of busy waiting above.
or 
/*
**    Wait for the user to make a selection, then press start.
**
**    Setting the wait flag to true in GetControlPad puts us into
**    the sleep queue until there's a change of control pad 
**    status, allowing lower or equal priority tasks to get time
**    slices.
*/
do {
    err = GetControlPad (kMyControlPad, true, controlPadData);
    CHECKRESULT (err, "GetControlPad");
    switch (controlPadData->cped_ButtonBits) {
        case ControlUp:
            MoveSelectionUp();
            break;
        case ControlDown:
            MoveSelectionDown();
        case ControlStart:
            polling = false;
    }
} while (polling);
Wait functions used wisely eliminate busy-waiting. The 3DO Portfolio documentation, its html online version, or 411 help describe these calls. The kernel, the event broker and the audio folio all have functions for putting a process to sleep while it's awaiting a resource. Using them will measurably improve overall performance.
/*
**    Wait for a half a second to go by before we proceed
*/
struct timeval delay;
delay.tv_sec     = 0;
delay.tv_usec    = 50000;
WaitTime (myTimer, &delay);            // See functions below