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.