Module 5: Explaining the First Program

Recapping

In the last module, we introduced sufficient code to make a Wimp program work. There was a price to pay in that we introduced a number of new concepts without explaining them, and this module is intended to put that right. In particular, we included functions and procedures, we added some new keywords including the CASE ... ENDCASE construct, the DIM statement, the ERROR statement, and we used some system calls in the form of the SYS command. To make it easy to follow we will work through the program and explain line by line.

Errors and procedures

After the REMs the program begins with a LIBRARY statement. This was explained in Module 4, and this line tells the BASIC interpreter that we will be using the extra routines in the library file called Library1. Note that it uses the system variable Obey$Dir to indicate where it will be found, and that BASIC requires the system variable to be contained within the marks < and > for it to be recognised as such. Because the LIBRARY command expects a string, it is contained in quotes.

The next line uses the ON ERROR keywords. We could have left this until a later Module, but it is so valuable in solving any problems in your program that we have put it in now. The ON ERROR statement tells BASIC what to do if it comes across an error, and in this case it is told to execute a procedure.

A procedure is like a self-contained small program that undertakes just one specific task. It is called by name by entering PROCname. It is normal practice to keep the name in lower case which makes it easier to identify; PROC must be in capitals as with all BASIC keywords. The name in this example is 'error', and out of sight in the Library there is a corresponding section of code that begins DEFPROCerror which defines where the routine begins. At the end of the routine it is closed with the keyword ENDPROC. Procedures are the preferred way of going to specific routines rather than using GOSUB commands that depend on line numbers. To view this procedure you can load the library file into Edit as a normal BASIC program file.

Following PROCerror there is a section in brackets. This is a way of passing additional information to the procedure. In this case, REPORT$ is another BASIC keyword that is made to contain the error message last encountered. We have added to this the words 'at line' and then put STR$ERL at the end. STR$ converts a number to the string equivalent, and ERL is another BASIC keyword rather like REPORT$ but it is made to contain the number of the line in which the last error occurred.

As an example, we might have miss-typed the 12th line of our program. In this case an error message would read: "Syntax error at line 120". Notice it is 120, not 12. This is because BASIC counts the line numbers in tens by default. To find the line in Edit you would need to press F5 and enter the number to go to as 12.

The DIM statement

The DIM statement requires the system to set aside a specific part of memory which has an appropriate name chosen by you, the programmer. DIM is short for dimension, and reflects the purpose of defining the size of the memory block required.

In the three lines of DIM statements we have set seven different parts of memory up for future use. In the first case, we have used the name block. This will be used frequently for a wide variety of purposes, and has been dimensioned as 255 units. This is equivalent to 256 bytes. block% itself is not what is contained in the memory. It actually contains the start address of the memory allocated, and we will see later how we can access different parts of the next 255 bytes when we need to.

message% defines a section of memory for passing messages around. texta%, textb%, etc will be used to provide information to go into window displays, and R5% to set up the 3D look to the icons.

In the 10th line we put a string, R5, into the memory that starts at R5%. Notice how this is done: the $ symbol preceding R5% tells BASIC that the string that follows the equal sign must be stored at the address R5%.

The next 2 lines contain nothing new, but set the variable quit% to be FALSE and app$ to contain the name of the program.

System routines

System routines make life very easy for Risc programmers. The idea is that a number of frequently used routines have been written into the operating system itself. Any program, whatever language it is written in, should be able to call these routines which are generally very quick and efficient. They are called software interrupts - SWIs for short - and are exactly that. They interrupt the normal progress of your software program in order to execute a special request to the operating system.

In BASIC we call a SWI by using the system command SYS, and the next line of our program is the most important call we make because it is designed to say 'This program is to be run in the Wimp'. The SYS command calls on the system routine called Wimp_Initialise. Note that the use of upper and lower case is essential; it must be typed exactly as shown.

Every SWI expects a given number of inputs, and will usually return other values when it has completed the routine. In this case, Wimp_Initialise requires 3 pieces of information. The first number, 200, tells the operating system that this program is written for RISC OS 2 onwards. If we replaced this with 300, then the program would only run on RISC OS 3 upwards, but we can't just choose arbitrarily the value we insert. If we use in our program any OS 3 SWIs that were not defined for OS 2, then we have to use 300. Unless such calls are necessary, we would avoid them, use 200, and maintain backwards compatibility.

The next (hexadecimal) number is always the same, and is there to identify it as a genuine Risc program. It is the same for all programs, so you can copy it in and forget it! The last item is the string app$ which we have already set to be the name Secrets, and tells the system the name we have given to the program. It does not have to be the same as the application name, but it will be used to display information in the task manager. It makes sense to use the same name.

Icons and Windows

Remember that icons are the small sprites that make up the window displays. The most important icon is usually the one that will appear on the iconbar, and the next line in the program makes sure the right icon is put on the iconbar in the right place. It uses a function and also involves a system call.

'The keys that make the Secrets main icon'

Functions work like procedures with just one key difference. A function is a specific section of code to do a particular task, and is called using the FN keyword which is followed by the function name. However, when the function is completed it returns a value to the main program, which is why, in this case, we make iconbar% equal to the function. For simplicity at this stage the function is contained in the Library, and so we will not describe it in detail, but part of the function contains a SYS statement which sets up a pointer which will be stored in iconbar%. We will be able to use iconbar% to identify the icon in the rest of the program.

The numbers passed to this function in the brackets that follow pass on some important information. '-1' says put this icon on the righthand side of the iconbar. The next two values define the position, but because this is the icon bar we don't know, so we leave this to the operating system and move on to the next two values which define the width and height of the space required for the icon. These are measured in OS units.

The sixth number contains what are called flags. In this case, the 2 indicates that the icon will contain a sprite, and the 3 ensures that a click on the icon will be noticed by the application. The next field contains the name of the sprite to be displayed, and the last three numbers must be zero in this case.

The next line creates an information window. The code is again hidden away in the Library, so I will not describe it here, but the strings passed to the function should be obvious, after you have run the program if not before.

The Polling Loop

The next most important section of the program begins after the REM statement heading The Poll Loop. This is the heart of a multi-tasking program, and without a poll loop, a multi-tasking program cannot run. The loop beginning WHILE NOT quit% runs continuously throughout the life of the program until quit% is changed to TRUE.

The SYS call to Wimp_Poll effectively asks the operating system repeated to tell the program what is happening. This is returned in a variable called reason%, so every time the program asks, a number is returned. At the moment, we are only interested if this number is 6 or 9. The CASE reason% line introduces a list of possible events. If reason% is 6 then it will execute the procedure PROCclick(block%!12). If it is 9 then it will execute the menu procedure PROCmenuselect. If it is any other number, then it will be ignored.

This is probably sufficient for one module, but we will finish by asking a couple of questions.

1. Can you work out how and where in the program quit% gets changed to TRUE?

2. Most of the program up to the line REM The Poll Loop is concerned with setting up initial conditions, defining windows, etc. Many programmers would put this in a procedure of its own and call it PROCinit. This would then be placed after the END statement following the poll loop section. See if you can set this up in this way, which will then help us to introduce the need for structure in our next module.