Multitasking: A first complete program

Let's now put all this together into a complete program. The following code contains all the housekeeping stuff. Also, I have changed some labels into the form I prefer to use. This is a consistent way of generating label names that in particular saves a lot of head scratching to come up with names and also makes it much easier to find what I want in a 6000 line program. The basis of my labeling scheme is that I give each function (subroutine) a short 2 or 3 letter capitalised prefix.

*****************************************
; I/O assignments
Light      oEQU      15            ;MMi99 front panel LED
FlashLight oEQU      14            ;MMi99 front panel LED
Switch     iEQU      8             ;MMi99 front panel push button
*****************************************
; RAM assignments
OOS_Address mEQU     0             ;2 bytes for a suspend address.
*****************************************
; initialize code
         GoSub       FTL_Init
         GoSub       OOS_Init
*****************************************
; Main loop
MainLoop
         GoSub       FTL_Update    ;Update the flashing light
         GoSub       OOS_Update    ;Update the push on/push off light
         GoTo        MainLoop
*****************************************
;On-off switch function
;Short name: OOS_
;Function: Toggles the Light output each time the front panel button
;          switch is pressed.
;Methods:  OOS_Init
;          OOS_Update

OOS_Update
         Resume      OOS_Address   ;Resume from where we last Suspended
OOS_Init
OOS_0
         Suspend     OOS_Address
         GoIfInOff   Switch,OOS_0
         On          Light
OOS_1
         Suspend     OOS_Address
         GoIfInOn    Switch,OOS_1
OOS_2
         Suspend     OOS_Address
         GoIfInOff   Switch,OOS_2
         Off         Light
OOS_3
         Suspend     OOS_Address
         GoIfInOn    Switch,OOS_3
         GoTo        OOS_0
******************************************
;Light flasher function
;Short name: FTL
;Function: Flash output FlashLight at 1Hz, 50% duty cycle.
;Methods:  FTL_Update
;          FTL_Init
FTL_Update
         Test        0              ;Test the timer
         RetIfT                     ;Return (yield) if still timing
         SetTimer    0,5            ;Restart the timer
         InputO      FlashLight     ;Read back the output
         Not                        ;Reverse the value
         Output      FlashLight     ;Update the output
FTL_Init
         Return                     ;Yield

Copy and paste this program into SPLat/PC now (you may have to manually fix up some weird stuff inserted by the copy and paste). You will need SPLat/PC V6.12.0 or later set to dialect 12 or later. Run the program in simulation mode. You should be able to actually observe that the program passes through different parts of OOS_ as you click the button (input 8) on and off. If you look at RAM locations 0 and 1 (in the Data Memory window) you will even be able to see the current line number where OOS_ has suspended from. The line number is 256*RAM(0) + RAM(1). You should even be able to relate that back to the actual program line number displayed in the SPLat/PC editor status bar. Note that in the simulator the editor line number is saved in RAM. In the actual board, it is the program memory address that is stored, which is a totally different number.

Can you see how each of the two subroutines is operating quite independently of the other, and how all the main program loop does is to call them in quick succession? Can you see how easy it would be to add a third, and a fourth subroutine (function)? Can you imagine a large control program taking care of a quite complex piece of equipment, and structured as maybe 10 or 20 or 30 such subroutines, each controlling a separate aspect of the equipment? In the next section I will evolve this into the idea of a task or process, and start to show you how a program can indeed be structured as a number of such tasks that perform their individual functions while communicating with each other to co-ordinate their efforts.

"Why", I hear you ask, "have you got FTL_Init when it does nothing?" (You did wonder, didn't you?). The reason is to make the programming as boringly consistent as possible. Doing things in consistent way throughout can save a lot of work in the long run, even if it means a bit more typing in the short run.

In the next section we will establish some communication between our two tasks, to show how you can co-ordinate activities

Special note: This tutorial and the multitasking mechanism it covers have largely been superseded by the newer MultiTrack mechanism. MultiTrack achieves everything and more, with considerably less programming effort. The only time you would use this older multitasking mechanism would be if the controller you are using is unable to handle as many tasks as you need using MultiTrack.