Page 135
(table continued from previous page)
Table 6-11. SOUND_PLAY Sounds (continued)
Sound Number Description
2 Descending arpeggio
3 Ascending arpeggio
4 Long low note
5 Quick ascending arpeggio (same as 3 but faster)
The sounds can be either unqueued or queued. Unqueued sounds will be played right away if no sound is currently playing. If a sound is currently playing (i.e., the sound system is already
busy), then the unqueued sound will not be played at all. A queued sound, on the other hand, waits for the sound system to finish whatever it's doing and then plays. The value of code
determines if a sound is queued (4003) or unqueued (4004).
SOUND_GET (address --)
This word returns the current state of the sound system to the given variable. You can use the pbFORTH-supplied variable RCX_SOUND for this word. A zero indicates that the sound system is not
busy. Any other value means that the sound system is busy playing another sound.
Cooperative Multitasking
pbFORTH version 1.0.5 introduced words that support cooperative multitasking. Cooperative multitasking allows multiple tasks to appear to run simultaneously. In reality, each task must
voluntarily yield control to the next task in line. The other kind of multitasking, which you've seen in NQC and will see again in legOS, is called preemptive multitasking. With preemptive
multitasking, the system gives little bits of time to each task, interrupting each task to give control to the next task.
Cooperative multitasking is a little tricky to program because each task needs to explicitly yield control to the other tasks. If your robot has a task that is going to do any lengthy processing, the
task needs to be structured so that it can yield control frequently.
The pbFORTH web page has more information on cooperative multitasking. Take a look at the tortask.txt example, which is a good demonstration of the use of multiple tasks in pbFORTH.
The basic procedure for running a multitasking program has four steps:
1. First, you need to allocate space for each task using the ALLOT_TASK word. This includes space for user variables and space for a parameter and return stack. Here's a sample from tortask.txt:
0 32 CELLS 32 CELLS ALLOT_TASK MOTOR_TASK
Page 136
The CELLS word simply converts a number on the stack from cells, which are the fundamental units of Forth memory, to bytes. The line above allocates no space for user variables and 32
cells each for the parameter stack and return stack. The name of the new task is MOTOR_TASK. In tortast.txt, three other tasks are allocated in the same way:
0 32 CELLS 32 CELLS ALLOT_TASK TIMER_TASK
0 32 CELLS 32 CELLS ALLOT_TASK SENSOR_TASK
0 32 CELLS 32 CELLS ALLOT_TASK DISPLAY_TASK
Notice how the name of the new task is specified after the ALLOT_TASK word, almost like a variable definition.
2. Next, each task must be built into a list. When one task voluntarily gives up control (cooperates), the next task in the list will get control. The BUILD word assembles tasks into a list: