M/C Part 24 MULTITASKING ON YOUR SAM ======================== Now for the ignorant, naive or Dundee-supporting readers (although I don't think many Dundee fans can actually read. Ooh, bitchy!!!) multitasking is the ability of a machine to run more than one program similtaneously. Now, since the poor wee processor inside this bundle of tricks can only do one instuction at a time, real multitasking is impossible. What I propose to dicuss is a method for simulating multitasking on the Coupe. I should probably start by mentioning existing software which allows this to some extent. MasterBasic has facilities for background/ foreground tasking, that is, a non-urgent process is carried out at the same time as one which requires more processor attention - Interrupt driver printing is the obvious example, but MB also allows interrupt driven sound. In fact, you could do a whole host of stuff "interrupt-driven", mainly input/output. Most of you will have written, or at least seen, interrupt-driven scrollers. I remember one of the first decent programs I wrote on the Speccy was an interrupt driven clock. (Aaah, nostaligia. Shame about SU wasn't it? Ha!) I'm sorry. For the Dundee supporter I'd better remind you what interrupts actually are. When a peripheral wants to be serviced (I WILL resist cheap gags, I WILL resist cheap gags) it tugs on the Z80's interrupt line. The processor then completes its current instruction and runs a servicing routine. When the routine's finished, the CPU resumes its previous task. In fact the Z80 has 3 modes of maskable interrupts, but I will normally use mode 1, which is the normal one. Chris White's column has mentioned mode 2 recently, but if you want to know more then consult the back issues of this esteemed organ. The most-used interrupt on the SAM (and the Speccy, for that matter) was the frame int. This happens regularly 50 times a second after the TV has completed one scan of the screen. The MB background taskers use this, but some people prefer (for whatever perverse reason) to envoke a line interrupt somewhere on the screen and use that instead. I covered the line int in an earlier article. WHAT? HOW? WHY? =============== I suppose the big question is why the hell do we want to multi-task, anyway? In fact, aside from the background tasking mentioned previously, there seems no reason. It's really only on big machines (eg. mainframes) where it becomes important. I'm only writing this to avoid another horrible confrontation with Brian (I still haven't got the blood stains off the wall. Blue blood, of course), and to stimulate (something I'm rather good at, as the females among the Perth public will tesify to. Ahem) the coders amongst you. Besides, it sounds pretty cool to say that the SAM can multitask. Makes a nonsense of the Amiga manual's claim to be the only comparable machine capable of it. And the ST can stick itself up a user port too. Now, after consulting a heavy (both in weight and content) book on the subject, I reckon that there are two ways to do this. *** 1. The "I'm doing f**k all, you can have a go" Method *** Using this, we have a main program which trundles along minding its own business until it has to wait for something to happen. A keypress, input from a modem, Saints to win the cup, that kind of thing. (I guess you're beginning to see the problems already.) When this happens, control reverts to a secondary program which executes until either the first program is ready to continue, or it is held up be a peripheral or whatever, in which case control reverts to a third program, and so on... Well, this certainly has its advantages. The SAM only has one user interface, so only one program can have priority. In fact a priority scheme would be very easy to implement. The problem is, simply, how the hell to do it! The first bit, when the program executes until it comes up against a brick wall, is easy enough to do. The smelly bit is trying to include a method for testing whether or not the program can continue, when the second task is running. *** 2. The "Time Slicing/ Gerrof it's my turn" Method. *** Here, each program is given a certain amount of time to run, and control switches to the next one once time runs out, or the "brick wall" is encountered. Simple, but effective. It sounds too easy to be true - and it is. How the f**k do we "time" the running of a program? And this doesn't allow for priorities, producing time delays. People can only use one at a time! So, in fact, multitasking isn't possible, and I've led you all blindly up a wild goose. Or something. Ha! What d'ya mean I can't do that? Why not? No money? Grumble, grumble... Okay, okay. Howsabout we combine the two systems. My idea is this: (rolls up sleeves, runs figures back through hair, lick lips) We have a control program running off the frame interrupt. It handles everything; mouse movement, key scanning, port I/O, the economy, the SFA, Fergie. Everything. Every 50th of a second it calls round all the "tasks" in order (highest priority first) asking them whether they could run. The call will be to a routine in the task which checks what it's waiting for: keypress, port input, mouse click, nothing etc. and responds accordingly. As soon as a routine says it's waiting for nothing, or whatever it's been waiting for has happened, the controller checks whether it is currently running. If so, do nothing. If not, this means that a lower priority task IS running and must be halted. A seperate routine in that is called to inform it (so that it can save registers, data etc), and a third routine in the new task is called to tell it to start running. It all sounds kinda complicated, but it isn't really. All that the tasks need attached are three routines: A. Check ready to run. B. Terminate execution. C. Run. When a task hits the brick wall, it calls the controller to tell it, routine B is called, the controller checks the most suitable tasks out with A, and starts one with C. If a smaller time slice is required, line interrupts can be used. Easy eh? Easy as scoring.