Below is the manual that came supplied with the CM and XP models of the Psion Organiser II, from 1986 to 1988. I have combined two editions of the manual in this web page. By using the radio buttons below you can choose which version to show. If you choose to view both, then you will see the changes made between the two versions, with old text written in red and crossed out, and new text written in green, like this: This is the firstupdated version of this sentence.
You are currently viewing: Version 1Version 2 of the manual.
Introduction 1 Where Things Are 2 Getting Started 3 The Time Function 4 Switching Off 5 Saving and Finding Data 6 Erasing Data 7 Datapaks 8 The Calculator 9 The Diary 10 Alarms 11 Prog 12 Info 13 Copy 14 Reset 15 Record HintsHints About Records 16 Customising the Menu
17 Introduction to OPL 18 Creating a Procedure 19 Running a Procedure 20 Variables 21 String Variables 22 Array Variables 23 Operators 24 Procedures 25 Data File Handling 26 Loops, Labels, Jumps and Branches 27 Error Handling 28 Printing Procedures 29 Procedure Directory 30 Erasing Procedures 31 Copying Procedures 32 Example Programs 33 OPL Commands 34 OPL Functions Appendices Index
Copyright Psion LimitedPLC 1986
To avoid any possible damage your Organiser should not be exposed to extremes of temperature or humidity. Do not subject it to hard knocks or excessive force, nor use volatile liquids when cleaning the case.
UK PATENT NUMBER: 2161300
REGISTERED DESIGN APPLICATION No'sUK REGISTRATION DESIGN Nos: 1019736 & 1019737
Manufacturer's Warranty and Limitation of Liability
If within 12 months of purchase this computer can be shown to the reasonable satisfaction of Psion to be faulty and not to function substantially as described in the user manual, Psion will (at the option of the purchaser) refund the purchase price or replace the computer. Apart from this warranty, Psion will not in any event be liable for any loss, including consequential loss, caused by any error, defect or failure of the computer, or howsoever otherwise arising, including but not limited to loss of use, loss of stored data, loss of profit or loss of contracts.
This limitation of liability shall not apply to consumer transactions nor to any liability for death or personal injury.
Written by Barry Thomas
Typeset by KeywordsADO Typesetting, London
Printed by Premier Metropolis Limited, London
The Psion Organiser II that you have just purchased is a powerful computer for your pocket - an expandable system with a microprocessor significantly more advanced than those found in micros many times its size.
Your Organiser can be used straight away. It has its own built-in memory which will retain information, even when the Organiser is switched off.
The Organiser also has two unique and versatile 'solid-state devices' concealed under its protective sliding case, and these thumb-sized units are the key to the open-ended power of the Organiser.
The internal memory of the Organiser will hold around 1600032000 characters of information (Model XP) or 8000 characters on Model CM, but the addition of one or more Datapaks boosts the storage capacity by up to 64000 characters per Datapak on Model CM or 128000 characters per Datapak on Model XP.
Additional Datapaks allow you to create an infinitely large and secure personal information base, which, when used in conjunction with program packs from the software library, provides unbeatable processing power in your pocket.
The Organiser has a built-in Diary facility which allows you to keep track of personal appointments and engagements. You may set an alarm on any or all of your diary entries, or simply let ituse the built in Alarm feature to operate as an alarm clock.
The Organiser is also a sophisticated calculator, and can carry out complex calculations involving any number of levels of brackets. You can use mathematical and scientific functions and use up to ten memories. You can enter both data and formulae exactly as you would write them. The Organiser also has its own built in programming language OPL, specially designed to handle your database applications and fully utilise the machine's facilities.
A selection of peripherals and program packs allow you to, for instance, print out information stored in your Organiser, connect it to another computer or send information over a telephone line.
The Organiser supercedes your personal notebook, diary, clock and calculator and in addition puts unparalleled database processing power into one pocket-sized computer.
A range of peripherals and program packs is available for the Organiser, including a mains adapter, RS232 communications, bar-code reader, and card-swipe reader, Maths Pack, Finance Pack and Spelling Checker.
As you learn about all the powerful facilities of your Organiser, feel free to experiment! Don't be afraid to try things out - you can't harm the machine by pressing keys, so go ahead and find out just what the Organiser can do for you.
Figure 1. Rear view with protective case removed.
Figure 1. Rear view with protective case removed.
Figure 2. Front view with keyboard exposed.
Figure 3. Top view of Organiser
Figure 4. Fitting the Battery
Your Organiser uses any 9 volt PP3 size battery. However, for a longer operating life the use of alkaline batteries is recommended, especially if Datapaks are fitted.
Grip the protective case (Fig 2.3) just below the separation point (Fig 2.4) and pull it firmly downwards until it comes right off the Organiser. Find the tab of the battery cover at the back of the Organiser. Pull the tab to remove the cover, and the battery connector will be visible on the side wall of the battery compartment.
To connect the battery, slide it into the opening, making sure that the two connectors on the top of the battery slide all the way into the battery connectorsmaller, positive, terminal enters first. If the battery only slides in half way, then you have tried to put it in the wrong way round. Turn the battery over so that the other metal contact slides into the battery connector first, and try again.
To replace the battery cover, slip its lip into the corresponding groove just inside the battery compartment. Clip the tab in place and your Organiser is now ready for use.
When the battery runs low, a LOW BATTERY message will be displayed on the Organiser's screen to let you know. This will be displayed for fivefour seconds and then the machine will switch itself off. The battery must be replaced before the machine can be used again.
If you are saving information to a Datapak when the battery runs low, the record which is currently being saved will be finished, but then the low battery message will appear and the machine will switch off.
The information stored in the Organiser, in the Diary and main data file for instance, relies on the presence of the battery to keep it safe.
When the battery needs to be changed, first ensure that the machine is switched off. If this is not done - all data will be lost from the internal memory of the Organiser as soon as the old battery is disconnected. Ffollow the instructions above for opening the battery compartment on the bottom of the machine. When the old battery is removed, you have a limited time to replace it with a new one, after which you begin to lose the contents of the Organisers memory. Data stored on Datapaks is quite safe however.
From wWhen the old battery is removed, if the new one is not inserted in the machine within 30 seconds, the system time as stored in the TIME function on the main menu will be lost. This can be reset when the new battery is safely installed, and no other losses will occur.
If you have not successfully inserted the new battery' within 90 seconds of removing the old one, then the contents of the machine's memory will be lost.
If you are at all doubtful about being able to insert the new battery within this time, then you should save any important data onto a datapak first.
Alternatively, you may use the Psion Mains AdapterPsion Mains Adaptor to power your machine while you change batteries, this means that the power supply to the Organiser is uninterrupted and you are not limited to the above times to fit the new battery.
Press the ON/CLEAR key, the top left hand key on the keyboard. The screen will show the menu - the list of built in applications which are available to you. If you cannot see anything on the screen or if the screen is difficult to read, you may have to adjust the contrast using the contrast wheel on the right hand side of the casing. Experiment to find the setting that suits you best.
Look at the keyboard before you continue. Most of the keys have labels both on the keys themselves, and above them.
The letter keys normally produce capital (upper case) letters on the screen. The position on the screen where the character will appear is marked by a flashing cursor. When the Organiser is switched on, the cursor will flash alternately as a block and a line underneath the character.
By holding down the SHIFT key and pressing one of the letter keys, you are able to access the symbols and numbers marked above the keys. When the SHIFT key is held down, the cursor is a solid (i.e. not flashing) line underneath the character.
By holding down the SHIFT key and pressing the NUM key, these numbers and symbols may be 'locked' on, so that the SHIFT key does not have to be constantly held down. This is useful when entering long sequences of numbers. Repeating the process returns the keyboard to normal upper case operation.
Lower case letters may be typed by using 'CAP lock' mode, i.e., by holding down the SHIFT key and pressing the CAP/up arrow key. You can return to capital letters by repeating this process. To type lower case letters, first hold down the SHIFT key and press the CAP / UP cursor key. To return the keyboard to upper case mode, repeat the above process.
The top row of keys on the keyboard, and some of the bottom row, are somewhat different to the other keys in that they do not produce a character on the screen when pressed. The use of each of these keys will be described in turn. Each of these keys is described overleaf.
The key at the top left of the board which is used to switch the machine on and to exit from various levels of use of the machine.
The key at the bottom right of the keyboard which is used to confirm an action or complete a line of input to the Organiser.
The four keys on the top row of the keyboard marked with arrows are used to move the cursor around records stored in the Organiser and used in other varying ways by the built in facilities of the machine.
Used like the shift key on a full size keyboard to access the characters marked above each of the keys (numerals, arithmetic operators and other special characters.)
The delete key is used to delete characters typed at the keyboard and used by some of the built in facilities of the Organiser.
Initially, the screen will look like this:
FIND SAVE DIARY CALC PROG ERASE
The first character of the first word on the screen, is covered by a flashing block, this is called the cursor. To move the cursor, use the four arrow keys on the top row of the keyboard. These are the cursor keys. In this manual, the right arrow key will be referred to as the RIGHT cursor key, the left arrow as the LEFT cursor key and so on.
Pressing the RIGHT or LEFT cursor keys will move the flashing cursor on to the first letter of the next (or previous) item on the menu. Further presses of the same key will move the cursor across the screen and then to the next line and so on. When the cursor is positioned on the last item visible on the screen, pressing the RIGHT cursor key once more will bring up the next line of the menu.
The UP and DOWN cursor keys allow you to scan the menu by a line at a time, instead of just one item at a time. Then when you reach the end of the menu, the last item will be OFF. Pressing the RIGHT or DOWN cursor keys once more will return you to the top line of the menu, where you began.
The full range of menu items when you first switch on your Organiser are:
|FIND||For retrieving and/or editing records you have previously saved, providing access via any aspect of their contents|
|SAVE||For saving information either in the Organisers internal memory or a removable Datapak|
|DIARY||All the usual diary functions, plus the ability for appointments entered in the diary to sound an alarm when they become due; listing of diary appointments; searching for diary appointments|
|CALC||For calculations: allows use of numeric functions from OPL (see below) and includes ten memory stores|
|PROG||Full programming language, OPL, (Organiser Programming Language) allows you to write programs for your own specialised applications|
|ERASE||For erasing records from the Organiser's memory or a Datapak|
|ALARM||Up to eight alarms can be set to sound once only, hourly, daily or weekly|
|TIME||Real time clock (time, day, date, month and year) which is permanently stored in the Organiser, and is also used by the alarms and the language functions|
|INFO||Gives a full description of how much memory is occupied by the DIARY, how much room is available on any Datapaks fitted, and how much space is left in the internal memory of the Organiser.|
|COPY||Allows you to copy information from memory to Datapak, Datapak to Datapak or Datapak to memory|
|RESET||Performs a 'cold' start and erase all data, erasing all information in the internal memory|
|OFF||For switching your Organiser off|
So much for the menu itself, but how do you make a selection from that menu? There are two methods. At the bottom right of the keyboard is a key labelled EXE (for execute). This is the key which is used to indicate to the Organiser that you have finished typing something, or that you wish to select an option presented to you.
To select an option from the menu, simply use the cursor keys to position the cursor over the start of the activity you wish to begin, and press EXE. The other method is to press the key corresponding to the first letter of the option required. For instance, press the T key to move the cursor to the TIME option in the menu. The Organiser will take you straight into the menu item you selected.
However, there may be more than one entry in the menu starting with the same letter. Each time that letter is pressed the cursor will move to the next word starting with that letter.
Pressing that letter again will return you to the first item, assuming of course, that there are no further entries starting with the same letter.
When the cursor is over the particular menu item that you want, press the EXE key and you will be taken into that menu option.
Select the TIME function from the menu as described in the Getting Started chapter, by pressing the T key or using the cursor keys to position the cursor over the first letter of TIME in the menu and then pressing the EXE key.
The date, day and time will be displayed on the screen in this format:
WED 1 JAN 1986 00:03:06
When the battery is first fitted, the time and date will be set to 00:00:00 on the 1st January 1986. To set the current time and date, press the MODE key, and the cursor will appear over the day of the month. To change this to the current date, press the UP cursor key and the figure will be incremented. Continue pressing UP until the correct day of the month is reached.
You will notice that the day of the week changes automatically whenever the date is changed.
To change the month, year and time, the LEFT and RIGHT cursor keys are used to position the cursor over the relevant part of the screen, and the UP and DOWN cursor keys used to increment and decrement that part of the time or date. The time is displayed in 24 hour format, including seconds, so for instance, 4.30 pm will be shown as 16:30:00.
After setting the correct time and date, press EXE to remove the cursor, and a press of ON/CLEAR will return you to the main menu. The time and date need only be set once, providing the battery is not removed from the Organiser for any considerable length of time.
Now that the time and date have been set on your Organiser, to check the time, or check the day of the month for instance, just select TIME from the menu in the usual way and the clock and calendar will be displayed. Just press ON/CLEAR to return to the main menu.
Select the OFF option from the main menu by pressing the O key or by using the cursor keys and the EXE key. The display will disappear and the machine is then off. Just press ON/CLEAR to switch it on again, and the Organiser will display the main menu ready for your selection.
If the Organiser is left on for five minutes without any keys being pressed, it will switch itself off to conserve battery power.
When this happens, don't worry! Even if you were half way through editing a record, or, even worse, entering a long record, your data is not lost. Just press ON/CLEAR once and the Organiser will reawaken at the exact place it was when it went to sleep. All of your data is intact and you can carry on where you left off.
One of the prime functions of the Organiser is its use for storing and retrieving large amounts of information in any format you require. This can be done either from the main menu, or from within a stored program. The latter is covered in Section Two, chapters 17 onwards, in a full description of the Organisers programming language, OPL.
Suppose you want to store important names, addresses and telephone numbers. One item or record might be:
Abraham Lincoln, President
The White House
If the main menu is not currently displayed, press ON/CLEAR once or twice until it is. Select SAVE from the menu, either by using the RIGHT cursor and the EXE key, or by pressing the S key. The screen will show:
You can now start to type in the information for Lincoln. As you type the first name, the letters will appear to the right of the SAVE A: message on the screen. If you type a name with more letters than will fit in the rest of that line, then the whole line will be scrolled to the left. leaving you enough room to complete the line.
SAVE A:Abraham Lin_
When you have typed in the full name and title, you may want to put the telephone number on a new line. To do this, press the DOWN cursor key. This will take the cursor down to the next line, and allow you to enter the number. By starting a new line you can lay out the information in the way that suits you best.
Another reason for dividing the information into a number of short lines rather than one long one is that when you retrieve the data later, two short lines can be seen at the same time, so in this case, Lincoln's name and number can be read at a glance.
This process is repeated until the last line of the address is typed in. If you are satisfied with what has been entered, press the EXE key and the information will be saved to memory. This item can then be found at anytime by using the FIND option (see below).
Sometimes you will want to edit the information before it is saved. This can be done by using the cursor keys and the DEL (delete) key.
NOTE: The DEL key deletes the character to the left of the cursor. By holding down the SHIFT key when the DEL is pressed, the character under the cursor is deleted, and the text to the right moves in to fill the gap.
If you wish to combine two lines into one longer line, you can easily pull the second line up to join the first. This is done by placing the cursor on the first character of the second line and pressing DEL once. However, the reverse is not true. You may not split one line into two separate lines, and you may not insert a new line into the middle of a record.
To delete the text on a line, press the ON/CLEAR key once when the cursor is on that line. Now if you press the ON/CLEAR again the whole of that part-finished record will be abandoned and you will return to the main menu.
When you have finished typing in your record and are happy that there are no errors or things you would like to alter, press the EXE key and the whole record will be saved to the memory of the Organiser, and you will be returned to the main menu.
If you wish to abandon a part-half finished record, and not save it to the Organiser's memory or a Datapak, you simply have to press the ON/CLEAR key. The screen will display the main menu, and the record will be discarded.
Each record may be up to 16 lines long and each whole record may contain up to 254 characters. Each line may contain any number of characters, subject of course to this overall limit.
If you have fitted a Datapak to your Organiser in one of the slots on the bottom of the casing, you will also be able to save the record to that Datapak. To do this, the MODE key is used to select the appropriate Datapak, either before, or at any time while entering the information.
For instance, when you have finished typing in the information to be contained in a record, but before you press the EXE key, press the MODE key, and the display will show which of the devices you are currently operating on.
The internal memory of the Organiser is treated in the same way as the Datapaks, if any are fitted, and is referred to as device A: (as opposed to the physical Datapaks, devices B: and C:.) This memory is always available, so you will always have at least one destination for your data. or source if you are trying to retrieve data. So if device A: is current. after you have typed in your information, the screen could look something like this:
SAVE A:Abraham L Tel 01-010-0000
Press the MODE key once, and assuming you have fitted a Datapak to one of the slots, the screen will then show:
SAVE B:Abraham L Tel 01-010-0000
Of course, if you have fitted the Datapak to the second (lower) slot, then the display will say C: instead of B:
If the main menu is not currently displayed, press ON/CLEAR once or twice until it is. Select FIND from the menu, either by using the RIGHT arrow key until the cursor is flashing on the F of FIND and pressing the EXE key, or by pressing the F key. The screen will clear, and then show:
To find any item, you need simply to type a three or four character 'search-clue'. For example, If you had previously saved the record for Lincoln and now want to retrieve it you would type LINC. The screen would then show:
Abraham Lincoln Tel 01-010-0000
The Organiser operates far more flexibly than a card index or telephone directory, because it will access the required information on any part of the text in the record. For example, the record on Abraham Lincoln would be found by typing any of the following search clues:
FIND A:LINC FIND A:PRES FIND A:ABR FIND A:WASH
In other words, you can access the whole record by just typing in part of his first name, last name, job title or any part of his address.
Pressing the DOWN cursor key a number of times will move the other lines of the record into view, one at a time, until the last line is reached. Occasionally, you may FIND a record which contains a line which has more than 16 characters, that is, more than the number of characters that can be displayed on one line of the screen.
When this happens, if the record has only one line, then it will automatically scroll from right to left. The line loops around to the beginning when it reaches the end so you see a continuous progression of its contents. By holding down the RIGHT cursor key, the scrolling will be speeded up, allowing you to scan to the end of the line rapidly.
If the record has two or more lines, then if any of the lines are more than 16 characters long, by using the UP and DOWN cursor keys, each of the lines can be examined, and any long lines will automatically scroll on the display. Normally long lines will scroll on the lower line of the display, except when the first line is long, in which case it scrolls on the upper line.
When a line is scrolling, the direction of movement can be altered by using the cursor keys. If the line is scrolling right to left, press the RIGHTLEFT cursor key once and the line will stop. Press it again and the line will start scrolling left to right. Use the LEFTRIGHT cursor key to reverse the process.
If the record that was found is not the one you are looking for, press EXE and the next matching record will be displayed in the same way.
If there are no records which match, or the last matching record has been displayed, the message:
**************** ** END OF PACK *
is shown. Press EXE again and the first matching record will be displayed once more. To return to the main menu, press ON/CLEAR once.
It doesn't matter if the stored record is all in capitals, and the string you type after the FIND message is all in lower case letters, or vice versa. Your records can be in any combination of upper and lower case letters, and they can still be easily found at a moment's notice.
So, the string ANN will successfully find Anne and Joanne
If you wish to browse through the stored records, select FIND from the main menu in the usual way, and press EXE without typing in any string. The first record in the main file will be displayed, and at each subsequent press of EXE successive records will be displayed.
After the last record has been displayed, the END OF PACK message is shown. Press the EXE key once more and you will return to the first matching record.
Again, to return to the main menu, just press the ON/CLEAR key once.
Records may at some time need to be altered. For example, if someone's telephone number or address changes and you want to update your Organiser record, then it can easily be done
When you FIND a record, it is displayed on the screen like this:
Abraham Lincoln Tel 01-010-0000
To edit it, just press the MODE key. The screen will now show:
SAVE A:Abraham L Tel 01-010-0000
Now by using the cursor keys to move around the record, and inserting or deleting text, you can alter the record to its new form. Any of the lines can be altered, and you can even add new lines onto the end of the record, although you will not be able to insert new lines between the old ones.
You may also delete the whole record at this point by just pressing the ON/CLEAR key. The whole record will disappear and the screen will show:
If you do this by accident when editing a long record, don't worry, you can retrieve the record as it was before you pressed the ON/CLEAR key by just pressing the ON/CLEAR key once more. You will be returned to the main menu, but your record will be intact and can be found again with the FIND facility. If, however, you really do want to delete the whole record, after pressing the ON/CLEAR key once, press the EXE key and the record will be erased.
Otherwise, when you have finished editing and are happy with the record, press the EXE key and the whole new record will be saved to the current device, the old record will be deleted and the Organiser will return you to the main menu.
If the edited record is saved to a different device to the one it was originally stored on, the old record will not be erased.
Occasionally you will need to erase one or more records from the MAIN within a file. To do this, select ERASE from the main menu in the usual way. The screen will display the message:
It you then press the EXE key, the first record in the current file will be found and displayed in full, and can be examined by using the cursor keys.
It you wish to erase the record which is currently displayed on the screen, press the DEL key. The top line of the screen will be unchanged, but the bottom line will show:
Pressing the Y key will erase the record and the next record will be displayed. If you do not wish to erase the record, press the N key and the next record will be displayed. You can step through successive records with repeated presses of the EXE key.
You may also specify a search string at the ERASE prompt, to erase just the records containing a certain string. If no record is found to have text which matches your search string, then the END OF PACK message will be displayed.
To return to the main menu, just press the ON/CLEAR key once.
There are two solid-state devices in the back of your Organiser (see chapter 1). When you first purchase your Organiser, these two devices will be fitted with covers to protect the electrical connections inside the machine. For the same reason, you should always keep a Datapak (or a program pack) or one of the protective covers in each device.
The Datapaks slide into and out of their devices, and have an easy grip outer surface. Try to avoid pressing any key while removing or fitting a Datapak. (This is easily avoided by placing the machine face down on a flat surface, as the keyboard is slightly recessed.)
Simply press down and out on the ribbed portion of a Datapak to slide it out of its device. To fit a Datapak, just push it into the required device until you feel it click home.
Use the white label on your Datapak to mark it for identification later.
Datapaks are available with capacities of approximately 8000, 16000, 32000 and 64000 characters (128000 on model XP) to suit whatever application you have in mind. You can keep a whole library of Datapaks, each catering for a different subject area. So for instance aAll of the names, addresses and telephone numbers you might ever need could comfortably be held in one Datapak (over 2000 entries of up to say 30 characters each in a 64K Datapak).
When a new Datapak is fitted to the Organiser, the first time you try to use it, the Organiser will detect that it is an unused Datapak, and the message:
SIZING PACK B: PLEASE WAIT
will be displayed. The Organiser is just checking the size of the new Datapak, and making sure that it is completely blank. After two or three seconds, the screen will clear and you will be able to continue with whichever operation you were carrying out, SAVE or FIND for instance. You can then either use the Datapak you have just sized, or select another one by pressing MODE until the device you wish to use is indicated in the display.
For example, after entering a record with the screen showing SAVE A:, you might wish to fit a new Datapak to device B: and save the record to that pack. Remove the device cover from the top slot on the back of the casing (device B:) and lit a new Datapak, the screen will show:
SAVE A:Abraham L Tel 01-010-0000
Press MODE once:
SIZING PACK B: PLEASE WAIT
There will be a short pause, and then the screen will show:
SAVE B:Abraham L Tel 01-010-0000
Pressing EXE will save the information in your record to whichever is the current Datapak as shown on the screen.
Any Datapak will only be sized once, so fitting one which has already been sized will mean that you can go right ahead and use that Datapak immediately.
Many of the activities available from the main menu, such as FIND and SAVE, can be performed on either the internal memory of the Organiser or one of the two Datapaks. They are referred to by the machine as device A:, B: and C: respectively.
The Organiser checks which devices have Datapaks fitted, and only offers these as options at the appropriate times.
Once you have used a particular device, the Organiser assumes you want to continue using the same one until you select another one.
If you do not have any Datapaks fitted, pressing the MODE key when trying to SAVE or FIND information will have no effect, device A: will remain current.
The built in memory of the Organiser differs in one or two ways from the Datapaks. The most obvious point is that the memory cannot be removed in the way that the Datapaks can. However, the second point is rather more important.
When you have stored a few records in the memory of the Organiser, (device A:), if you then ERASE any of these records, they are actually removed from memory, and the space thus freed can be filled with another record.
With Datapaks, this is not the case. Erasing a record from a Datapak is like crossing out a piece of written work in a book' it is still there, occupying space, but you can no longer read it.
The advantage with Datapaks is that you can have as many as you need to build up a library of information, with different datapaksa different Datapak for each subject. They are completely safe, easy to carry around and are not affected when the battery runs low on the Organiser and are easy to carry around.
With Datapaks, if you repeatedly save information and then erase it, you are using up storage capacity which will eventually come to an end. So it is obviously wise to keep unnecessary SAVEs and ERASEs to a minimum.
However, no matter how careful you are with a Datapak, at some point it will be filled. The next time you try to SAVE any information on that Datapak, the Organiser will display a PACK FULL message. Further attempts to save information on that Datapak will produce the same message.
Although Datapaks store your information permanently, it is possible to clear an entire Datapak using a process called formatting. This is achieved by controlled exposure to ultra-violet light in a purpose-built machine called the Psion formatter.
The reformatted Datapak will be completely blank, and when reinserted into the machine, will be seen as such, and re-sized as if it were brand new.
Note that the white label on the underside of each Datapak is to protect it from excessive exposure to light and must be removed before formatting can occur.
The problem of Datapak becoming full with information which. although 'erased', is still occupying space can be resolved by copying the rest of the information to another pack. During copying, the erased records and files are ignored, so just the good information will be copied across, then the old pack can be reformatted in the Psion Formatter, and it can then be used afresh.
The CALC option on the main menu is for performing arithmetic calculations of great sophistication if required. Select CALC from the menu by using the cursor keys and the EXE key, or by pressing the C key.
The screen will show:
The keyboard will be automatically in SHIFT mode so the numeric keys can be accessed immediately, without the use of the SHIFT key.
The basic arithmetic operators, +, -, / (divide), * (multiply) and ** (raising to a power) are used in the same way as they would be in a written calculation. For information on the precedence of these operators, see chapter 23.
You can now type in a calculation on the top line of the display, just as you would write it, for example, if you typed in:
and pressed the EXE key, the screen would show:
When the result is displayed on the bottom line of the display, the actual calculation string is displayed on the top line, if this string is longer than 16 characters it will be scrolled from right to left. Any number of levels of brackets may be used in the calculation.
Results are displayed with only the necessary number of significant figures by default (up to 12), By default, only the significant figures (up to 12) are displayed in the result, but this can be changed at any time when the CALC: prompt IS shown. Simply type in FIX=n where n is a number between 0 and 12. Results will then be displayed to that number of decimal places. To return to the default, type FIX= without a number.
So by typing FIX=3 at the CALC prompt, the calculation above would return the answer 3.111
Any number of levels of brackets may be used in the calculation.
In your calculations, you are able to use the mathematical functions which form part of the Organisers language OPL (see chapter 34). These enable you to perform far more operations than are available on an ordinary calculator. Here is an example:
Here the SIN, COS and PI functions are used, but any of the numeric functions can be used. When the EXE key is pressed, the result will be printed on the lower line of the screen with an equals sign. an equals sign will be printed on the lower line of the screen, followed by the result.
If there is an error in your calculation string, an error message will be displayed. To return to the place in the string where the error occurred, just press the SPACE key. The calculation will then be redisplayed with the cursor flashing on the first character which the calculator did not recognisewas not recognised.
For instance, if you included a character which did not signify a procedure on the current device and was not an arithmetic operator. like this:
then the cursor would be flashing on the P, as that is an illegal charactercharacter cannot be evaluated by the calculator.
Note. The percent key (%) does not operate as the percent key on ordinary calculators. This key simply produces the % character for use in the Organiser's programming language, OPL. To calculate percentages, they must be entered into the calculator in longhand form.
So to calculate 37 percent of 250, you must type in:
37/100*250, or .37*250 = 92.5
Built into the Organiser are ten memories which can be used either in the calculator or in OPL.
These can be used to store and retrieve numbers for use in calculations, they can be added to, subtracted from and cleared.
When numbers are stored to these from the calculator, they can then be accessed from the language and vice versa. It doesn't matter if the Organiser has been switched off between using one and the other, the memories are held until they are deliberately cleared or until the machine is reset with the RESETRESET with that option in the main menu.
In the calculator and OPL they are referred to by the same names, M0 to M9; lower or upper case letters may be used.
To store the result of a calculation to a memory, press the MODE key while the result is on screen. The top line of the display will then show:
M: PRESS 0-9
Now press one of the numeric keys, for instance 0, and the top line will show:
Now you have four choices:
|+||Add the current result to the memory selected|
|-||Subtract the current result from the memory selected|
|EXE||Store the current result to the memory selected, overwriting the current contents|
|DELETE||Set the contents of the memory to 0.0|
Press one of these keys to perform one of the operations listed above, or ON/CLEAR to return to the calculator with no change to any of the memories. The calculation will still be displayed on the top line and the result on the bottom line.
When a value has been stored to one of the memories, it may then be used in a calculation. For instance, the calculation string:
would add 2 and 3 and the contents of M0.
To find out the contents of a particular memory, type the name of that memory (M0 to M9) and press the EXE key and its contents will be displayed.
To edit your original calculation, perhaps to vary a parameter for a what-if calculation, just press one of the cursor keys, the DEL key or the EXE key.
If the EXE key is pressed, the result will disappear from the bottom line and you can edit the calculation. Pressing the LEFT or RIGHT cursor keys will erase the result and allow you to edit your calculation, but the cursor will have moved as if you had pressed the EXE key and that cursor key. So if the LEFT cursor key is pressed, the result will disappear and the cursor will now be moved one character from the end of the calculation.
If the DEL key is pressed, the result will disappear and the last character of the original calculation string will be erased. Further presses of the LEFT and RIGHT cursor keys will enable the calculation to be edited and then tried again.
If you decide to use the result from one calculation as part of another one then just press any other keyof the operator keys (+, -, *, /) and that result will be displayed on the top line and can be added to in order to form a new calculation.
At any time, you may clear the current calculation string and/or result by pressing the ON/CLEAR key. Press the same key again to return to the main menu.
You can even include programs which have been written in the Organiser's programming language and saved to the current device. Any procedure called in this way may need one or more parameters supplied in brackets, or will operate on one or more of the calculator memories and will return a value as would a numeric function.
If, on the current device, there is a program called FACT: which works out the factorial of a number passed to it, then you could include this as a part of a calculation string like this:
The value 3 is being passed to the program. The returned value is then added to 4 and the rest of the calculation performed on the result.
The expression inside the brackets is evaluated differently to the rest of the calculation as it is part of the parameter passing mechanism of the Organiser's language, OPL. If the expression contains only integers, even though the true result of the expression would be a floating point number, then the result passed to the routine will be an integer.
This means that the above calculation will pass the integer value 2 to the procedure proc:(INT(8/3)). This would produce an error in the final result.
To avoid this problem, if a procedure requires a floating point number, then the expression in brackets must be forced to produce a floating point result by the inclusion of a decimal point thus:
This would indicate to the Organiser that the result being passed was to be a floating point and the true result (2.666...) would be passed, ensuring a true final result.
Any procedure called from the calculator must return either a floating point number or an integer.
Any procedure called from the calculator which results in an error will be treated like this. First the usual message for the error in question is displayed on the top line. The bottom line shows the name of the procedure, so if a syntax error occurred in a procedure called COUNT:, the screen would show:
SYNTAX ERR IN COUNT:
Press the SPACE key to return to the calculation string.
From the calculator, parameters are passed as floating point numbers by default. To pass an integer to a procedure, you must use the INT function from OPL like this:
5/3 + proc:(INT(10))
One of the most useful standard applications in the Organiser is the DIARY, which is selected from the main menu in the usual way with the cursor keys and the EXE key, or by pressing the D key.
On entry to the diary, the screen will clear and then show the next diary slot from the current time and date. The diary slots are spaced 30 minutes apart. The display will be in this format:
The first time you view a slot there will be nothing entered for that date. so there is nothing to display on the bottom line.
The current diary date can be altered using the LEFT and RIGHT cursor keys. Press the RIGHT key once and the date will change to the 2nd January, further presses will run through the month, day by day, to step forwards through the month, one day at a time, until the end of the month is reached.
Hold any of the cursor keys down continuously and the key will auto-repeat, so you do not have to repeatedly press the key. If you press the RIGHT cursor key while the diary is displaying the entry for the last day of the month, then you will step to the first day of the next month. To flick back through the days of the month, use the LEFT cursor key. Also, on stepping forward from 31st December 1986, you will move to 1st January 1987 and vice versa.
To change the current diary time, i.e. the time slot that the diary is currently displaying, you use the UP and DOWN cursor keys. To move the time forward by a half hour, press the DOWN key, and to move back in time by half an hour, press the UP key.
Think of the diary as a large sheet of paper divided into window-sized boxes, rather like a year planner. The display screen acts like a window which can be moved across and up or down the sheet, viewing the contents of one box at a time.
This is known as PAGE mode and is the only mode in which the contents of the diary can be changed. You must be in this mode to enter and change any diary entry.
WED | THU | FRI ------------------+------------------+------------------ JAN:01:WED:08.00 | JAN:02:THU:08.00 | JAN:03:FRI:08.00 | | Cancel papers ------------------+------------------+------------------ JAN:01:WED:08.30 | JAN:02:THU:08.30 | JAN:03:FRI:08.30 | Pick up suit | ------------------+------------------+------------------ JAN:01:WED:09.00 | JAN:02:THU:09.00 | JAN:03:FRI:09.00 | | Pick up car ------------------+------------------+------------------ JAN:01:WED:09.30 | JAN:02:THU:09.30 | JAN:03:FRI:09.30 | (A)DENTIST | ------------------+------------------+------------------ JAN:01:WED:10.00 | JAN:02:THU:10.00 | JAN:03:FRI:10.00 | Call Maria | Heathrow Term 2
Figure 45 The Diary
As you step through the diary slots, there will be nothing displayed on the bottom line of the screen because you haven't entered anything into them yet. To make an entry, just start typing. The cursor will appear on the bottom line of the display with an EDIT: prompt and you can type your text as you would write in a normal diary. It you type more than sixteen characters, the text will scroll to the left as usual with long lines.
It is best to keep your diary entries short, because each one uses up valuable memory space, and longer entries must be scrolled on the screen to be seen in full. All diary entries may, however, be up to 64 characters long.
When you have typed in your entry, press the EXE key and the Organiser will ask whether you want to set an alarm to sound when that entry becomes due, like this:
JUN:30:MON:17.00 ALARM (Y/N)
If you don't want this diary entry to set off an alarm, press either the N or the ON/CLEAR key. If you do want an alarm to be sounded when the 'real' time reaches this diary entry, press the Y key. Pressing any other key will have no effect. The screen will now show:
JUN:30:MON:17.00 MINUTES : 15
You can now specify how many minutes before the actual time of the diary entry you want the alarm to go off. For instance, if you work right next to your dentist, say, then an alarm only five or ten minutes before the appointment might be enough warning to let you be there on time. But if you want a reminder to pick someone up from the airport, then a longer advance warning might be useful.
You can set the number of minutes to any figure between 0 and 59, so you can be prewarned of any of your diary appointments or reminders by up to one hour.
The Organiser suggests 15 minutes as the advance warning time, but this time can be changed. Press the DOWNUP cursor key to increase, or the UPDOWN cursor key to decrease the number of minutes. One press of either of these keys changes the number of minutes by one, and as with the time and date functions elsewhere on the Organiser, if you try to decrease the number of minutes when the number shown on the screen is 0, the display will return to 59 minutes and vice versa.
Having decided how many minutes advance warning of the diary entry you want, press the EXE key and the screen will now show the text on the bottom line, with an indicator that the alarm has been set, like this:
If the text is longer than one screen length then the alarm indicator will scroll around with the text.
If you set the current diary slot to a time and date which has passed then even if you enter data to that time slot, you will not be given the option of setting the alarm.
As the diary is divided into half hour segments, clearly it would be possible to make two advance warning alarms overlap. For instance, you could set an advance warning alarm to go off 45 minutes before a ten o'clock appointment, i.e. at 09.15. You could also set an alarm to go off say 15 minutes before a 09.30 appointment, again at 09.15.
In a case like this, the Organiser will sound the alarm from the first diary entry, followed by the alarm from the second one.
When an alarm becomes due, you will be warned by a sequence of beeps. Also, the date and time of the diary entry will appear on the top line of the screen and the actual diary entry on the bottom line. If the entry is longer than 16 characters, it will scroll across the screen.
The reminder will remain on the screen for one minute, at the end of which time, you will return to whatever operation you were carrying out before the alarm was sounded.
Alternatively, it you press the ON/CLEAR key before the minute has expired, you will go straight back to what you were doing beforeyour original task.
The other possibility is that the Organiser is switched off when an alarm becomes due. Fortunately, when the machine is switched off, it is still keeping an eye on things like the time, date and any alarms which have been set.
In the event that an alarm is due while the machine is off, the Organiser will firstfirst thing that happens is that the Organiser will switch itself on. Then the alarm process is just the same as above: there will be the audible alarm warning, the date and time 01 the diary entry will be shown on the top line of the display, and the entry itself will appear on the bottom line.
These will be displayed for one minute, and then the Organiser will return to whatever operation was being carried out when the machine was switched off. You may press the ON/CLEAR key at any time during that minute and the machine will return to where it was immediately. To switch the machine off, just press the O key as usual.
You could set an alarm to sound at a particular time, and then not have your Organiser with you when that time arrives. In this event, the alarm will sound as has been described, and then at the end of the one minute when the reminder is on screen, you will not be around to switch the machine off.
Nevertheless, after five minutes without any keys being pressed, the Organiser will automatically switch itself off.
After an alarm has been sounded and the reminder displayed on the screen, the diary entry will remain intact until you delete it, but the alarm indicator at the beginning of the entry (A) will disappear.
As the diary is divided into half hour segments, clearly it would be possible to make two advance warning alarms overlap. For instance, you could set an advance warning alarm to go off 45 minutes before a ten o'clock appointment, i.e. at 09.15. You could also set an alarm to go off say 15 minutes before a 09.30 appointment, again at 09.15.
In a case like this, the Organiser will sound the alarm from the first diary entry, followed by the alarm from the second one.
If you decide that you don't want the diary alarm for any entry to sound after all, you must first go back to that entry. Press the EXE key and the EDIT: prompt will appear in front of the text. Now if you press EXE again you will be offered the ALARM Y/N option. Press the N key and the alarm will be cancelled.
Before you go any further with how the diary works, press the MODE key to see the full range of options that are available within the diary. The screen will clear and then display a menu. This is not the original menu which contains FIND and SAVE and the DIARY itself, but a sub-menu. This is just a menu of options that are only relevant to the operation of the diary itself, and are not seen anywhere but inside the diary.
When the DIARY sub-menu is selected, the screen will look like this:
PAGE LIST FIND GOTO SAVE TIDY
There are more menu options than this, but the others can only be seen, like those in the main menu, by scanning the menu using the cursor keys. Here is the full range of options in the diary sub menu:
|PAGE||This is the mode you are in when you first enter the diary, which allows you to make your entries and set an alarm which will sound when the entry becomes due|
|LIST||Lists all of the diary entries sequentially from the current system time. Allows you to view all appointments and engagements simply and quickly|
|FIND||Just like the FIND option in the main menu, it will find any entry immediately given a three or four character search clue|
|GOTO||Allows you to GOTO any date|
|SAVE||To save the entire contents of your diary to a Datapak|
|TIDY||Lets you tidy up the diary by removing out of date entries, up to the current diary date and time|
|RESTORE||To restore the contents of the diary from a Datapak - overwrites the current diary contents|
|DIR||To read the directory of diaries on a Datapak|
|ERASE||To erase a diary from a Datapak|
Let's have a look at each of the choices on the menu in turn. The menu items are selected in exactly the same way as those in the main menu, by moving around the menu with the cursor keys followed by a press of the EXE key, or by pressing the first letter of the menu item you wish to select.
This is the selection which will take you back to the page of the diary which you just left. Try it. Just press the EXE key when the cursor is over the P of PAGE or press the P key and the original diary entry will be visible again.
Press the MODE key again and you will return to the diary menu.
The LIST function is selected from the diary menu in the usual way. The screen will clear and then display the first diary entry from the current diary time and date onwards. So it the current diary time and date is, say, 1st26th August at 0800, when LIST is selected, any diary entry you have made for any time after that will be displayed sequentially, but those entered in time/date slots which have already passed will not.
The first slot which contains any text will be displayed, with the date and time on the top line, and the entry on the bottom line. It the entry is longer than can be displayed on the screen then after a delay of two seconds it will be scrolled to the left so that the whole line can be seen.
If, when that diary entry was typed in, an alarm was set as a reminder. the text on the bottom line of the screen will be preceded by an indicator showing that the alarm is in fact set. It will look like this:
Press the EXE key again and the next diary entry will be displayed and so on.
When the last slot which contains an entry has been viewed, press the EXE key once more and an END OF DIARY message will be displayed. Press the EXE key again and you will return to the first diary entry.
The diary FIND function works in a slightly different way tothe same way as the main menu version of FIND. To locate a particular piece of text, select FIND from the diary menu in the usual way by pressing the F key or by using the cursor keys and then the EXE key.
The FIND facility in the diary works in just the same way as the main menu version, and any entry found can be edited by pressing the mode key to produce the EDIT prompt. Editing of the entry can then be carried out in the usual way.
The GOTO option is used to change the current diary date to some other date and/or year, and when selected from the diary menu in the usual way, the screen shows: the current date.
1986 OCT 10
Initially, the cursor flashes over the year, press the RIGHT cursor key to move the flashing cursor over to the month and again to move it to the day of the month. The LEFT cursor key will move the cursor back again. The year, month or day of the month can be advanced by pressing the UP cursor key or counted back by pressing the DOWN cursor key.
When you reach the exact date you wish to go to, press the EXE key to go to that diary slot.
As you make entries in the diary and they become outdated as the days go by, you will occasionally need to erase the diary entries that are now in the past. This can be done as often as you like, and has the advantage of freeing memory space on device A: which is otherwise being wasted by these outdated entries.
To do this, just select the TIDY option from the diary menu in the usual way.
The screen will clear and then show the time and date of the current entry, and prompt you to confirm that all diary entries up to, but not including, this date will be deleted, It will look like this:
JAN:02:THU:08.00 DELETE UPTO Y/N
AUG:09:THU:08.00 DELETE UPTO Y/N
If you now press the Y key, all diary entries before the current date ant time, but not including that entry, if indeed there is one, will be deleted and you will be returned to the diary menu.
If you decide not to delete all of these entries, press the N key and you will be returned to the diary menu and the diary entries will be left intact. Pressing any other key when the Y/N prompt is visible will have no effect.
The entire contents of the diary can be saved at any time to the internal memory of the Organiser or to a Datapak. To do this, select the SAVE option from the diary menu and the screen will show:
The MODE key may be used to select another device. When the required device is selected, type in a file name and press the EXE key. The contents of the diary will be saved to the current device under that name. These contents may then be loaded back into memory with the RESTORE option below.
A filename may be up to eight characters long. It must begin with an alphabetic character but the rest of the name may be numeric or alphabetic. If a file name does not adhere to these limits then an error will be reported.
When the contents of the diary have been saved to a device, that diary can be restored to its place in memory at a later date by using the RESTORE option.
Select the option from the diary menu in the usual way, and the top line at the screen will show:
The MODE key may be used to select another device. When the required device is selected, the file name the diary has been saved under may now be typed in. This diary will be retrieved from the current device and overlayed on top of the current diary contents, overwriting them. The display will then return to the diary menu.
When a number of different diaries have been saved, at some point you may need to see a directorythe names of all of the diaries on that device.
When the DIR option has been selected, the top line of the screen will show:
The MODE key may be used to select another device. When the required device is selected, press the EXE key and the name of the first diary saved on that device will be displayed on the top line of the screen. Successive presses of the EXE will show any other diaries saved on that device.
When the name of the last diary on the current device has been displayed, the usual end of pack message is given. Press the ON/CLEAR key to return to the diary menu.
To erase a saved diary from a device, the ERASE option is used from the diary menu. The option is selected in the usual manner, and the top line of the screen will show:
The MODE key may be used to select another device. When the required device is selected, the name of the saved diary may be typed in. That diary will be erased from the device and the screen will return to the diary menu.
If you decide that you don't want the diary alarm for any entry to sound after all, you must first go back to that entry in PAGE mode because the contents of the diary may only be changed in that mode. Press the EXE key and the EDIT: prompt will appear in front of the text. Now if you press EXE again you will be offered the ALARM Y/N option. Press the N key and the alarm will be cancelled.
Now press the MODE key to return to the sub menu or the ON/CLEAR key to return to the nain menu.
The ALARM option of the main menu allows up to eight individual alarms to be set to sound at any time of the day up to a week ahead. Each of the alarms may be set to repeat weekly, daily or hourly.
The ALARM option is selected from the main menu in the usual way, and initially, the screen will show:
1) FREE press EXE to set
The alarms are numbered 1 to 8, but may be set in any order to any time. Number 1 need not be set to sound before number 2 and so on. Press the UP or DOWN cursor keys to change the alarm number.
To set any alarm, as the screen suggests, press the EXE key. The screen will then show the alarm number and the current day of the week and time of day. Alarms can be set on any of the seven days. starting with the current one. This means that individual settings can be made for up to a week ahead.
The screen will show:
1) WED 00.00
1) WED 12.25
The cursor will flash over the day of the week. That day may be changed by pressing the DOWN cursor key. To move on to the hour and the minute, press the RIGHT and/or LEFT cursor keys.
The hour and the minute may then be changed in the same way as the day, by using the DOWNUP cursor key to go forwards and the UPDOWN cursor to go backwards.
When the required time has been set, press the EXE key and the cursor will disappear. To return to the main menu, press the ON/CLEAR key.
Alternatively, you may move on to the next alarm when one has been set by pressing the UPDOWN cursor key. This can then be set in exactly the same manner as the first.
Any alarm may be set to repeat on a weekly, daily or hourly basis. When the time of the alarm has been set as above, press the MODE key and an R will appear under the part of the time where the cursor is positioned.
You can now move the repeat marker to either the day, so that the alarm repeats every week on that day; the hour so it repeats every day at that hour, or the minute so it repeats every hour at that number of minutes.
To confirm the setting you have selected, press the EXE key.
You may now return to the main menu as above by pressing the ON/CLEAR key.
To cancel the repeat feature on any alarm, first select that alarm as described above, Press the EXE key and then press the MODE key. The R will be removed and the alarm will no longer repeat.
First select the alarm to be cancelled as described above. Press the DEL key and the alarm will be switched off. Press the ON/CLEAR key to return to the main menu.
The Organiser has a built in language called OPL (Organiser Programming Language) This programming language is ideally suited to fast, comprehensive and ideal for many applications, including the processing of data and the handling of data files like the one created from the main menu.
It has a full command set together with scientific and mathematical functions and comprehensive file handling facilities.
The language is described in full in Section 2 of this book, where a complete explanation of the structures and programming methods are given, along with a definition of all of the commands and functions available.
There is a chapter of example programs which are both useful in their own right and exhibit techniques which show the full potential of the language, apart from all of the examples which appear in the text to illustrate specific points.
OPL is a procedure based language. Any program may consist of a number of procedures. The first procedure may call another procedure which, in turn, may call another procedure and so on. There is no limit to the number of procedure calls you can design into your program.
Each procedure is broken down into a number of program lines which may contain one or more instructions to the Organiser. Lines with more than one instruction, multi-statement lines, have the individual statements separated by colons preceded by a space in the format:
instruction :instruction :instruction
One procedure may pass values down to the next, and procedures may also pass values back up to the procedure which called them.
The commands and functions which make up the language include database constructs and allow you to write programs which create and interrogate data files to a high degree of sophistication.
OPL is covered in some depth in the second section of this book, starting at chapter 17.
The INFO option on the main menu reports on the amount of storage space left in the internal memory of the Organiser and any Datapaks that may be currently in position on the devicesfitted.
Select INFO from the main menu by using the cursor keys and then the EXE key or by pressing the I key and then the EXE key.
The top line of the screen will show the number of free bytes (one byte stores one character) in the internal memory of the Organiser. The bottom line will show a scrolling display of the amounts of storage space used in terms of percentages of the total available.
The Organiser has 8192 bytes of internal memorymodel XP has 16384 bytes of internal memory (8192 in model CM), or RAM (Random Access Memory) but a small amount of this is used up by the machine for internal 'housekeeping' purposes.
If you have a Datapak fitted in B:, a number of diary entries and some data stored in both devices, the bottom line will show something like this:
DIARY 4% PACK A: 15% PACK B: 36% FREE 81%
The amounts of storage spaced occupied are 4% of RAM for the diary: 15% of RAM on pack A: data and 36% on pack B: data. This leaves a total of 81% of the RAM free, as shown by the last part of the line.
This display scrolls around continuously until the key ON/CLEAR is pressed.
The active diary is always resident in the internal memory of the Organiser, it never takes up room on your datapaks, but this does mean unlike SAVEd diaries which may be stored on Datapak. This means that it you make extensive use of the diary facility, the memory you have in device A: for other activities will decrease accordingly.
Also, ifIf at any stage a new Datapak which has not been initialised by the machine is found in one of the devices, the Organiser will initialise it straight away without being told to do so.
The COPY facility in the main menu, is for copying data files from one device to another. Information can be copied from the internal memory of the Organiser to one of the Datapaks, or vice versa, or from one Datapak to another. To copy programs written in the Organisers programming language, OPL, see the COPY facility in chapter 31.
Select COPY from the main menu in the usual way, by using the cursor keys or by pressing the C key until the cursor rests on the first letter of COPY. When you press the EXE key, the screen will prompt you, on the top line of the display, with the message:
At this point, you should type in a device name (i.e. A:, B: or C:) and you may also type in a filename. This is the source device and file.
After typing the device and filename, the screen will prompt you tor a destination device and tile name, on the bottom line of the display:
You must now specify a destination device, and again, you may specify a file name.
At the FROM prompt, if you specify a device name without a file name, the whole contents of then all data files on that device will be copied to the destination. The information is copied across, file by file. If there is already a file on the destination device, with the same name as the one being copied across, then all of the records being copied are added onto the end of that file on the destination device.
So for example, if your MAIN file on device A: contains ten records. and you choose to copy all of the files from A: to B:, then the records in A:MAIN will be added to those already in the file B:MAIN. Each file on the source device will be treated in the same way.
Note. The file with the name MAIN is automatically created by the Organiser when you use the top-level SAVE option. It is interrogated with the top-level FIND option.
If there are files on the source device which do not have a corresponding file on the destination device, then a new file is created with that name on the destination device.
If, at the FROM prompt you also type a file name in addition to the device name, then just the contents of that file will be copied to the destination. When copying just one file, it you supply a tile name at the TO prompt, then the records will be copied into that file name on the destination device.
If that file already exists on the destination device, then the records will be added on to the end of the file. If there is no file on the destination with that name, then a new file is created and the records written to it.
The copying process may take several minutes if a very large amount of information is being copied. The time taken will depend upon the number and size of the records in the source file(s).
This option enables you to erase all information in the internal memory of the Organiser, efficyively performing a 'cold start'.
This option enables you to erase all information in the internal memory of the Organiser. All diary entries are lost, along with any files or procedures saved on device A:. Data saved to Datapaks is quite safe and will not be endangered by this option.
Select RESET from the main menu and the screen will show:
ALL DATA WILL BE LOST - PRESS DEL
If you do not want to reset the machine, press the ON/CLEAR key and you will be returned to the main menu and all data will be intact. Otherwise press the DEL key and the screen will show:
ARE YOU SURE PRESS Y/N
Press the N key and you will be returned to the main menu and all data will still be intact. If you are sure you want to erase all data in the machine, press the Y key. You will then return to the main menu.
When you are entering information with the SAVE facility, think about finding it and structure it to give maximum retrieval efficiency. Points to remember:
FIND SAVE DIARY CALC PROG ERASE
When you first switch on your Organiser, the menu options available will bewill appear as shown above. This is known as the default menu. You may, however, change the order the items appear in the menu, or even erase them altogether.
The only menu item that cannot be removed is OFF, and this is always the last item in the menu. The Organiser will not allow you to put anything after OFF in the menu.
If you delete one of the resident functions from the menu, such as FIND or SAVE, you can always put it back again at a later date. But you don't have to put the item back in the same place that it came from. This allows you to rearrange your menu into the order which suits you best.
For instance, if your chief use of the Organiser will be as a diary, then it makes sense to put the DIARY function in the first position on the menu, where it can be accessed most easily alter switching your Organiser on.
To remove an item from the menu, just place the cursor over the first letter of that entry in the usual way, and press the DEL key. So if, for instance, you want to remove FIND from the menu, place the cursor over that menu item, press the DEL key and the screen will show:
FIND DELETE (Y/N)
The top line shows the menu item to be deleted, and the bottom line prompts you to confirm that this item is to be deleted.
You now have the chance to change your mind. Press the N key and you will return to the main menu without making any deletion. However, just press the Y key and the menu will reappear without the FIND option being seen.
That option is not lost forever though. If you now insert an item called FIND in the menu, the Organiser will realise that you mean the default function of that name, even though it might now be at a different place in the menu. So when you select that option, you will enter the usual FIND facility.
This means though, that even though you delete one of the default menu items from the menu, you cannot giveinsert one of your own procedures that name at this levelwith the same name, you will just end up with the original facility offered under that name.
Similarly, if you try to insert a menu item under a name which already exists in the menu, then the Organiser will not let you.
Note. When using the Organisers built in programming language, you are able to give your procedures names which already appear in the default menu, but these will not be either visible or available from the main menu. A full description of procedures and the Organisers programming language can be found in Section Twochapters 17 onwards.
To replace a deleted menu item, either at the same place as before or in another position, first place the cursor at the position in the menu you want the item to appear.
If you now press the MODE key, the screen will show:
You can then type the name of your insertion, and press the EXE key. The new item will then appear at that position in the menu, pushing the following items one position to the right.
So it you have deleted FIND from the its position at the top of the menu and reinserted it further down, the Organiser will realise that this 'new' item is really one of the resident functions, and it can now be used from its new position.
Your Organiser is a very powerful computer, and like all computers, it relies on sets of instructions to make it work.
The language OPL (Organiser Programming Language) is available from the main menu under the option PROG. It allows you to write, edit, save, run and copy programs, using a full and flexible command set.
The instructions you give to the computer are in the form of a list of statements and commands. These are all part of what is called the computer's programming language.
What makes a computer really useful is not just its ability to follow a set of instructions, but its ability to store that set of instructions and re-use it at a later date.
An OPL program consists of one or more procedures, or program segments. Each procedure must be given a unique name so that you can save, recall, run and edit it.
A simple program may consist of a single procedure. More complex programs will normally be composed of several procedures, one of which will be the main or top level procedure.
The main procedure controls the use of others, calling them when they are needed to do their particular task. Procedures can also be used like numeric functions from the CALC option of the main menu.
The most effective way of using OPL is to write short procedures which can be tested individually. Then, when they are fully operational, they can be used together to form the complete program.
Each procedure can be as long or short as necessary, and should ideally perform just one specific task. That way, programs which have similar requirements can share one common procedure to do the same job. This avoids duplicating code to do similar jobs in two different places.
Throughout this section of the manual, references will be made to programs made up from a number of procedures, but all points are equally applicable to programs which are self contained, and comprise just one procedure.
When you select PROG from the main Organiser menu, you are presented with another menu which contains the following items
EDIT / LIST / DIR / NEW / RUN / ERASE / COPY
These options can be selected in the same way as the items on the main menu, by pressing the initial letter of the selection required, or by use of the cursor keys and the EXE key.
|EDIT||Enables any existing procedure to be altered and re-saved in its new form, allowing improvements and changes to be made as well as corrections to faulty, or 'bugged', procedures|
|LIST||Allows any existing procedure to be listed to a peripheral such as a printer|
|DIR||Displays a list of all procedures on any of the available devices|
|NEW||Allows new procedures to be typed in and saved to either the internal memory of the Organiser or to one of the Datapak devices|
|RUN||Executes any existing procedure|
|ERASE||Erases a procedure from any device|
|COPY||Copies a procedure, or all procedures, to another device|
Here is a simple example of a procedure
now: CLS PRINT "IT IS NOW",HOUR;":";MINUTE GET
The procedures name is now:. It clears the Organisers display and prints the current time in hours and minutes. The time remains on the display until you press a key. This chapter shows you how to type this procedure into the Organiser and how to save and use it.
Select the NEW option from the menu and the screen will show:
The device name follows the word NEW, in this case it is device A:. Although device A: (internal memory) is referred to throughout this section, the description applies to the other (Datapak) devices. (Remember that you press the MODE key to change devices.)
The first thing needed is the name for the new procedure. This can be up to eight characters long and must start with a letter. The remaining characters may be letters or digits. Type in the name now as the name for your first procedure. When you press EXE, the procedure name will be shown on the top line of the screen, with a colon at the end of the name. The cursor will now be flashing at the end of the procedure name:
Press the EXE key to move the cursor down to the next line and you can begin typing commands. (The cursor is initially positioned at the end of the procedure name for a reason which will be explained later.)
At the end of each line, press the EXE key to indicate that the line is finished.
Start with the command CLS. This is an instruction to OPL to clear the display screen of all characters. When you have typed CLS and pressed the EXE key, the lines of text will scroll upwards on the display, leaving the cursor on a blank line ready for the next command.
Now carefully type the line:
PRINT "IT IS NOW",HOUR;":";MINUTE
Make sure that the line appears on the screen exactly as it does here. All computer languages are very particular about how you give them commands and even the spaces between parts of a command can be as important as the command itself. The line is more than 16 characters long, so it will scroll to the left as you continue typing beyond the width of the screen, enabling you to finish the line.
Let's look at that line and see just what it does. The first part, the instruction PRINT, indicates to OPL that you are about to supply something which you want to be shown on the display screen.
This is followed by a space, and then a piece of text which has been enclosed in quotation marks. These indicate the exact size and content of the text to be printed.
In computer terminology, any list of characters like this is called a string. Any such string given between quotation marks will be printed out exactly as it appears.
The next character, a comma, indicates to OPL that anything else which is to be displayed on the screen will follow on the same line as the existing text, separated from it by a space.
The next part of the line, HOUR, is a function. Exactly what functions are and how they are used will be covered in a later chapter. For now it is enough to say that this function will result in the current hour from the system clock being printed on the screen.
The next character in the line, a semi-colon, means that any text following must be placed immediately alter the previous printed item, with no separating space. The next item to be printed is another string. This time the string is just one character, a colon, but it must still be enclosed in quotation marks, and will appear on the screen after the current hour.
The final part of the line is another function, MINUTE. This allows you to access the current number of minutes from the system clock. It too will be printed out on the same line of the screen, completing the current time.
The next line, GET, is another function which, in this case, waits for any key to be pressed on the keyboard. When a key is pressed, the Organiser will continue executing the rest of the program. This means that the message which you printed to the screen will remain there until you press a key. The rest of the procedure will not be executed until this happens.
In this example, there are no further instructions so the program ends.
At anytime in the typing in of a procedure you can go back and make an alteration to a line by using the cursor keys. Just press the UP cursor key to move back up to a previous line. The line can then be edited in the usual way.
Should you need to insert a new line in between two existing lines, just position the cursor on the start of the line where you want to insert a new one, then press EXE.
When a procedure has been typed into the Organiser, it is held in the internal memory of the machine in exactly the form that it was typed. There are then three options:
TRANslate the procedure into a form which OPL can execute;
SAVE the procedure as it is to any of the devices or
QUIT and abandon the procedure which has just been typed in.
Press the MODE key to select a menu of these options. The screen will clear, then display:
TRAN SAVE QUIT
This is a sub-menu just like the PROG menu, and a selection can be made from it in the usual way. The difference is that after the choice has been carried out, you are returned to the PROG menu.
When the QUIT option is selected after typing in a NEW program, you will be prompted with the message
ARE YOU SURE Y/N
If you press the Y key, the whole text of the procedure typed in so far will be discarded. Any procedures previously typed in and either saved or translated (see below) are quite safe, if you press the N key, you will be returned to the editor and will be able to continue editing the procedure.
Note. Once a procedure has been abandoned with QUIT, there is no way to retrieve it again, so make sure that this is what you intend.
When you have typed in the above example, select the TRAN option from the TRAN/SAVE/QUIT menu. The procedure will be translated internally into a form that OPL will be able to execute. This process only takes a few seconds, during which, a message will be displayed on the screen indicating that translation is in progress.
When the procedure has been translated, the screen will show the prompt SAVE A: followed by the procedure name like this:
You may now save the procedure to any device available (internal memory or a Datapak). Press the MODE key to change devices then press the EXE key to save the procedure.
When the translatednew procedure has been saved to the current deviceone of the devices, the original text is also saved. This means that there is now a version of the program which can be executed directly, and a version which can be edited. These are both stored under the same procedure name, and at this level can be thought of as a single entity.
If you have made a typing error while typing in the procedure, when it is translated OPL will probably spot it. If, for example, you typed the word PRONT instead of PRINT, or left out one of the sets of quotation marks around the piece of text alter the PRINT command, then OPL would pick it up. However, if your procedure contains logical errors then these will not arise until the procedure is run. It is your responsibility to ensure that there are no logical errors in your procedures.
When this happensan error in a procedure is detected during the translation process, you will be returned to the text of the procedure, and the cursor will be positioned in the line which caused the error, near to the first character which was not allowed.
You can then edit the line in the usual way until it reads correctly and will be accepted by OPL. Having done this, press the MODE key to return to the TRAN/SAVE/QUIT menu and select TRAN again.
This time, if OPL detects no other errors, the translation will be successful and you will be shown the SAVE prompt - see below. return to the PROG menu. The translated version of the procedure will now be saved to the current device as will the original 'plain-text' version.
If you have typed in part of a procedure and intend to return to it later to complete it or make alterations, you should use the SAVE option from the TRAN/SAVE/QUIT menu.
This allows you to save the text of the procedure, just as it was typed in and not waste memory by producing an unnecessary translated version.
Figure 5 The following diagram shows the difference between TRAN and SAVE.
Figure 6 TRAN, SAVE and QUIT
When a procedure is saved rather than translated, no form of error checking is carried out. The text is saved exactly as it was typed in and will only be checked for errors in syntax when it is translated.
Note. Saving procedures to Datapaks, like saving records from the main menu, takes up space which can only be recovered when the Datapak is reformatted in the Psion Formatter. The most economical way of using the Datapaks is therefore to develop a program using the internal memory of the Organiser, device A:. Then if a procedure takes a couple of versions before it runs exactly as you require, each edit will not be using up Datapak space.
Figure 5 TRAN, SAVE
When an edit is carried out on device A:a procedure stored on device A: is edited, each time the new version is saved or translated, the old one is erased completely. On Datapaks, the old versions remain in place but they are no longer accessible - they just take up storage space.
When a bug-free version of a procedure has been produced, it can be copied onto a Datapak with the COPY option in the PROG menu. See chapter 31.
The EDIT option from the PROG menu allows you, for example, to return to a half-written procedure to complete it. When selected from the menu, the screen shows:
Type in the name of the procedure you want to edit and press EXE. You will be returned to the procedure and can add or delete lines or make alterations to the text.
When the procedure is complete you can use the TRAN option from the TRAN/SAVE/QUIT menu to translate it, as described earlier.
Once a procedure has been successfully translated you can then RUN it. In other words, you can tell OPL that you want it to execute that particular set of instructions.
When the RUN option is selected from the PROG menu, the screen shows:
You can now type in the name of an existing procedure on that device. To continue the example from chapter 18, type in the name now and press EXE.
The screen will clear and show something like this, depending on the current time:
IT IS NOW 16:35
OPL will then execute the next line of the procedure, namely, GET. This instruction simply waits until any key is pressed on the keyboard. The actual key pressed is unimportant, it will not be remembered or recorded in any way. This instruction just gives you the chance to read the screen and decide when you want to continue.
When you press a key, OPL detects that the procedure has ended and the Organiser will return to the PROG menu.
That was quite a simple example for your first procedure, and the examples in chapter 32 will be rather more complex. However, they will be taken a step at a time and will enable you to learn about all of the facilities offered by OPL, and how to make the most of your Organiser.
A variable is a named region of memory in which your program can store either a number or a piece of text. For example, you could say, rather like in algebra, that X=10. In this statement, X is a numeric variable.
The program stores the value 10 in the region of memory referred to by the name X. Later on in the program you could change the value of X by saying X=X-1. In algebra, that statement would not make sense, because no number can equal the same number minus one. However, many computer languages have a different interpretation of the equals sign, including OPL.
The equals sign means becomes equal to, so the left hand side of the equation becomes equal to the right hand side. So X=X-1 means let X become equal to the original value of X, minus 1.
Variable names may be up to eight alphanumeric characters long, beginning with a letter. This allows you to use meaningful variable names, such as age or price. They may also contain numbers, so a1 for example is quite valid, but the first character must be alphabetic.
Before you go on to look more closely at variables and what they can do for you, you need to know how to inform OPL that you are going to use them. All variables must be declared before they are used.
Here is a very simple procedure:
procname: GLOBAL a,b,c a=1.2 b=2.7 c=3 PRINT a+b+c GET
The first program line of this procedure contains the command GLOBAL. It declares the variables which will be used in this program. Every variable that you use in our programs occupies memory space. To let OPL know just how much storage space to allocate, you must declare all of the variables you are going to use, right at the start of the program or procedure. More will be said on this topic later on.
The next three lines of the procedure define values which will be assigned to the variables a, b and c. Notice that the first two numbers, those assigned to a and b, have decimal points. They are floating point numbers. All floating point numbers are stored to an accuracy of 12 digits and must lie in the range plus or minus 1E100 (inclusive).
The last line of the procedure adds the values of the three variables and prints the result to the screen. In this case the result is 6.9.
OPL supports two types of numeric variables, integer and floating point variables. An integer is a whole number such as 10 or 537, and, unlike a floating point number, does not have a decimal point.
Using integer variables wherever possible allows programs to execute many times faster than if floating point variables are used. This is a great benefit, provided the 12 digit accuracy of floating point variables is not required. Integer variables also occupy less memory than floating point variables, needing two bytes of memory compared to eight bytes for a floating point number. Integer variable names end with a percent sign (%) while floating point variable names do not. The name must not be more than eight characters long including the percent sign.
In the example above, variable names a, b and c were used. If the numbers to be assigned to them had been integers, the variable names would have been a%, b% and c%.
Integers are dealt with by OPL much more quickly than floating point numbers, which means your programs weill run more quickly if integer variables are used.
OPL will only accept numbers as being integers if they are in the range -32768 to +32767. Any number outside this range will automatically be treated as a floating point number.
A procedure using integers and integer variables might look like this:
procname: GLOBAL x%,y% x%-7 y%=3.5+x% PRINT y% GET
This procedure follows the same format as the last one.
There is a potential mistake in the procedure: the variable y% is an integer variable, but in the third program line it is assigned a floating point value. In this case OPL will not report an error, instead an automatic type conversion is carried out internally on the value assigned to that variable.
The right hand side of the assignment is evaluated to 10.5, but the fractional part of the number is dropped before the result is assigned to y%. The PRINT statement will therefore display the value 10.
Since OPL does not report this as an error, the onus is on you to ensure that it does not happen - unless you want it to! You must always take care when mixing variable types that the answer produced is the one which you expect.
Now if you look back to the previous example where only floating point variables were used, you can see that another type conversion was made there, but did not cause the value to change.
In that procedure, the floating point variable c is given the integer value 3. An automatic type conversion is carried out on such assignments, and in this case the result was 3.0, so the real value of the variable remained the same.
If you assign a floating point number to an integer variable, then the integer assigned will be rounded down. So if you say, a%=2.3 then the value of a% will be 2. If you assign a negative floating point number to an integer variable, then the number is still rounded down (rather than toward zero). So if you say a%=-2.3 then a% will take the value -3. In all cases the programmer is in ultimate control so it is his responsibility to ensure that the correct type of variable is used in every case.
If you expect an expression to return a floating point number, you must ensure that the correct types of number are used within that expression.
For example, if you wanted to round floating point numbers to the nearest half, so, for example, 2.4 rounds to 2.5 and 22 rounds to 2, then you might try the following statement:
where n is the number to be rounded.
This, however, would produce the wrong result. To see why, substitute a trial value, say 3.4, for the value of n. The expression becomes INT(2*3.4+0.5), i.e. INT(7.3), returning the integer 7. This is divided by 2, another integer, so the result will be the integer 3, not 3.5. To obtain the required value of 3.5 you must force the division to give a floating point result. In this case the simplest way to do this is to divide by the floating point value of 2.0, instead of the integer 2. So the expression:
will give the required result.
Other errors are possible through careless assignment of variables, but these can be avoided through knowing a little of how OPL deals with arithmetic expressions (see chapter 23).
Note. There are ten floating point variables which are always available. These are the calculator memories m0, m1, m2..., m9. You need not declare these as variables, as they are always in existence (If you do declare them, an error will be reported). Values may be assigned to these at any time in any procedure. They also retain the values assigned to them when you leave OPL. They may then be accessed from the calculator by the same names, and will have the values last assigned to them in the language.
A string is just a sequence of characters which will be treated literally. Strings have quotation marks at the start and end like this:
"this is a string"
You can also store strings in variables, but you must differentiate between string and numeric variables. String variable names must end with a dollar sign ($) and may be up to eight characters long including the dollar sign.
Strings may be up to 255 characters long, but you may assign a null string, i.e., a string containing no characters, to a variable.
When you declare a string variable you must specify exactly how much room to set aside for its storage. Here is an example:
procname: GLOBAL this$(10),that$(4) this$="Alphabetic" that$="ally" PRINT this$;that$ GET
The string variable this$ will be allocated room for ten characters, and that$ will be allocated room for just four. The declaration of a string variable automatically assigns a null string to the variable.
The next two program lines assign values to the two variables. In each case the maximum possible length has been used, but this is not obligatory. You may assign any length up to, and including, the length stated in the declaration. If you try to assign to a variable any string longer than has been allowed for, then OPL will display an error message.
If you try to allocate a number to a string variable an error will be reported. There is no automatic type conversion between string and numeric variables. However, OPL does have facilities for forcing conversion of numbers to strings and vice versa, in the form of the SCI$, FIX$, GEN$ and NUM$ functions (see chapter 34).
Adding two numeric variables is very simple. You just use a plus sign and assign the result to another variable, e.g., a=b+c. Adding strings together, or to use the correct term, concatenating strings, is just as simple. If a$ is "DOWN" and b$ is "WIND", then the statement c$=a$+b$ will mean that c$ becomes "DOWNWIND". You can also assign this value to c$ with c$="DOWN"+"WIND".
It must be remembered, when concatenating strings that the maximum length of a string must not be exceeded, i.e., trying to join a string which is 200 characters long to another which is 100 characters long would generate an error. This is because the 255 character maximum has been passed. Also you must not exceed the maximum declared length of any string.
If you need to define a string which includes the quotation mark character (ASCII character 34) then this character must be included twice in the string definition. So if you say a$="ABC""DEF""GHI" then the resulting value of a$ will be ABC"DEF"GHI.
Having combined two or more strings, you may later want to split them up again, or you may want to just take, say, the first five characters of a string. This process is known as string slicing.
There are three functions which allow you to do this. They are LEFT$, RIGHT$ and MID$. These allow you to access the left, right or middle portions of a string respectively.
If, for example, a$="ABRAHAM", then by giving the instruction b$=LEFT$(a$,4), you are assigning to the variable b$ the string "ABRA", i.e., the first four characters of a$.
The RIGHT$ function works in a similar fashion. The MID$ function is a little different in that you must supply the string to be sliced, the start position of your sub-string and the length of the string you wish to be returned.
So assuming a$ still equals "ABRAHAM", the instruction b$=MID$(a$,4,3) will return the value of b$ as "AHA". This is because you have taken the 3 characters starting at character 4 of a$.
All string slicing operations leave the original string unchanged, unless the left hand side of the equation is the same string as appears in the right hand side. So a$=LEFT$(a$,4) would return a string containing the leftmost four characters of a$ and assign it to a$, thus overwriting the original value.
Sometimes it is useful to arrange variables together into related groups, so OPL allows another type, called array variables. These fall into two types, numeric arrays and string arrays.
Several numbers may be stored under the same name, differentiated by a numerical index. These variables may be integer or floating point.
They look like this:
Numeric array variables may be thought of as a list of numbers, each with the same name, but with a unique number to differentiate it from its neighbours. So you might have an array of integers with the variable name num%, with five values, numbered, not surprisingly, 1 to 5.
When the array is declared, the number in the brackets denotes the number of elements in the array. Here is a simple procedure which assigns values to the elements of an integer array:
procname: LOCAL num%(5) num%(1)=1 num%(2)=3 num%(3)=5 num%(4)=7 num%(5)=11 PRINT num%(1)+num%(2)+num%(3)+num%(4)+num%(5) GET
This is a very crude way of finding the sum of the five elements in the array, but it does show how the elements of the array are used. Floating point arrays are used in exactly the same way except the percent sign is omitted from the variable name.
You have seen how numeric variables may be grouped into arrays, the same thing is possible with string variables.
The difference is that with strings, you must declare not just the number of elements in the array, but also what the maximum length of each stringa string is to be, just as you do when you declare the length of an ordinary string variable.
This is done when the arrays are declared, so the instruction:
would allocate room for five strings in the array array$, each up to ten characters in length. The, as yet, empty array can be thought of as a table like this:
array$(1)="" array$(2)="" array$(3)="" array$(4)="" array$(5)=""
Even though at this stage, no text has been assigned to each of the elements of the array, enough memory still has to be set aside to contain all of the five strings when full. Until any element has some text assigned to it, it will just contain a null string.
So far, the example procedures have only used one arithmetic operator; plus (+). There are, of course, more than just this one available in OPL, and the full range is shown below. They are divided into three classes; arithmetic, comparison and logical:
|>=||greater than or equal to|
|<=||less than or equal to|
|<>||not equal to|
The various operators have differing precedence when they are encountered by OPL. The operators are shown here in order of precedence, with operators of equal precedence on the same line.
|NOT, Unary minus||[HIGHEST]|
|=, >, <, <>, >=, <=|
(The logical operators AND, NOT and OR are covered in greater depth later in this chapter.)
An arithmetic expression such as a+b+c presents no problems because whichever addition is done first, the result will be the same. But in the expression a+b*c the result will be different depending on which operation is done first, either the addition or the multiplication.
So for example, add and subtract have equal precedence, and in turn have a lower precedence than multiply and divide. So an expression such as:
would be evaluated in the order: b*c divided by d, the result of which would then be added to a.
If you want to change the order of precedence of the operators, you can do so by the use of brackets. Any operation in a pair of brackets has a higher precedence than one outside. So, using the equation above, to perform the addition first, followed by the division and then the multiplication, you would write the equation like this:
In an expression where all of the operators have equal precedence, they are evaluated from left to right, except in the case of powers which are evaluated right to left. So for example, in the expression:
b% will first be raised to the power of c% and the resulting value will be used as the power of a%.
This is fairly complicated, but there is a simple way to proceed. If you are not sure of the precedence of one operator over another, use brackets! They force the expression inside them to be evaluated first.
Although OPL distinguishes between integer and floating point values, you are free to mix them in any order in an expression. You should, however, be aware of how OPL handles such a mixture.
For example, your procedure may include the expression:
This mixture of variable types would be evaluated like this: Floating point numbers take priority over integers, so on the right hand side of the equation the value of b% will be converted to floating point before the addition is performed. The resulting floating point value will then automatically be converted to an integer before being assigned to the variable a%. Any fractional part of the result of the right hand side of the expression will be lost in the conversion to an integer.
If the value of variable a is less than or equal to the value of b then the statement:
will print zero. If a is greater than b it will print minus one.
In this example a>b is evaluated as a logical expression. The result has one of only two possible values, depending on whether or not a and b are equalis greater than b.
All logical expressions represent some type of condition. They evaluate to either zero, if the condition is false, or a non-zero value (usually minus one) if the condition is true.
When a logical value is expected, OPL will accept zero to mean false, and any non-zero result to mean true. For example, the two expressions:
a<>0 and a
are equivalent. They will both be interpreted as logically true values if a is non-zero.
The comparison operators in OPL always give an integer result. They are listed in the following table. They may be used either with string values or with any mixture of integer and floating point values. Their effects are summarised in the following table.
|<||a%<b||-1||(true) if a% less than b|
|>||a%>b%||-1||(true) if a% greater than b%|
|<=||a<=b||-1||(true) if a less than or equal to b|
|>=||a>=b%||-1||(true) if a greater than or equal to b%|
|<>||a$<>b$||-1||(true) if a$ not equal to b$|
|=||a=b||-1||(true) if a equal to b|
OPL will report an error if you attempt to use any of these operators with a mixture of string and numeric values, for example:
The operators AND, OR and NOT are logical operators, and may only be used to operate on numeric values. AND and OR combine two values to give a single result, whereas NOT acts on a single value. These three operators have different effects, depending on whether they are used with integer or with floating point numbers.
When used with floating point values, they interpret any non-zero value as being true, in a similar way to the comparison operators. Their actions are as described in the following table.
|AND||a AND b||-1||(true) if both a and b are non-zero|
|OR||a OR b||-1||(true) if either a or b is non-zero|
|NOT||NOT a||-1||(true) if a is zero (reverses value)|
When used with integer values, AND, OR and NOT are bitwise logical operators. For example, the statement:
PRINT 12 AND 10
will print the value 8. To understand this it is necessary to write down the two integers in binary notation.
The AND operator acts separately on each pair of corresponding binary digits in the two numbers. Thus, working from left to right:
|1 AND 1||→ 1|
|1 AND 0||→ 0|
|0 AND 1||→ 0|
|0 AND 0||→ 0|
The result is therefore the binary number 1000, or 8 in decimal notation.
What result would the statement:
PRINT 12 OR 10
Again, write down the numbers in binary notation and apply the operator to each corresponding pair of digits:
|1 OR 1||→ 1|
|1 OR 0||→ 1|
|0 OR 1||→ 1|
|0 OR 0||→ 0|
The result is the binary number 1110, or 14 in decimal.
The NOT operator simply complements an integer, that is, it replaces every 1 by a 0 in the binary representation of the number, and vice versa. To calculate the result by hand, all 16 binary digits must be written down. For example, to find the value of NOT 7, write 7 in binary notation with 16 digits:
Then complement the value, giving:
This is the binary representation of the decimal integer -8.
Hint. A quick way of calculating the result of NOT for integers is to add 1 to the original number and reverse its sign. Thus, NOT 23 is -24, NOT 0 is -1 and NOT -1 is 0. Note that the last two results are the same as when using NOT on floating point numbers.
Procedure names may be up to eight characters long. The first character must be alphabetic, but the rest may be either alphabetic or numeric. The procedure name may also be given a qualifier, according to the value it will return (if any).
So the procedure PROC$: will return a string. The qualifier ($ for string procedures and % for integer procedures) must be part of the eight characters, so you may not use the name, for example, PARTICLE%:. The procedure name is always followed by a colon.
A program is constructed from one or more procedures. The top level procedure will call one or more other procedures, each of which has a specific job to do. Procedures may also call themselves.
If the top level procedure is being run from A:, for example, procedures called by it will be looked for on that device first. If the procedure is not found then it will search the next device (B:) and so on.
If the top level procedure is on device B: then OPL searches device B: first, then C: then A:.
In earlier chapters the command GLOBAL was used to declare variables. This is one of two commands which do a similar job, the other is the LOCAL command.
Their uses are similar, in that both are used to declare lists of variables which the program will use, but there is an important difference. The variables declared by the GLOBAL command may be used in not only that procedure, but in any procedure called by it. The values assigned to global variables in any procedure will be available to all other procedures that it calls.
Any procedure may contain a GLOBAL command, but the variables declared by it will only be global from that level downwards, i.e. in that procedure and any procedure called by it.
The LOCAL command may be used in any procedure to declare any variables which will be used in only that procedure. Each procedure may declare its own set of variables with the LOCAL command. These variables are available only to the procedure in which they are declared, if the same name is used for two local variables in two different procedures, then the two variables will be quite distinct and will not affect each other.
Any variable referred to which is not declared in the current procedure will be assumed to have been declared as a global variable in a prior procedure. This is called an external variable as it has been declared externally to the current procedure.
You may use as many GLOBAL and LOCAL commands as you want, provided they occur before any other procedure statements. Attempting to use a variable which has not previously been defined with one of these commands will result in an error being reported when the program is run.
When one procedure calls another, the one being called is said to be below the calling procedure. This in turn may call other procedures which will then be below it in the hierarchy.
In figure 624.1, the top level procedure, proc:, declares a global variable a%, This is then available to all the other procedures below it.
The next procedure, sales:, then uses a%. The next procedure, called salary, called declares another global variable called a%, so this variable is now available to all procedures further down, but it effectively hides the first global variable with that name. So when the last procedure, costs:, uses the variable a%, it accesses the variable declared with that name in salary: as it is the nearest one above it in the hierarchy.
It is for the programmer to ensure that the right variable becomes available to a procedure wherever there are different variables with the same name.
Figure 67 Variable availability.
Procedures can communicate by means of global variables as described earlier. You may also pass values to a procedure via parameters.
When writing a procedure, the procedure name may be followed by a number of parameters which will be used to carry external values into the procedure. The names of these parameters will not be recognised outside the procedure, as for local variables. Here is an example:
fact:(n) IF n=0 RETURN 1 ENDIF RETURN n*fact:(n-1)
The procedure calculates the factorial of a number which is passed to it via the parameter n. To do this, it calls itself as many times as necessary.
Unlike the examples seen so far, the name of this procedure is followed by a pair of brackets containing the name of a parameter. This is why, when writing the procedure in the NEW option of the prog menu, the cursor is initially positioned at the end of the procedure name. You are given the option to add a number of parameter names after the procedure name.
Here is a procedure which could be run from the main menu or the PROG menu, and calls the procedure fact:
dofact: LOCAL result,num PRINT "Number for" PRINT "factorial"; INPUT num result=fact:(num) PRINT result GET
The second procedure dofact: is RUN from the PROG menu, and prints a prompt to the screen. Any number then typed in is passed to the second procedure fact: which returns its factorial. This result is printed to the screen. The last line of the top level procedure just waits for a key to be pressed before returning to the PROG menu.
As you can see, the line result=fact:(num) in dofact: is the one which passes the value of the variable num to fact: and then assigns the returned value to the variable result. (Floating point variables have been used rather than integers, because the range allowed for integers would be exceeded for factorials of numbers greater than 7.)
A similar method is used to pass values to procedures which have more than one parameter. The parameters are supplied in brackets. separated by commas, e.g. proc:(a,b,c).
The values passed to a procedure must match in number, order and type the parameters declared in the procedure. A parameter can only be referred to by the declared name.
Also, parameters differ from true variables in that their values may not be changed. So in the procedure fact, it would have been illegal to have tried to assign another value to n. For example by saying; n=n-1
At the end of a procedure, control automatically returns to the point from which the procedure was called. The RETURN command may be used anywhere in a procedure to force the procedure to terminate at a point other than its natural end. This command may also be used to pass a value back to the calling procedure or the calculator.
Only one value may be returned by any procedure by use of the RETURN command, but any number of values can be passed back by the use of global variables.
Any value which is to be returned to the user from the top level procedure, say to the calculator, must be passed with the RETURN command. If a value is expected from a procedure and none is passed by this command then the value will be assumed to be zero or a null string.
If a procedure has been declared as a string procedure, for example, proc$:, it must return a string or nothing at all. If the RETURN command passes back a numeric value to the calling procedure an error will be reported.
Chapter 16 described how to insert new items into the Organiser's top level menu of the Organiser. It is possible to put a new item into that menu, for example, proc:the procedure dofact:, which can then be run from the top level. The trailing colon is omitted when adding procedure names to the top level menu, and any lower case letters will be automatically converted to uppercase.
The procedure may be run from the internal memory of the machine or from a Datapak.
When the item proc:DOFACT is selected from the main menu in the usual way, the screen will clear and the procedure will run as if it had been called from the PROG menu, When the program finishes, the Organiser will return to the main menu, not the PROG menu.
It is not possible to pass values to a procedure which is run from the main menu. However, by then inputting values to the top level procedure in the usual way, values may be passed 'down' to other procedures.
By using the MENU function, any procedure may display a menu, from which, selections may be made in the same way as those which are from the built-in menus of the Organiser.
Any procedure which is run from the main menu may then display a menu which offers a number of choices relevant to the use of the procedure. Each of these selections may lead to other procedures being called which in turn use a menu to show the choices available for differing courses of action.
To halt the execution of a procedure, first press the ON/CLEAR key. This will pause the procedure indefinitely. You may now quit the procedure by pressing the Q key. The screen will show:
ESCAPE IN A:procname
Now press the SPACE key to return to wherever the procedure was called from.
Note. This method of halting a procedure will not work it the ESCAPE OFF command has been used. This command disables the ON/CLEAR key for the purpose of pausing or halting procedures.
If the ESCAPE OFF command has been used and your procedure enters a loop which has no logical end then you will have to remove the battery from your Organiser, and all data in the internal memory of the machine will be lost.
If your procedure uses a GET or KEY function repeatedly, it may be difficult to quit the procedure in this way. The ON/CLEAR key may then have to be pressed several times.
Before starting to store information in your Organiser, it is essential to decide upon the format which you will use for the information you wish to record.
Information is stored in your Organiser in the form of files, each of which is given a unique file name. These files are in turn divided into records. A file is rather like a card index system, divided into individual cards, each of which holds information in a particular format. Each of these cards corresponds to a record in one of your Organiser files.
The records within a file all contain information in the same format, but the information on each card is different from the next. In a name and address file for example, each record would contain someone's name. telephone number and address.
In a card index, the information stored in each record is organised in a regular way. Different parts of the card are used for each piece of information. Organiser files are arranged in a similar way. Each item is stored in a separate region of the record, known as a field. So in a name and address file, there would be a name field, a telephone number field, and separate fields for each line of the address.
Figure 78 A card index file.
When your Organiser is displaying the main menu, it assumes that any operations such as SAVE or FIND, will be carried out on a file in the memory or one of the Datapaks - whichever is current at the time. This tile is called MAIN. However, when you are using your Organiser from the main menu, you never have to worry about the file name, as only the contents of that one file will be visible and accessible to you.
OPL allows you to create other files which can then be manipulated from the language, and even the file MAIN can be accessed.
The language OPL has a number of commands which are specially applicable to data file handling which enable you to manipulate data in very sophisticated ways. These, combined with the other powerful tools which are part of OPL, give you unequalled data handling power in a pocket sized unit.
Before you can start to enter data into a data file, you must create that file with a suitable name and format on one of the devices using the CREATE command.
The CREATE command must be supplied with a number of parameters, in the following format:
The device and filename which make up the parameter <spec$> may be either a string literal, e.g. "B:filename" or a string variable, e.g. spec$. The file name may be up to eight characters long. The next parameter is the logical file name. This may be A, B, C or D. The file is then referred to by this name from within the program.
Next come the field names. There may be up to 16 fields in any record, and these may be given a qualifier, either % or $ to signify integer data or string data respectively. Fields containing floating point data need no qualifier. Field names may be up to eight characters long including any qualifier used.
When a file has been created, it is automatically open, and can have records saved to it immediately, without use of the OPEN command. This file is then current and all file access will be on this tile, until another file is made current with the USE, CREATE or OPEN commands.
To open an already existing file, the syntax of the OPEN command is exactly the same as for the CREATE command. Up to four files may be open at any one time, and these may be spread over any of the three devices, e.g. with two files open on A: and two others on B:, or one file each on A: and B: and another two on C:.
When a file is created or opened, that file is then automatically the current file and all access is to that file. It more than one file is open, to change the current file from one to the other, the USE command is employed.
In this example the file with the logical file name B becomes the current file. All access is now to this file until it is changed with another USE command or another file is opened, created or closed. If an attempt is made to use a file which has not previously been opened, an error is reported.
To add a record to the open file, you must first assign some values to the current field names. The field names act in a similar way to variables, and for example can be assigned values or used in INPUT statements.
To INPUT a value to a data field, the field name must be used with the logical file name like this:
where B is the logical file name and field$ is the name of the field. These are separated by a full stop.
When the fields have been assigned values, you can add them to the open file with the APPEND command. The fields of the record will consist of the values currently assigned to all the field variables for that file. The APPEND command has no parameters, the field values are automatically added to the file in the correct order and format.
Also, just as with variables, it you try to assign a text string to a numeric variable, then an error will be reported.
Records cannot be added into the middle of a file, they may only be added to the end.
At any time during access of a data file, the field names currently in use can be used like any other variable, for example, in a PRINT statement, or a string or numeric expression.
You can change the current record by using any of the above five commands. The FIRST command, as the name suggests, moves to first record in a file.
The NEXT command moves to the following record in a file. If the end of the file is passed, NEXT does not report an error, but the EOF function will return true (see chapter 34). The current record will then be null.
The BACK command moves to the previous record in the file. If the current record is the first record in the file then the current record does not change.
The LAST command moves to the last record in the file.
You can move to a particular record by using the POSITION command. For example, the instruction POSITION 3 makes record 3 (the first record is record 1) the current record.
You can find the current record number by using the POS function which returns the number of the current record.
To erase a record, simply make that record current by use of one of the above commands (FIRST, NEXT, BACK, LAST or POSITION) and use the ERASE command. This removes the current record from the file and renumbers the following records.
If you want to find any records in a file that contain a particular piece of text then the FIND function may be used.
This acts rather like the FIND facility in the top level menu. The difference is that whereas the main menu FIND prints the found text to the screen, this function returns a record number.
If the text is found, the number returned corresponds to the record containing that value, and that record is made current. If no such text is found in the current file then the number returned is zero.
So the line r%=FIND("Abraham") would make the first record containing the string "Abraham" the current record and return the number of that record to the variable r%.
When all access of a particular file has been finishedyou have finished accessing a particular file, that file can be closed with the CLOSE command, which closes the current file.
Any data file may be deleted by using the DELETE command. The file to be deleted must be closed when this command is issued or an error message will be reported. The device and the file name must be specified thus:
Note: The device and filename which make up the parameter <spec$> may be either a string literal, e.g. "B:filename" or a string variable, e.g. spec$. Once a file has been deleted there is no way of restoring it to memory - it is gone for good!
The COPY command is a powerful tool which acts in a similar way to the COPY facility in the main menu. There are three possible courses of action: a copy may be made of a file under the same name as the original, a copy may be made under another name or all data files on one device may be copied to another. This is how the three versions would appear in a program:
COPY "device1:filename1","device2:" COPY "device1:filename1","device2:filename2" COPY "device1:","device2:"
All string literals in these examples may be replaced with string variables. Examples of programs using all of these commands can be found in Chapter 32.
So far we have only considered programs which run in a straight line from start to finish. They consist of a number of instructions which are executed in the order they appear in the program. It you want to carry out an instruction more than once then that instruction must appear however many times you want it carried out.
That is clearly very inefficient. A far more efficient method is for the program to be able to loop around a particular part of the program as many times as you require, or until a certain condition is met.
This is a vital part of the stored program concept, and there are a number of ways of doing this in OPL.
The first two are the DO/UNTIL and the WHILE/ENDWH loops. These are known as program Structures, because they do nothing themselves, they just enable other instructions to be repeated as often as necessary. They operate in a similar way to each other, with the distinction that the DO/UNTIL structure tests for a condition being fulfilled at the end of the loop. The WHILE/ENDWH structure tests the condition at the start of the loop
First let's look at an example of DO/UNTIL:
a%=10 DO PRINT "A=";a% a%=a%-1 UNTIL a%=0
As you can see, this is just a small part of a program to illustrate how a loop works.
The first line assigns the value 10 to the integer variable a%. The loop itself starts on the next line, with the instruction DO. This is the instruction which says to OPL, "Execute all of the following lines of program until an UNTIL instruction is reached, if the condition following that instruction is not met, then repeat the same set of instructions until it is." That may sound longwinded, but read it through again, it is quite simple really.
The next line tells OPL to print a short text string to the display, followed by the value of the variable a%. The first time through the loop, the value of a% will be 10.
Next, the value of a% has 1 subtracted from it. That now makes the value of a% 9. Now comes the UNTIL instruction, followed by a condition. The condition is that a% is equal to zero.
As this is the first time through the loop, the value of a% is non-zero, so the program control returns to the DO instruction and the loop is repeated. This time the value of a% decrements to 8, and again the condition fails. This process continues until a% does equal zero.
At that point, the condition is met and the program control can now continue in a straight line to the instruction following UNTIL.
The first of the statements between the DO and UNTIL commands may be on the same line as DO. So in the procedure above, the line:
DO PRINT "A=";a%
would have been valid.
The WHILE/ENDWH structure operates in a very similar way, so lets look at an example straight away:
a=4.1 b=2.7 WHILE a> b PRINT "a is greater" PRINT "than b" b=b+1.04 ENDWH
In this structure, the test condition is at the beginning of the loop. With both of these structures, if the program contains the beginning of the structure (DO or WHILE) but does not have the corresponding end to the loop then an error will be reported.
However many loops are nested within each other (to a maximum of 8), OPL will keep track of the number and checkmake sure that each loop has both a start and an end of the correct type. If you try to match, say, a DO with an ENDWH, when you translate the procedure a structure error will be reported.
Note. Tests may be made using the logical operators available to OPL. See Chapter 23 for more information on these operators.
Another command which can redirect the program control out of a straight sequence is GOTO. Not surprisingly this indicates that the program control should jump to another part of the procedure altogether. This part is referred to by a label.
The label used must be in the same procedure as the GOTO command, and the jump is not conditional, i.e., it will always be executed.
GOTO exit:: PRINT "MISS THIS LINE" PRINT "AND THIS ONE" exit::
In the above example the program, on reaching the line containing the GOTO instruction, would jump to the line beginning with the label exit::. Note that all labels must end with a double colon.
The GOTO is one of the ways of branching within a program, but it is a fairly crude tool and if used indiscriminately, can lead to programs which are difficult to read and de-bug.
A more adaptable way of performing a branch, in this case a conditional branch, is the IF/ELSEIF/ELSE/ENDIF structure.
This structure is used to perform one or more instructions IF a condition is met. If that condition is not met then the ELSEIF instruction may follow, to test another possible condition. There may be any number of ELSEIF instructions within an IF/ELSEIF structure.
After all likely eventualities are catered for by the ELSEF instructions, any other possibilities can be catered for by an ELSE statement, followed at the end by the ENDIF statement.
Here is an example to illustrate how this might be used:
report: GLOBALLOCAL g% g%=GET PRINT "THAT KEY IS" IF g%>64 AND g%<91 PRINT "UPPER CASE" ELSEIF g%>96 AND g%<123 PRINT "lowercase" ELSE PRINT "NOT A LETTER" ENDIF GET
The program just waits for a key to be pressed at the keyboard, and then states that it is either a lower or upper case letter. If it is not a letter, then that is stated, as allowed for by the ELSE statement. The ELSE statement needs no condition as it allows for all other possibilities other than those outlined in the conditions of the ELSEIF statements.
The ELSEIF and ELSE statements are optional, but for every IF there must be a corresponding ENDIF, otherwise an error will be reponed.
It is also valid for the statement following the ELSE part of the structure to be on the same line as ELSE. So in the procedure above, the line:
ELSE PRINT "NOT A LETTER"
would have been quite valid.
At various points in this manual it has been stated that if an argument or parameter is supplied incorrectly, or the required syntax for a particular command is not followed, then an error will be reported.
Under normal circumstances, the screen will clear and then display an error message corresponding to the particular type of error encountered by the program.
In such a case, execution of the program is ended. There are ways to avoid this, but they put the programmer in full command and must be used carefully.
The tools used to control error reporting are the ONERR, TRAP and RAISE commands and the ERR and ERR$ functions.
The first of the commands, ONERR, is used to detect the occurrence of an error and to redirect program control to another part of the procedure to deal with that error.
The ONERR instruction must be followed by a label which is found elsewhere in the same procedure, like this:
ONERR zero:: PRINT PI/0 PRINT PI RETURN zero:: PRINT "YOU CANNOT" PRINT "DO THAT" ONERR OFF
The first line instructs OPL to branch to the line beginning with the label zero:: on the occurrence of any error. Sure enough, the next line tries to perform a division by 0 which would cause an error to be reported, so the program branches to the label.
Here we print your own message. Note that, in this example, the line after the one containing the error is never executed.
After the ONERR command is used, all subsequent program errors - even in other procedures - will result in the program being directed to the same point in this procedure, the label zero::. If you want to direct the program elsewhere then the ONERR command must either be used again with a different label, or cancelled with the ONERR OFF command. This switches the error trapping facility off, so any further errors will be handled by OPL which will display a suitable error message. Figure 89 shows this in action:
Figure 8 The ONERR command
Figure 9 The ONERR command
The error in the procedure proc1 (a=LOG(-1)) will mean that control is rerouted to the point marked by label::, where it will be dealt with accordingly. However, if the ONERR OFF command is not used to switch off this command, then in any procedure called by proc1, in this case proc3, an error will still mean that control will return to the same point, label::.
This may or may not be the result you require, and you must ensure that if you do not want all errors to return control to the same point that the ONERR label:: and ONERR OFF commands are used appropriately.
The next error handling tool at your disposal is the TRAP command. This can be used with any of the commands listed below:
The trap command immediately precedes any of these commands, separated from it by a space. Here is an example:
TRAP INPUT a%
The INPUT command will be executed in the usual way, but in the event of an error occurring as a result of that command, then the error will be suppressed or trapped, and the next line of the program executed as if there had been no error.
This might happen in the above example it a string was typed in instead of an integer. This allows the program to supply its own error message in such a case, letting the user have another try:. If, when using the INPUT command without TRAP, a text string is entered when a number is expected, the display will scroll up and a question mark will be shown, prompting for another - valid - entry.
label:: PRINT "NUMBER"; TRAP INPUT a% IF ERR=226 PRINT "NOT A NUMBER" GOTO label:: ENDIF
In this example, if a text string is typed in instead of a number, then the TRAP statement will still allow the next line to be executed. In that case, the IF statement would find the error concerned, print out a suitable message and then return to the line containing the prompt so that another attempt can be made.
This example also shows you the ERR function in action. This function returns the number of the last error which occurred in the program, according to the table later in this chapter.
The last command which you can use to control error trapping is RAISE. This is used to artificially generate an error.
If you are using the ONERR command to trap errors and handle them yourself, then at some during the development stage of your program you will need to test your error handling routines. The best way to do this is with the RAISE command.
You can generate an error that you think might occur when the program is in use, and see if the error handling routine takes care of it in the way you anticipate.
RAISE also comes into its own when your program is built up from a number of procedures which call one another in sequence. If the procedure currently being executed was called by another procedure, which was called by another and so on, then you may wish to return 10 the top level quickly, to carry out a particular operation. The usual method would be to use the RETURN command to exit from all of the procedures in turn.
A faster method would be to issue an ONERR statement at the top level procedure, then when you RAISE an error at the lowest level, the program control will return to the label following the ONERR statement, even though it is several jumps back in the sequence of procedures.
When an error occurs in a program, the number of the error from the table below is accessible by using the ERR function. This can be used in your program, so that when an error occurs, if it is one of a certain range of anticipated errors, you can trap it and deal with it within the program.
The ERR$ function can be used to access any of these strings, given the appropriate error number.
Alternatively, if an error occurs and is not trapped, the program will halt, an error message will be displayed and OPL will offer the option of returning to the EDIT option from the PROG menu, the cursor will be at or near the instruction which caused the error and you will be able to correct the fault. (This is dependent on the text version of the procedure being available - see chapter 31 for more details.)
These are the error messages which can occur, their numbers and meanings:
|255||NO ALLOC CELLS|
Seen only when running machine language routines which access internal buffer space.
|254||OUT OF MEMORY|
Either the internal memory of the machine is fully occupied by programs, diary entries and data files, or the current program has used up all available memory.
A number has exceeded the exponent maximum of plus or minus 99.
|252||STR TO NUM ERR|
A non-numeric string has been passed to the VAL function.
|251||DIVIDE BY ZERO|
An attempt has been made to divide by zero.
|250||NUM TO STR ERR|
Only occurs when calling operating system machine language routines or from the calculator.
Will only occur when users machine language program destroys the Organisers stack.
|247||FN ARGUMENT ERR|
The wrong type of argument has been passed to a function or a user's procedure.
There is no Datapak fitted to the device named in an instruction such as CREATE, OPEN etc, or a pack has been removed during pack access.
|245||WRITE PACK ERR|
The Organiser cannot write data to one of the Datapaks, try re-fitting it.
|244||READ ONLY PACK|
An attempt has been made to write to a Datapak used by the MK1 Organiser, or a program pack. These may be read from, but not written to.
|243||BAD DEVICE NAME|
A device name other than A, B or C has been used.
Occurs when calling operating system machine language routines or when a pack is changed in the middle of a COPY.
|241||PACK NOT BLANK|
Datapak needs to be re-formatted as residual data is still present.
A pack not supported by Organiser MK2 has been fitted to one of the devices.
An attempt has been made to write to a Datapak which is already full.
|238||END OF FILE|
Occurs when an attempt is made to read past the end of a data file.
|237||BAD RECORD TYPE|
Occurs only when running machine language programs.
|236||BAD FILE NAME|
An illegal file name has been specified which does not conform to the rules in chapter 18.. (Max 8 characters, alphanumeric starting with a letter.)
An attempt has been made to create a file or procedure under a name which already exists on that device.
|234||FILE NOT FOUND|
An attempt has been made to access a file which does not exist on the specified device.
No device may contain more than 110 files, an attempt has been made to create a file which exceeds exceed this limit.
|232||PAK NOT COPYABLE|
An attempt has been made to copy a pack which is copy-protected.
|231||BAD DEVICE CALL|
Will only occur when user accesses a device which is not available from a machine language program.
An attempt has been made to access a device which is not present, eg a printer. When no printer is connected, the LPRINT command will produce this error.
|229||DEVICE LOAD ERR|
A program pack or peripheral pack has been removed during its verification by the Organiser or the pack has become corrupted.
A syntax error has been detected during the translation of a procedure.
An incorrect number of brackets has been found in an expression, either too few or too many.
|226||BAD FN ARGS|
An illegal number or type of arguments has been supplied to a function, eg LOG(-1), SIN(x,y), or LEN(a).
An out of range subscript has been specified for an array variable, eg a(0) or a(10) when the array a() has been declared as having 9 elements.
A value has been assigned to a variable of the wrong type, eg a$=12 or a="text", or a procedure parameter has been given a value of the wrong type.
|223||NAME TOO LONG|
The specified file, procedure, or variable name exceeds the maximum number of characters allowed, eight characters including the $ or % qualifier.
An incorrectly formed variable name has been used, eg name$$, or a name is too long.
Occurs when either too many sets of quotation marks are used to enclose a text string or one of the pair is omitted.
|220||STRING TOO LONG|
A string has been produced which exceeds the allocated with the GLOBAL or LOCAL commands, eg:
A non-valid character such as ? or @a has been included in a calculation string or an expression.
A number which cannot be evaluated properly has been used, eg 2.3.4
|217||NO PROC NAME|
An externally created program file has been introduced which does not have a valid procedure name as its first line.
A variable has been declared illegallyincorrectly, eg:
|215||BAD ARRAY SIZE|
An array has been declared with an illegal number of elements, eg GLOBAL name$(0,15).
The file, procedure or variable name given is already in existence on the current devicein the current procedure.
An IF/ENDIF, WHILE/ENDWH or DO/UNTIL structure has been incorrectly nested.
Structures within a procedure have been nested too deeply No more than 8 structures may be nested within each other
An attempt has been made to GOTO a label which does not exist in the current procedure.
A comma has been omitted from a list of items which should be delimited by commas throughout.
|209||BAD LOGICAL NAME|
An illegal logical name has been specified; ie, not A, B, C or D.
An attempt has been made to assign a value to a procedure parameter.
|207||BAD FIELD LIST|
Any file must contain at least one and not more than sixteen fields. Occurs when an attempt is made to exceed these limits.
The ON/CLEAR key has been pressed during program execution, pausinghalting that program, followed by a press of the Q key has then been pressed- quitting the program. This does notcannot happen if the ESCAPE OFF command has been used.
|205||ARG COUNT ERR|
An incorrect number of arguments has been supplied to a procedure.
A variable has been encountered which has not been declared in a calling procedure as a global variable, has not been declared as a parameter to the current procedure and has not been declared in the current procedure as a local or global variable. The bottom line of the display shows the name of the missing external. Press the SPACE key and the name of the procedure where the error occurred will be displayed. Press SPACE again and the message EDIT Y/N is shown - provided there is a text version of that procedure saved. You may then edit the procedure (Y) or quit to the PROG menu.
A procedure has been called which does not exist on any device.
|202||MENU TOO BIG|
The string supplied to the MENU function is too large and must be shortened.
Occurs when a field variable used does not match any of those in any logical file.
|200||READ PACK ERROR|
The data in a Datapak cannot be read, the pack needs re-formatting.
|199||FILE IN USE|
An attempt has been made to open a file which is already open, or to delete a file which is open.
|198||RECORD TOO BIG|
No record may exceed a total of 254 characters.
|197||BAD PROC NAME|
Occurs when an invalid procedure name is given in the NEW option in the PROG menu.
|196||FILE NOT OPEN|
An attempt has been made to write to or read from a file which is not open.
The range of numbers allowed for integer variables (-32768 to +32768) has been exceeded.
If an error occurs when a procedure is running, and it is not trapped by the procedure itself, then an error message will be displayed and you will be instructed to press the SPACE key.
If the program we run from the PROG menu yYou will then be offered the chance to edit the procedure. The screen will show the messageprompt EDIT Y/N. Press the Y key to edit the procedure or the N key to return to the returned PROG menu. This option is also only offered if a SAVEdthere is a text version of the procedure is available.
When the procedure has been edited so that the error no longer occurs, press the MODE key to return to the TRAN/SAVE/QUIT menu, and either translate, save, or quit the proceduremake a selection. If you quit at this stage, then even if you have made alterations to the procedure, they will be discarded and the old version of the procedure will still remain be stored on the current device.
All programming languages are very particular about the way commands and functions are used, and especially in the way program statements are laid out. They must conform to the syntax for the language in use. The various items of punctuation are vital to the programs and ensure that the correct action is performed on each part of the program line.
An area where OPL requires careful handling is in the passing of parameters to procedures and functions and ensuring that the correct types of numbers are used.
Below are a number of errors which can easily occur, and the correct format which should be used. In each case the statement containing the error is marked.
Omitting the colon between statements on a multi-statement line:
|a$="text" PRINT a$||a$="text" :PRINT a$|
Omitting the colon after a called procedure name:
|GLOBAL a,b,c||GLOBAL a,b,c|
Omitting one or more of the colons after a label:
|GOTO below:||GOTO below::|
Omitting the space before the colon between statements on a multi-statement line:
|a=a+b:PRINT a$||a=a+b :PRINT a$|
Passing an integer, or an expression which evaluates to an integer result, to a floating point procedure called proc2:(x) - this may occur when calling a procedure from within the language or from the calculator:
1) From the calculator:
2) From another procedure:
Passing the wrong number of parameters to a procedure - here, the procedure proc3:(x,y)
OPL only allows numbers between minus 32768 and plus 32767 to be assigned to integer variables, so any expression which exceeds these limits will cause an error:
|LOCAL a%||LOCAL a|
The structures allowed within OPL are DO/UNTIL, WHILE/ENDWH, and IF/ELSEIF/ELSE/ENDIF. These may all be nested within one another to up to eight8 structures deep. If you attempt to nest to a greater depth than this, as error will be reported.
If the three structures are nested incorrectly, for example by matching up a DO command with a WHILE command, an error will also be reported.
|WHILE a>2||UNTIL a<=2|
It is possible to write a procedure containing an endless loop to which there is no logical exit. If the ESCAPE OFF command has been used, the ON/CLEAR key will not break you out of that loop and it may only be exited by removing the battery from the Organiser. The ON/CLEAR key usually acts as a pause button, suspending execution of the current procedure until another key (except Q) is pressed, whereupon execution continues. If the Q key is pressed, the ESCAPE error message is displayed. Press the SPACE key o return to the PROG menu. This pocess does not operate if the ESCAPE OFF command has been used. (The ON/CLEAR key can usually act as a panic button, aborting the current procedure - except when the ESCAPE OFF command has been used. See end of chapter 24.)
Removing the battery will result in the loss ot all data in the internal memory of the machine, so it should be avoided. Here is one such procedure which contains an endless loop - DO NOT TYPE IT IN!
proc: ESCAPE OFF here:: PRINT "Endless loop..."; GOTO here::
This is a very simple example and you would be unlikely to make such a clumsy mistake. However, when using the ONERR label:: command, it is easy to forget that all errors will result in control returning to the last label specified with that command. This may also result in an endless loop, so great care must be taken when using the ONERR label:: command in conjunction with the ESCAPE OFF command.
When you start writing your own procedures you may, from time to time, want to list a procedure out to a printer. It may help you get a clearer idea of the sequence of the procedure when it is there in black and white on a piece of paper. It is certainly easier to show someone else how a procedure is made up by handing them a piece of paper which they can then take away with them.
To connect a printer to your Organiser, you will need the RS232 Communications Link from Psion. This allows any serial printer to be connected to the Organiser or may be used to communicate with another computer. (See Appendix F)
If no printer is connected to your Organiser when the LIST option from the PROG menu is selected, a DEVICE ERROR message will be displayed. Press the SPACE key to return to the PROG menu.
The DIR option in the PROG menu is used to read the directory of procedures which are stored on the current device.
Select DIR from the PROG menu in the usual way. The screen will clear and show:
If necessary, press the MODE key one or more times to change to the required device, then press the EXE key. If there are any procedures stored on the current device, the first will be displayed. Each time you press the EXE key the next procedure name is displayed.
After the last procedure name has been displayed, the screen will show an END OF PACK message.
Press the ON/CLEAR key to return to the PROG menu.
The ERASE option from the PROG menu allows you to erase procedures from any of the devices. Select ERASE from the PROG menu in the usual way and the screen will show:
If necessary, press the MODE key one or more times to change to the required device. You may now type in the name of a procedure to be erased from the current device, for example PROC. Press the EXE key and the screen will show:
ERASE A:PROC ERASE Y/N
Press the Y key to confirm that you wish to erase that procedure, or the N key to cancel the instruction.
The COPY option in the PROG menu is used to make copies of procedures from one device to another.
When COPY is selected from the menu in the usual way, the screen will show:
COPY OBJECT ONLY Y/N
Press the Y key if you want to copy just the translated copy of a procedure, the object file, to another device. Press N to copy both the object and text versions. If both are copied, then the procedure may be edited in the usual way on the destination device after the copy has been made.
However, if only the object file is copied, then that copy cannot be edited. It is wise to make sure that your procedures are fully tested before making an object-only copy.
The advantage of copying just the object file is that the procedure will then occupy only about half of the memory space occupied by the original.
The COPY option operates in the same way as the COPY option in the main menu with just one exception: If a file already exists on the destination device with the same name as the one being copied, the existing version on the destination device will be deleted. There cannot be more than one procedure with the same name on any of the devicesdevice.
After the file or files have been copied to the destination device, the screen returns to the PROG menu.
This chapter contains example programs written in OPL. The programs are not intended to demonstrate all of the features of OPL, but should give you a few hints on how the commands and functions can be used to the best advantage.
Each of the procedures must be entered separately, it is not possible to enter two procedures in one continuous block.
This procedure acts rather like the INFO option in the top level menu. However, it also shows which model of the Organiser is in use, the total amount of memory in the machine and the free space (in bytes) on each of the three devices - if fitted.
stat: LOCAL a$(8),b%,c$(5),d$(6),e$(2),f% a$="Memory:" :c$="MAIN" d$="FREE:" PRINT "Model:"; f%=PEEKB($FFE8) IF f%=0 PRINT "CM" PRINT a$+"8K" ELSE PRINT "XP" PRINT a$; IF f%=1 PRINT "16K" ELSE PRINT "32K" ENDIF ENDIF :GET :b%=0 DO e$=CHR$(b%+%A)+":" IF EXIST(e$+c$) OPEN e$+c$,A,f$ PRINT d$;e$;SPACE CLOSE :GET ENDIF b%=b%+1 UNTIL b%=3
This procedure, taken from the Organiser II Finance Pack, calculates monthly mortgage payments based on the amount and period of the loan, the interest rate and the source of the loan. The procedure calls another procedure, q:, a general input routine.
This can be called by any procedure which needs to prompt the user with a text string to enter a floating point number. The text string is passed to the procedure as a parameter, and the input value is returned. Use of such a general procedure avoids the unnecessary duplication of identical code at several places in a program.
mortgage: LOCAL a%,loan,b,y,i,p ONERR l1:: CLS PRINT "EVALUATE MONTHLYMORTGAGE PAYMENT" PAUSE 30 loan=q:("ENTER AMOUNT OF LOAN"+CHR$(63)+" ") DO i=q:("INTEREST RATE % "+CHR$(63)+" ") UNTIL i>0 AND i<99 DO y=q:("ENTER TERM IN YEARS "+CHR$(63)+" ") UNTIL y>.5 AND y<100 a%=MENU("BUILDING-SOCIETY,BANK,OTHER") IF a%=0: RETURN : ENDIF i=i/100 :b=1+11*(A%/2) p=loan*i/12/(1-((1+i/b)**(-b*y))) CLS :PRINT "MONTHLY PAYMENT",FIX$(p,2,-8) GET l1:: RETURN
q:(a$) LOCAL z ONERR l1:: l1:: CLS : PRINT a$,CHR$(16); INPUT z CLS RETURN(z)
Interest rates on loans and hire purchase transactions may be quoted as a percentage per month, rather than as an annual rate. It is therefore sometimes not obvious which of two quoted interest rates offers the best deal on a particular investment or purchase. The way around this is to calculate an APR (Annual Percentage Rate) for each quoted figure and compare the two. The APR is a comparative _ measure of the interest rates on an annual basis, and standardises quotations of interest rates.
This procedure, also from the Finance Pack, allows you to do this quickly and easily. The Finance pack contains not only the procedures listed here, but also a bank account logger, an expenses recording package, calculators for NPV (Net Present Value), IRR (Internal Rate at Return), compound interest and gilts and bonds.
apr: LOCAL i,n DO CLS :PRINT "ENTER PERIOD IN MONTHS? "; INPUT n UNTIL n>=1 AND n<15 DO CLS :PRINT "INTEREST RATE % FOR PERIOD? "; INPUT i UNTIL i>0 AND i<20 i=(1+i/100)**(12/n) i=(i-1)*100 CLS : PRINT "APR=";FIX$(i,2,-6) GET
The procedure below may be used to mute all audible alarms and beeps from the Organiser. Mute: acts as a toggle, so the same procedure is used to switch the alarms on and off. No input is required, the procedure detects whether the alarms are enabled or disabled and then acts accordingly.
mute: PRINT "Sound now <"; IF PEEKB($A4)=0 POKEB $A4,1 PRINT "OFF>" ELSE PRINT "ON>" POKEB $A4,0 ENDIF PRINT "Press any key"; GET
This procedure can be used to provide a degree of security to the data held in your Organiser. When run, the procedure starts by switching the machine off. When the ON/CLEAR key is pressed, switching the machine back on, the procedure is still being executed and a password is requested. If the password entered is not the correct one then the machine switches off again.
The ONERR command is used to prevent the procedure being halted, so the password must be supplied, or the battery removed to gain access to the data in the machine.
password: LOCAL a$(20) ONERR start:: start:: OFF CLS :PRINT "Enter password" INPUT a$ IF a$<>"Barry" GOTO start:: ENDIF
Note. It is not wise to pick for a password a word or sequence of characters which has an obvious connection with yourself. Using your name or your name spelled backwards is not a terribly secure password.
This program generates the first 30 prime numbers and prints them to the screen:
prime: GLOBALLOCAL prim%(31),j% LOCAL i%,flag%,k%,l%,m% flag%=0 i%=3 :j%=2 prim%(1)=2 DO l%=1 :m%=1 WHILE l%<j% k%=prim%(l%) IF i%=k%*INT(i%/k%) m%=0 :BREAK ENDIF l%=l%+1 ENDWH IF m% prim%(j%)=i% j%=j%+1 IF flag% PRINT ",": ELSE PRINT "Primes:2,"; ENDIF flag%=1 PRINT i% ENDIF i%=i%+1 UNTIL j%>=30 PRINT "FINISHED" GET RETURN
This program consists of five procedures, tax:, taxin:, taxout:, taxcalc: and newtax:. The program is used to calculate personal tax payments based on gross income, marital status, expenses, perks and capital gains.
When the program is used for the first time, you are prompted for tax threshold data for the current tax year. This data is put into two files which are then interrogated by the program to determine personal tax levels. All five procedures are needed, and these must be entered and translated separately.
tax: GLOBAL inc,gross,cap,dr$(2),b%,c$(6),f$(8),tax c$="TAXALS" :b%=0 DO dr$=CHR$(b%+%A)+":" IF EXIST(dr$+c$) f$=dr$+c$ ENDIF b%=b%+1 UNTIL b%=3 IF f$="" PRINT "Files Dont Exist";CHR$(16) PAUSE 20 newtax: ELSE dr$=LEFT$(f$,2) ENDIF OPEN dr$+"RATES",A,thresh,rate OPEN f$,B,sing%,marr%,capg% taxin: CURSOR OFF :CLS :PRINT " COMPUTING" taxcalc: taxout: CLOSE
taxin: LOCAL an$(1),allow% CLS :USE B PRINT "Enter Gross";chr$(15);"Income: "; :INPUT gross CLS :an$="" WHILE NOT(an$="m" or an$="s") CLS :PRINT "Married/Single";CHR$(15);"(m/s): ";CHR$(63); an$=LOWER$(GET$) ENDWH IF an$="m" :allow%=B.marr% ELSE allow%=B.sing% ENDIF inc=gross-allow% CLS :PRINT "Enter Allowable";CHR$(15);"Expenses:"; INPUT allow% inc=inc-allow% CLS :PRINT "Enter Taxable";chr$(15);"Perks: "; INPUT allow% inc=inc+allow% CLS PRINT "Enter Capital";chr$(15);"Gains: "; INPUT cap RETURN
taxout: LOCAL cgt CLS PRINT "Tax on Earned";chr$(15);"Income- ";FIX$(tax,2,8) GET CLS PRINT "Net Earned";chr$(15);"Income= ";FIX$((gross-tax),2,8) GET IF cap>B.capg% cgt=(cap-B.capg%)*0.30 CLS PRINT "Capital Gains";chr$(15);"Tax= ";FIX$(cgt,2,8) GET :CLS PRINT"Total Tax Bill";CHR$(15);"= ";FIX$((tax+cgt),2,8) GET :CLS PRINT "Net Total income";CHR$(15); PRINT "=";FIX$((gross+cap-tax-cgt),2,8) GET ENDIF RETURN
taxcalc: LOCAL i%,old USE A FIRST WHILE NOT EOF IF inc>A.thresh :i%=POS :ENDIF NEXT ENDWH POSITION i% tax=(inc-A.thresh)*A.rate/100 old=A.thresh WHILE i%>1 i%=i%-1 POSITION i% tax=tax+(old-A.thresh)*A.rate/100 old=A.thresh ENDWH RETURN
newtax: LOCAL c%,i% i%=MENU("RAMFILE,PACKA,PACKB") IF i%=0 :RETURN :ENDIF dr$=CHR$(%A+i%-1)+":" f$=dr$+"RATES" TRAP CREATE f$,A,thresh,rate IF ERR<>O :PRINT ERR$(ERR) PAUSE 60 :RETURN ENDIF PRINT "RATES data:" DO PRINT "Threshold:"; :INPUT A.thresh PRINT "Rate:"; :INPUT A.rate c%=c%+1 :APPEND UNTIL c%=6 :CLOSE f$=dr$+"TAXALS" TRAP CREATE f$,B,sing%,marr%,capg% IF ERR<>0 :PRINT ERR$(ERR) PAUSE 60 :RETURN ENDIF PRINT "TAXALS data:" PRINT "Single:"; :INPUT B.sing% PRINT "Married:"; :INPUT B.marr% PRINT "Cap.Gains:"; :INPUT B.capg% APPEND :CLOSE
The data which must be entered into the files TAXALS and RATES is given in the tables below. These figures are valid for the tax year 1986/87, the figures for each year are given in the annual budget.
THRESHOLD RATE (%) 0 30 17201 40 20201 45 25401 50 33301 55 40201 60
SINGLE 2335 MARRIED 3655 CAP. GAINS THRESHOLD 6300
The following program, comprising three procdures, demonstrates the creation and opening of a file. You may easily add records, list the contents of the file, or step through the recods and delete any records which become out out date.
menu: GLOBAL fname$(10) LOCAL option% begin:: option%=MENU("OPEN,CREATE,QUIT") IF option%=1 OR option%=2 CLS :PRINT "File Name:" :AT 1,2 :INPUT fname$ ENDIF IF option%=1 IF EXIST(fname$) OPEN fname$,a,name$,tel$ ELSE CLS :BEEP 200,200 VIEW(1,".....NOT FOUND.....") GOTO begin:: ENDIF ELSEIF option%=2 IF EXIST(fname$) CLS :BEEP 200,200 VIEW(1,".....FILE ALREADY EXISTS.....") GOTO begin:: ELSE CREATE fname$,a,name$,tel$ ENDIF ELSEIF option%=3 STOP ELSE GOTO begin:: ENDIF menu:: option%=MENU("APPEND,DISPLAY/ERASE,LIST,QUIT") IF option%=1 append: ELSEIF option%=2 display: ELSEIF option%=3 list: ELSEIF option%=4 CLOSE :GOTO begin:: ENDIF GOTO menu::
The procedure above, called menu:, calls the following procedures; the first allows you to add data to your file:
append: WHILE 1 CLS AT 1,1 :PRINT "NAME: "; :INPUT a.name$ IF LEN(a.name$)=0 :RETURN :ENDIF AT 1,2 :PRINT "TEL : "; :INPUT a.tel$ APPEND ENDWH
The next procedure lists, in a scrolling format, the first 15 characters of the first field name$ of the file currently open:
list: LOCAL line% line%=1 FIRST DO IF LEN(a.name$)>0 PRINT LEFT$(a.name$,15) ENDIF NEXT UNTIL EOF RETURN
The last procedure of this program allows you to display the
current record in the file. The options shown on the top line of the
Organiser's display while this procedure is executing are:
F - First record
N - Next record
B - Back a record
L - Last record
E - Erase the displayed record
Q - Quit back to previous menu
display: LOCAL opt% CLA FIRST WHILE 1 AT 1,1 :PRINT "F/N/B/L/E/Q" opt%=VIEW(2,a.name$+" "+a.tel$) IF opt%=%F FIRST ELSEIF opt%=%N AND COUNT>1 NEXT ELSEIF opt%=%B BACK ELSEIF opt%=%L LAST ELSEIF opt%=%E AND COUNT>0 ERASE ELSEIF opt%=%Q RETURN ENDIF ENDWH
This is a game which demonstrates the use of user defined graphics (UDG's). The game consists of three procedures, game:, igame: and udg:.
The main procedure, game:, calls igame: and udg: which set up the graphics characters used in the game.
The object of the game is to avoid being caught by the 'pacman' type chaser. Your movable man can jump between the two lines at the display to avoid the accelerating pursuer. Press the X key to jump down and the S key to jump up.
At the end of the game your score will be displayed on the screen. To pause the game, press the ON/CLEAR key once. To stop the game, follow this with a press of the SPACE key.
game: LOCAL a$(1),b$(1),c$(1),d$(1),e$(2),f$(1),g$(32) LOCAL a%,b%,c%,x%,y%,z%,sc%,b1%,f%,h$(1) igame: CURSOR OFF a$=CHR$(0) :b$=CHR$(1) c$=CHR$(2) :d$=CHR$(3) e$=CHR$(4)+CHR$(6) :f$=CHR$(5) g$=REPT$(CHR$(165),32) :h$=CHR$(7) b%=20 :c%=12 :x%=16 :y%=1 DO CLS :PRINT g$ :AT x%,y% :PRINT h$ a%=1 :c%=1+RND*2 DO AT a%,c% :PRINT a$ :BEEP b%,10*b% AT a%,c% :PRINT b$ :BEEP b%,10*b% AT a%,c% :PRINT c$ :BEEP b%,10*b% AT a%,c% :PRINT d$ :BEEP b%,10*b% AT a%,c% :PRINT e$ :BEEP b%,10*b% AT a%,c% :PRINT f$ :BEEP b%,10*b% AT a%,c% :PRINT " " :z%=KEY IF z% IF z%=%S AND y%=2 AT x%,y% :PRINT CHR$(165) y%=1 :AT x%,1 :PRINT h$ ENDIF IF z%=%X AND y%=1 AT x%,y% :PRINT CHR$(165) y%=2 :AT x%,2 :PRINT h$ ENDIF ENDIF a%=a%+1 IF a%=x% AND c%=y% f%=0 DO AT x%,y% :PRINT CHR$(170+f%) BEEP 10,100+f% f%=f%+1 : BEEP 10,100-f% UNTIL f%=30 b%=b%+5 : a%=16 :x%=x%-2 IF x%<1 :CLS :PRINT "GAME OVER" PRINT "SCORE:",sc% :PAUSE 40 WHILE KEY :GET :ENDWH GET :RETURN ENDIF ENDIF UNTIL a%=16 sc%=sc%+1 IF b%>12 :b%=b%-2 ELSEIF b%<6 IF b1% AND b% :b%=b%-1 :b1%=0 ELSE b1%=1 :ENDIF ELSE b%=b%-1 :ENDIF UNTIL c%=3
igame: udg:(0,0,0,28,30,30,30,28,0) udg:(1,0,0,14,31,30,31,14,0) udg:(2,0,0,7,14,12,14,7,0) udg:(3,0,0,3,7,6,7,3,0) udg:(4,0,0,1,3,3,1,0.0) udg:(5,0,0.0,1,1,1,0,0) udg:(6,0,0,24,16,4,16,24,0) udg:(7,30,14,4,14,30,14,11,25)
udg:(x%,a%,b%,c%,d%,e%,f%,g%,h%) POKEB $180,64+x%*8 :POKEB $181,a% POKEB $181,b% :POKEB $181,c% POKEB $181,d% :POKEB $181,e% POKEB $181,f% :POKEB $181,g% POKEB $181,h%
During a working day, most people accumulate a number of tasks that must be done. You may also make plans to do things in the future. It would probably help if you could sit down from time to time and organise these 'things to do' in some kind of sequence, perhaps order them by priority.
The Organiser of course offers the ideal solution, as it is portable and can store all of these tasks. By using a program such as the one below, the tasks can easily be entered and displayed in order of priority.
In the example, 'THINGS TO DO', you may enter tasks to be performed with one of three levels of priority, urgent tasks, things that must be done, and those to attempt if you have the time. The program also date-stamps the entries so you know how long a particular task has been in the computer.
A simple report facility has been provided for each priority category. The entries may be edited and their priorities changed. A delete option is also provided for when a task has been completed.
The program has a main section, the procedure things:, and calls the two procedures pri: and edittask:. These also demonstrate the global nature of field variables in a procedure which accesses a data file.
things: REM **THINGS TO DO** LOCAL option%,t%,file$(10),search$(20),ed$(100) PRINT "ENTER FILE NAME:"; AT 1,2 :INPUT file$ IF EXIST(file$) OPEN file$,a,des$,pri$,dy%,mn% ELSE CREATE file$,a,des$,pri$,dy%,mn% ENDIF begin:: option%=MENU("INPUT,REPORT,EDIT,QUIT") CLS IF option%=1 GOTO enter:: ELSEIF option%=2 GOTO report:: ELSEIF option%=3 edittask: ELSEIF option%=4 CLOSE :RETURN ENDIF GOTO begin:: enter:: REM **ENTER TASK** PRINT "TASK TO BE DONE:"; AT 1,2 :INPUT a.des$ IF LEN(a.des$)=0 GOTO begin:: ENDIF pri: a.dy%=DAY : a.mn%=MONTH APPEND GOTO begin:: report:: REM **BUILD REPORT** option%=MENU("URGENT,MUST,IF,RETURN") CLS IF option%=1 FIRST PRINT "URGENT" DO IF UPPER$(a,pri$)="U" VIEW(2,a.des$+" on "+num$(a.dy%,2)+"/"+num$(a.mn%,2)) ENDIF NEXT UNTIL EOF ELSEIF option%=2 FIRST PRINT "MUST BE DONE" DO IF UPPER$(a,pri$)="M" VIEW(2,a.des$+" on "+num$(a.dy%,2)+"/"+num$(a.mn%,2)) ENDIF NEXT UNTIL EOF ELSEIF option%=3 FIRST PRINT "IF POSSIBLE" DO IF UPPER$(a,pri$)="I" VIEW(2,a.des$+" on "+num$(a.dy%,2)+"/"+num$(a.mn%,2)) ENDIF NEXT UNTIL EOF ELSEIF option%=4 GOTO begin:: ENDIF GOTO report::
The procedure pri: follows; this allows only the selection of 'U', 'M' or 'I' for the field a.pri. You will notice that it makes use of only one local variable, and only accesses the field vairables defined in the main things: procedure.
pri: LOCAL t% CLA\AT 1,1 :PRINT a.des$ t%=1 WHILE t% AT 1,2 :PRINT "Urgent/Must/If: " :a.pri$=get$ IF UPPER$(a.pri$)="U" t%=0 ELSEIF UPPER$(a.pri$)="M" OR UPPER$(a.pri$)="I" t%=0 ENDIF ENDWH RETURN
The following procedure, edittask:, performs the editing functions for the program:
edittask: LOCAL option%,search$(16),ed$(100) FIRST edit:: option%=MENU("EDIT,DELETE,RETURN") CLS IF option%=1 PRINT "EDIT CLUE:" AT 1,2 :INPUT search$ CLS IF FIND(search$)=0 PRINT "Not found" :GET$ :GOTO edit:: ELSE PRINT "EDIT:" ed$=a.des$ AT 1,2 :EDIT ed$ a.des$=ed$ pri: UPDATE ENDIF ELSEIF option%=2 PRINT "DELETE:" AT 1,2 :EDIT search$ IF FIND(search$)=0 CLS :PRINT "Not found" :GET$ :GOTO edit:: ELSE VIEW(2,a.des$) :ERASE ENDIF ELSEIF option%=3 RETURN ELSE GOTO edit:: ENDIF
This procedure is taken from The Finance Pack which, as the name suggests, contains programs suited to a financial environment. Two of the procedures in the Finance Pack make use of the following procedure, row:. This sets up a one dimensional spreadsheet on the screen of the Organiser. The procedure shows how a procedure can effectively take control of the screen and keyboard of the machine and displays the power and flexibility of screen handling possible within OPL.
Each key press is examined in turn and the procedure then acts accordingly.
The one-dimensional spreadsheet is displayed on the bottom line of the screen. The bottom line shows the contents of the first three cells, (initially zero) and the top line shows the message:
use ← → MODE=end
As the message indicates, you may now use the cursor keys to view and edit the contents of the cells of the spreadsheet. Use individual presses of the LEFT or RIGHT cursor keys to move one cell at a time, or hold the cursor keys down to move quickly along the row of cells. To enter positive numbers (receipts), just position the cursor in the appropriate cell and type the number. To enter negative numbers (payments), preface the number with a minus sign. Each cell in the sheet is four spaces wide, allowing entries up to plus or minus 9999 to be made. These figures may represent pounds, hundreds, thousands. millions or whatever multiple suits the size of your application.
Enter numbers in the cells and move to the right and left by using the cursor keys. The contents of any cell may be edited by returning to it and entering a new value. When the cursor is moved to any cell other than the leftmost one, the display changes to show the cell numbers on the top line of the screen.
row: LOCAL a%(99),m%,n%,j%,g%,z$(1),s$(3,5),p%,minus% CLS :KSTAT 4 z$=chr$(124) :n%=99 m%=1 :j%=1 :p%=0 :minus%=1 DO s$(j%)=NUM$(a%(j%),-5) IF LEFT$(s$(j%),1)=" " s$(j%)=z$+RIGHT$(s$(j%),4) ENDIF j%=j%+1 UNTIL j%=4 '%=1 REM - REDRAWS SCREEN AFTER EACH KEY PRESS DO AT 1,1 IF m%<>1 PRINT CHR$(14);z$,NUM$(m%+1-j%,-2),z$,NUM$(m%+2-j%,-2); PRINT " ";z$,NUM$(m%+3-j%,-2),z$ ELSE :PRINT" use ";CHR$(127);CHR$(126);" MODE=end" ENDIF AT 1,2 PRINT s$(1);s$(2);s$(3);z$ IF minus%=-1 AND p%=0 AT (5*j%-3),2 :PRINT " -"; ENDIF AT 5*j%,2 CURSOR ON REM - WAITS AND DETECTS EACH KEY PRESS g%=GET REM ESCAPE ALL CLEAR KEY PRESSED IF g%=1 or g%=2 CLS : RETURN REM - RIGHT ARROW PRESSED ELSEIF g%=6 IF j%=3 AND m%<n% m%=m%+1 :s$(1)=s$(2) s$(2)=s$(3) :s$(3)=NUM$(a%(m%),-5) IF LEFT$(s$(3),1)=" " s$(3)=z$+RIGHT$(s$(3),4) ENDIF ELSEIF j%<3 j%=j%+1 :m%=m%+1 ENDIF p%=0 minus%=1 REM - LEFT ARROW PRESSED ELSEIF g%=5 IF j%=1 AND m%>1 m%=m%-1 :s$(3)=s$(2) s$(2)=s$(1) :s$(1)=NUM$(a%(m%),-5) IF LEFT$(s$(1),1)=" " s$(1)=z$+RIGHT$(S$(1),4) ENDIF ELSEIF j%>1 j%=j%-1 :m%=m%-1 ENDIF p%=0 minus%=1 REM - EXECUTE PRESSED ELSEIF g%=13 p%=0 :minus%=1 REM - MINUS KEY PRESSED ELSEIF g%=%- p%=0 minus%=-1 AT (5*j%-3),2 PRINT " -"; REM - NON NUMERIC KEY PRESSED - DO NOTHING ELSEIF g%<48 OR g%>57 REM NUMERIC KEY - WRITE TO SCREEN AND ADD TO NUMBER ELSEIF p%<>4 IF p%=0 a%(m%)-0 ENDIF IF a%(m%)>0 AND minus%=-1 a%(m%)=-a%(m%) ENDIF a%(m%)=a%(m%)*10+minus%*(g%-48) p%=p%+1 s$(j%)=NUM$(a%(m%),-5) IF LEFT$(s$(j%),1)=" " s$(j%)=z$+RIGHT$(s$(j%),4) ENDIF ENDIF UNTIL 0
This program will mute the buzzers produced by both the top level and the diary alarms. If you are going into a meeting or a concert hall where a beeping sound would be unwelcome, use this program to disable all sounds from the Organiser.
mute: LOCAL option% option%=MENU("MUTE,BUZZ") IF option%=1 POKEB 164,255 ELSE POKEB 164,0 ENDIF
Most OPL commands require one or more arguments. The arguments may be numeric or string depending on the command used, and either literal values or variables may usually be used.
In this and the following chapter on the OPL functions, the following method of specifying the syntax of a command has been used:
|<exp>||numeric expression, variable or literal|
|<exp%>||integer expression in the range -32768 to +32767, integer variable or literal|
|<exp$>||string expression or variable|
|<dev>||device (A:, B: or C:)|
|<var>||variable (integer, floating point or string)|
|<logfnam>||logical file name (A, B, C or D).|
|<statement list>||One or more OPL statements on one or more
lines of the procedure. Multi-statement lines are
allowed, the statements must be separated by a
space followed by a colon in the form:
statement :statement :statement
If more than one of the same type of expression is required then these will be numbered thus:
The current field values are appended to the current file as a new record.
See also: ERASE, FIRST, NEXT, POSITION, POS, UPDATE
Positions the cursor at the screen position corresponding to <exp%1>, <exp%2> where <exp%1> is the number of characters across the screen in the range 1 to 16, and <exp%2> (1 or 2) for the top or bottom line.
See also: PRINT, CURSOR, KSTAT
Sounds the internal buzzer of the Organiser with a period of <exp%1> for <exp%2> milliseconds.
[Frequency = 921100/(78+2*<exp%1>) Hz]. The frequency of the sound is determined by the equation Frequency = 921100/(78+2*<exp%2>) Hz. The sound duration is <exp%1> milliseconds.
Allows program control to break out of a DO/UNTIL or a WHILE/ENDWH loop, and to continue the execution of the program at the instruction following the terminator of the loop (UNTIL or ENDWH).
Closes the current file.
See also: OPEN, CREATE, DELETE
Clears the display screen, and returns the cursor to the home position, at the first character space on the top line of the window.
Used to return program control to the test expression of either a DO/UNTIL or a WHILE/ENDWH loop. In the above example, the CONTINUE command will be executed if the expression following the IF statement returns logical true. In this case, program control will then be transferred to the test expression following the UNTIL instruction.
|Syntax:|| COPY "<dev1>filename1","<dev2>filename2"
Enables whole files to be copied from one device to another. In the first example, the file on device <dev1> with the name filename1 is copied to device <dev2> into a file called filename2.
If there is already a file on the destination device with the same name as given by the second parameter (filename2) then the records from the source device are appended to the existing file on the destination device. Otherwise a new file is created with that name and the records written to it.
In the second example, the file name on the destination device is taken to be the same as that on the source device. In this case, filename1.
In the third example, all files on the source device are copied onto the destination device, and are given the same names on the destination device as they held on the source device.
Create a file on device <dev>, with the name fname, the logical file name <logfnam> , and up to 16 fields as specified by fldnm1, fldnm2 etc. The logical file name may be A, B, C or D. Each newly created file is OPEN by default, and up to four files may be open at any one time.
See also: OPEN, CLOSE, DELETE
|Syntax:||CURSOR ON or CURSOR OFF
Switches the cursor on or off, the default setting is CURSOR OFF
See also: KSTAT
Deletes a file with the name filename from device <dev>. The file must be closed before this command is given.
See also: CREATE, OPEN, CLOSE. DELETE
The DO command is used to indicate the start of a list of one or more statements which terminate with the UNTIL command. The list of statements will be repeated until the expression after the UNTIL command returns logical true.
See also: WHILE/ENDWH, BREAK, CONTINUE
The string variable <var$> is displayed on the screen, and may then be edited in the usual way by using the cursor keys and the DEL key. When editing has been completed, pressing the EXE key returns the edited string, if the EXE key is pressed without any editing being performed on the string then the same string will be returned as was included inside the brackets. If the ON/CLEAR is pressed during editing, the string will be cleared and new text may be typed. However, if the TRAP command is used with this command, control will pass on to the next line of the procedure with the ESCAPE error condition being set.
Erases the current record in the current file. Following this command, the current record will be the record after the one just deleted. If the erased record was the last record in a file, then following the ERASE command, the current record will be null and EOF will return true.
|Syntax:||ESCAPE ON / ESCAPE OFF
The ESCAPE ON command enables the ON/CLEAR key to be used to halt a program which is currently executing. The default state is ESCAPE ON. The ESCAPE OFF has the reverse effect, disabling the ON/CLEAR key while a program is running. The default condition is ESCAPE ON.
Note. If your program enters a loop which has no logical
exit, and the ESCAPE OFF command has been used, then
there will be no way to exit that loop except to remove the
battery from the Organiser and wait two minutes, The
program and all other data in the RAM of the machine will be
Makes the first record in a file the current record.
See also: NEXT, POSITION, POS, BACK
Used to define variables which will be available in the current procedure and any procedure below it in the program. Variable names ending with a percent sign (%) are declared as numeric integers; those ending with a dollar sign ($) are declared as string variables and all others are declared as floating point numeric variables.
Array variables may be of any of the above three types.
Variable names may be up to 8 alphanumeric characters
long, the first of which must be a letter. This length includes
the type identifier, eg. % or $. More than one GLOBAL or
LOCAL statement may be used, but only in that order and
must precede the instructions which make up the
procedure. See the chapter on variables for more
Sends the program control to the line containing the label name supplied by label::. The label name must be in the current procedure, and must end with a double colon. Labels may be up to 8 characters long excluding the colons.
|Syntax:|| IF <exp>
IF statements are immediately followed by an expression. If the result of that expression returns logical true, (non-zero) then the statements following are executed. If the expression returns logical false (zero) then those statements are ignored.
The ELSEIF statement is optional, but if it is included, and the following expression returns logical true, then the next list of statements are executed. There may be more than one ELSEIF, each with its own list of statements.
If none of the preceding expressions have returned logical true, then the list of statements after the ELSE statement and before the ENDIF statement are executed. The ELSE statement is optional.
|Syntax:|| INPUT <var%>
Allows data to be input from the keyboard during program execution. The variable supplied must have previously been declared with the GLOBAL or LOCAL commands, or be a field variable of the current file. If inputting to a string variable, only as many characters as have been set aside for that variable with the GLOBAL or LOCAL commands may be entered.
If the ON/CLEAR key is pressed during editing, the input
so far will be cleared and new data may be typed. However,
if the TRAP command is used with this command, control
will pass on to the next line of the procedure with the
ESCAPE error condition being set.
Sets the state of the keyboard, ie in SHIFT mode, CAPS mode etc, according to the following table:
Used to define variables which will only be available in the current procedure. Other procedures may use the same variable names for other uses.
See also: GLOBAL
Makes the next record the current record in the current file. If use of NEXT is continued beyond the end of a file, no error is reported but the current record will be a null record and the EOF function will return true.
See also: FIRST, BACK. ERASE. APPEND, UPDATE, POSITION, POS
The Organiser is switched off by this command. Pressing the ON/CLEAR key will resume program execution at the program line following the OFF command.
Opens an existing file on device <dev>, with the logical file name <logfnam>, with the field names as specified by fldnm1, fldnm2 etc. That file may then referred to by the logical file name for all file handling operations.
See also: CREATE, CLOSE, DELETE, USE
|Syntax:||ONERR label:: / ONERR OFF
In the event of an error being generated during program execution, the ONERR label:: instruction will transfer program control to the program line containing that label. The ONERR OFF instruction cancels the ONERR statement as set with ONERR label::, so that any errors occurring below the ONERR OFF statement are no longer referred to the same place in the procedure.
If <exp%> is:
<statement list> PAUSE 0 GET <statement list>The procedure will not pause at the GET function in the usual way because the key press stored in the butter from the PAUSE 0 command is taken as the input for GET.
Writes the integer <exp%2>, which must be in the range 0 to 255, into the memory address <exp%1>, which must be an integer. Addresses above 32767 are addressed by negative values or hexadecimal numbers. Eg, $FFFF=-1, which corresponds to address 65535.
Note. Casual use of this command can result in the loss of
all data in the Organiser.
Writes the integer <exp%2> into two successive memory addresses, starting with the address <exp%1>, with the most significant byte in the lower address.
Note. Casual use of this command can result in the loss of
all data in the Organiser.
Makes record number <exp%> the current record in the current file. If <exp%> is greater than the number of records in the file then makes the last record current.
See also: POS, FIRST, NEXT, ERASE, APPEND, UPDATE
Prints numbers or text to the screen. If items in the PRINT statement are separated by commas then a space is inserted between the items as they appear on the screen. If items in the list are separated by semi-colons then there will be no spaces between items in the output.
A final semi-colon indicates that the next item to be printed will start immediately after this PRINT statement. A final comma indicates that the next item to be primed will follow on the same line with a space inserted between the items. Otherwise the next line is used.
The LPRINT command (only available when a Psion
Organiser II RS232 cable is connected to the peripheral port
at the top of the Organiser) operates in the same way as the
PRINT command except all output is sent to a printer,
if connectedthe device
connected to that cable.
Artificially generates an error, even though no such error has occurred. If no ONERR statement has been issued previously then the appropriate message for that error number is displayed. The range of possible internal errors is 195 to 255. Refer to the chapter on error handling for a full list of error numbers and messages.
See also: ONERR, ERR, ERR$
Gives a new seed value to the random number generator. so that a new sequence of random numbers will be initiated. So use RANDOMIZE if you wish to use the same sequence of random numbers more than once.
|Syntax:||REM this is a remark
The REM statement precedes a REMark which contains information designed to make the program easier to follow. The Organiser ignores all text after the REM statement up to the end of that line.
Renames a file on device <dev> called filename1 as the file filename2.
Used on its own, the RETURN command terminates the execution of a procedure and returns control to the point where that procedure was called. Use of this command at the end of a procedure is optional.
The RETURN command may also be used to pass a value back to the level from which the procedure was called. The value must be supplied after the RETURN command.
Halts execution of the language and returns the Organiser to the point where that program was started, eg the main menu or the CALC option in the main menu.
(APPEND/BACK/CLOSE/COPY/CREATE/DELETE/ ERASE/EDIT/FIRST/INPUT/LAST/NEXT/OPEN POSITION/RENAME/UPDATE/USE)
TRAP may precede any command in the above list. Any error resulting from the execution of that command will then be trapped, the next program line will then be executed regardless of whether the error would normally have caused an error message to be displayed.
The current record in the current file is deleted and the current field values are appended as a new record. The last record in that file is then current.
See also: APPEND
Selects for use the file with the logical file name <logfnam> , which must previously have been opened with the OPEN or CREATE command.
See also: OPEN, CLOSE. CREATE, DELETE
|Syntax:||WHILE <exp> <statement list> ENDWH
This structure is started by the WHILE command which precedes an arithmetic expression. The subsequent list of statements, which must end with the ENDWH statement, is executed while the expression returns logical true (non-zero).
See also: DO/UNTIL
The convention used throughout this manual is that the receiving variable denotes the return type of the function. So a function shown here assigned to a string variable will return a string and so on.
Returns the absolute value, ie, without any sign, of a floating point number. Eg ABS(-10) is 10.
See also: IABS
Returns the address at which the variable inside the brackets is stored in memory. The variable may be an array. eg a%=ADDR(ARRAY()); subscripts may not be included; the base address of the array is returned.
See also: USR, USR$
Returns the ASCII value of the first character of a string expression. Alternatively, if the ASCII code for one character is required, then the form a%=%AG may be used. In this example, the ASCII code for the letter AG is returned.
Returns the arctangent of the expression inside the brackets in radians.
Returns the cosine of the expression inside the brackets. The expression represents an angle expressed in radians.
Returns the total number of records in the current file.
See also: POS, POSITION
Returns the number of the current day of the month (1 to 31).
See also: SECOND, MINUTE HOUR, MONTH, YEAR, DATIM$
Returns the value of the expression in the brackets, representing an angle measured in radians, as a number of degrees.
See also: RAD
The value of <exp%> may be -1, 0 or 1. If the value of <exp%> is -1 then <exp$> is ignored and the current record is displayed with one field on each line of the display. The cursor keys may be used to scroll around the record as in the top level records. If <exp%> is 1 then <exp$> is displayed as above. If <exp$> contains tab characters (ASCII character 9), these divide the string into a number of fields so the string is displayed on a number of lines.
If <exp%> is 0 then the last DISPlayed string or record is continued and <exp$> is ignored. If any key other than the cursor keys are pressed then the number of that key is returned.
No other commands or functions should be used between using DISP with <exp%> equal to 1 or -1 and DISP with <exp%> equal to 0. For example:
a%=DISP(1,a$) WHILE a%<>13 a%=DISP(0,"") ENDWH
This waits for the EXE to be pressed and continues displaying a$ until this happens. Clearly there can be no reason to use any other command or function which accesses the screen in between the two uses of DISP. Doing so may have unpredictable results.
Any program instruction which tries to read past the last record in a file will result in an internal flag being set to show that the End Of File (EOF) has been reached. This can then be tested, as above. For example:
DO <statement list> UNTIL EOF
Returns the number of the last error which occurred. See the chapter on error messages to determine the meaning of each of the error numbers. The number returned will be in the range 0 to 255. If 0 is returned, there is no error.
See also: ERR$, RAISE, ONERR
Tests for the existence of a file on device <dev> called filename. Returns logical true if the file exists and logical false otherwise. For example:
IF EXIST("<dev>filename") <statement list> ENDIFSee also: DIR$
Returns the value of the arithmetic constant e (2.71828...) raised to the power of the expression inside the brackets.
Searches forwards in the current file tor the string inside the brackets. If found, returns the record number where that string occurs, and makes that record current. If no such string is found, zero is returned. If <exp$> is a null string, the command operates like the NEXT command and makes the next record current.
See also: NEXT
Converts the integer expression inside the brackets into a floating point number.
Returns the number of free bytes in the built in memory of the Organiser.
See also: SPACE
Waits for a key to be pressed and returns the ASCII value of that key.
See also: GET$, KEY, KEY$, PAUSE
Returns the number of the current hour from the system clock (0 to 23).
See also: SECOND, MINUTE, DAY, MONTH, YEAR, DATIM$
Returns the absolute value, ie, without any sign, of an integer. Eg ABS(-10) is returns 10.
Returns the integer (ie the whole number part) of the expression inside the brackets. Negative numbers are rounded down, so INT(-5.3) will return the result -6 . Used when the returned value will be within the Organiser's integer range.
See also: INTF
Used in the same way as the above function, but the value returned is a floating point number and is used when the returned result will be outside OPL's integer range.
See also: INT
Returns the ASCII value of any key pressed, if any. If no key is pressed, zero is returned. This command does not wait for a key to be pressed.
See also: PAUSE, GET, GET$, KEY$
Returns the length of the string expression inside the brackets.
See also: LEFT$, RIGHT$, MID$, LOC, LOWER$, UPPER$, REPT$
Returns the natural (base e) logarithm of the expression inside the brackets.
Returns the position in <exp$1> that <exp$2> occurs. If the second string expression does not occur in the first string expression, then the value zero is returned, eg. LOC("STANDING","TANAND") would return the value 23 because the substring "TANAND" starts at the secondthird character of the main string.
See also: LEFT$, RIGHT$, MID$, LEN, LOWER$, UPPER$, REPT$
Returns the base 10 logarithm of the expression inside the brackets.
See also: LN
The string inside the brackets takes the form "item1,item2,item3...", and is displayed in the manner of the main menu. Allows a selection to be made from the menu in the usual way with cursor keys or the initial letter of the selected item, and returns the number of the item selected (1 to ...). If the ON/CLEAR key is pressed, 0 is returned.
Returns the current minute number from the system clock (0 to 59).
See also: SECOND, HOUR, DAY, MONTH, YEAR, DATIM$
Returns the current month from the system clock (1 to 12).
See also: SECOND, MINUTE, HOUR, DAY, YEAR, DATIM$
|PEEKB (Peek byte)|
Returns the value stored at the address specified by the expression inside the brackets. The value returned will be in the range 0 to 255.
See also: PEEKW, POKEB, POKEW
|PEEKW (Peek word)|
Returns the value of the two byte integer stored at addresses <exp%> and <exp%>+1.
See also: PEEKB, POKEB, POKEW
Returns the value of Pi (3.142... ).
Returns the number of the current record in the current file.
See also: POSITION, FIRST, NEXT, ERASE, APPEND, UPDATE
Converts <exp> from degrees to radians.
See also: DEG
Returns the number of bytes occupied by the current record. No record may contain more than 254 characters, so this function may be used to check that a record may have data added to it without overstepping this limit.
Returns a random floating point number in the range 0 (inclusive) to 1 (exclusive).
See also: RANDOMIZE
Returns the current number of seconds from the system clock (0 to 59).
See also: MINUTE, HOUR, DAY, MONTH, YEAR, DATIM$
Returns the sine of the expression inside the brackets. The expression represents an angle expressed in radians.
Returns the number of free bytes on the current device. There must be a file open on the current device for this function to operate.
See also: FREE
Returns the square root of the expression inside the brackets.
Returns the tangent of the expression inside the brackets. The expression represents the angle expressed in radians.
The value of <exp%2> is passed to the D register and the value of <exp%1> is passed to the PC register of the HD6303X microprocessor. The microprocessor then executes the machine language program starting at the address <exp%1>. At the end of the routine, the value in the X register is passed back to the language as an integer.
Note. Casual use of this command can result in the loss of all data in the Organiser.
See also: USR$, ADDR
Returns a floating point number which is the value of the string expression inside the brackets, eg VAL("470.0") would return the integer 470.0. A string containing any non-numeric characters would return an error. Scientific notation is allowed, so VAL("1.3E10") would return the value 1.3E10.
Displays <exp$> on line number <exp%> (1 or 2) on the screen. If the text is longer than 16 characters, the display auto-scrolls to the left, and pressing the left or right cursor keys allows you to change the direction of the scroll. Pressing any other key halts the scrolling of the text and returns the ASCII value of the key pressed. If VIEW is used again with <exp$> being a null string then viewing is continued at the point it was interrupted by a key press.
See also: DISP
Returns the current year from the system date (1900 to 1999).
See also: SECOND, MINUTE, HOUR, DAY, MONTH, DATIM$
Returns the ASCII character with the value of the expression inside the brackets.
Returns the current date and time from the system clock in string format; eg "MON 17 FEB 1986 16:25:30"
See also: SECOND, MINUTE, HOUR, DAY, MONTH, YEAR
|Syntax:||d$=DIR$("<dev>") / DIR$("")
The use of DIR$(<dev>) returns the name of the first file on the device specified in brackets. The device name (A, B or C) must be enclosed in double quotation marks and brackets. Subsequent uses of this function with a null string in the brackets will return the following file names, until there are no files left on that device, when the function will return a null string.
Returns a string which describes one of the errors which can arise during program execution. The ERR function returns the number of the error and ERR$ can then be used to access the relevant error message. If a number outside the range 195 to 255 is used, the error string returned is "*** ERROR ***".
See also: ERR, ONERR, RAISE
Returns a string representation of <exp> , with <exp%1> decimal places in a field which is <exp%2> characters wide. If <exp%2> is negative then the string is right justified. So:
FIX$(123456.127,2,9) = "123456.13"
FIX$(1,2,-5) = " 1.00"
If the number will not fit in the field width specified then the returned string will contain asterisks.
See also: GEN$, NUM$, SCI$
Returns a string representation of <exp> in a field of width <exp%> characters. GEN$ tries to represent the number as integer, decimal or scientific, in that order. If the value of <exp%> is negative then the result will be right justified. If the number will not fit in the field width specified then the returned string will contain asterisks.
See also: FIX$, NUM$, SCI$
Waits for a key to be pressed and returns that key as a string. So if the A key is pressed in lowercase mode, the string returned will be "a".
See also: GET, KEY, KEY$
Returns the hexadecimal (base 16) version of the integer expression inside the brackets, eg HEX$(255) will return "FF".
Returns a string containing the key pressed, it any. If no key is pressed, a null string is returned. This command does not wait for a key to be pressed.
See also: KEY, GET, GET$
Returns the leftmost <exp%> characters from the string specified by <exp$>.
See also: RIGHT$, MID$, LOC, LOWER$, UPPER$, LEN.
Converts any upper case characters in the string expression inside the brackets to lower case and returns the completely lower case string.
See also: UPPER$, LEFT$, RIGHT$, MID$, LOC, LEN, REPT$
Returns a string comprising <exp%2> characters of <exp$>, starting at the character at position <exp%1>. See chapter on string slicing.
See also: LEFT$, RIGHT$, LEN, LOWER$, UPPER$, LOC, REPT$
Returns a string representation of the floating point number <exp> as an integer in a field <exp%> characters wide. If the number will not fit in the field width specified then the returned string will contain asterisks.
See also: FIXS, GEN$, SCI$
Returns the rightmost <exp%> characters of <exp$>.
See also: LEFT$, MID$, UPPER$, LOWER$, LOC, LEN, REPT$
Returns a string comprising <exp%> repetitions of <exp$>.
See also: LEFT$, RIGHT$, MID$, UPPER$, LOWER$, LOC, LEN
Returns a string representation of <exp> in scientific format, to <exp%1> decimal places in a field of width of <exp%2> characters. For example:
SCI$(123456,2,8) = "1.23E+05"
SCI$(1,2,8) = "1.00E+00"
SCI$(l23456789,2,-9) = " 1.23E+08"
If the number will not fit in the field width specified then the returned string will contain asterisks.
See also: FIX$, GEN$, NUM$
Converts any lower case characters in the string expression inside the brackets to upper case and returns the completely upper case string.
See also: LEFT$, RIGHT$, MID$, LOWER$, LOC, LEN, REPT$
The value of <exp%2> is passed to the D register and the value of <exp%1> is passed to the PC register of the HD6303X microprocessor. The microprocessor then executes the machine language program starting at the address <exp%1>. At the end of the routine, the value in the X register must point to a length-byte preceded string. This string is then returned to the assigned variable.
Note. Casual use of this command can result in the loss of all data in the Organiser.
See also: USR, ADDR
The Psion Mains Adaptor allows you to power your Organiser II directly from the 220/240 Volt mains supply. Simply fit the adaptor into the slot at the top of the Organiser II, attach the cable, plug the power supply unit into the wall socket and switch on.
The Mains Adaptor unit may be used with or without a battery being present in the Organiser. But remember that if you are using your Organiser without a battery, the contents of the main memory will be lost when you switch off. For this reason it is advisable to keep a battery installed in the Organiser. With a battery fitted, the power required to run your application will be drawn only from the mains supply, and you data will be protected against accidental loss.
Each Psion peripheral device fro you Organiser II is supplied with an adaptor incorporating a socket for mains power input. When using any of these devices, the cable from the power unit should be plugged directly into the socket on the peripheral adaptor.
Note: The Mains Adaptor unit does not recharge batteries even if rechargeable batteries are fitted in the Organiser. Such batteries must be removed from the Organiser for external charging.
The character set of the Organiser is shown in the table overleaf. The characters used most often are accessible from the keyboard in the usual way, but there are many more characters which may be used but cannot be typed in directly, including accented and Greek characters.
These are accessed via the CHR$ function. By supplying the function with a number between 0 and 255, you can print out to the screen or the printer, or assign to string variables, any of the characters shown.
The characters numbered 0 to 7 are user definable. That means that you can define the pattern of dots which appear on the screen when you access those characters with the CHR$ function.
Each character is defined by a series of eightseven bytes, which must be poked into a particular memory location. From each of the eightseven bytes which make up the characters, the least significant five bits are used to define the shape of the character as shown belowin Figure 11. The dots comprising the top line of the character are taken from the first byte poked into address $181.
Figure 10 Organiser character set
Figure A.111 defining a pound character.
A program called UDG: (User Defined Graphics) to define these characters is shown below. When this is run, it will write the patterns you give it into memory where they will stay until you use the program again to change them. However, they do not have tomust be re-inserted every time you use the machine.
UDG: GLOBALLOCAL numb%,count%,byte%(8) start:: PRINT "CHAR NO. "; INPUT numb% count%=1 DO PRINT "BYTE NO. ";count% INPUT byte%(count%) count%=count%+1 UNTIL count%=8 PRINT "SAVING CHAR..." POKEB $180,64+(numb% AND 7)*8 count%=1 DO POKEB $181 ,byte%(count%) count%=count%+1 UNTIL count%=8
Note. On the Organisers screen, the bottom line of any character space is left blank to allow room for the underscore cursor to be clearly distinguished from the character itself.
Those characters with ASCII codes between 8 and 16 have special uses. These will not produce a visible character on the screen, but may be used to affect parts of the screen in the ways listed:
|CHR$(8)||Moves cursor 1 character to the left and deletes any character in that position.|
|CHRS(9)||Moves the cursor to the nearest position modulo 8|
|CHR$(10)||Moves the cursor to the next line|
|CHR$(11)||Moves the cursor to the top left ('home' position) of the display|
|CHR$(12)||Clears the display (equivalent to CLS)|
|CHR$(13)||Moves the cursor to the left of the current line|
|CHR$(14)||Clears the top line of the display and moves the cursor to the top left|
|CHR$(15)||Clears the bottom line of the display, moves the cursor to the bottom left|
|CHR$(16)||Sounds the Organiser's buzzer|
When the GET and KEY functions are used, the numbers returned correspond to the ASCII (American Standard Code for Information Interchange) code for the particular character the key represents.
The keys below do not appear in the ASCII set, but may still be read with the above functions. The table gives the numbers returned by each key:
|7||SHIFT and DEL|
If you cannot see anything in the display when you switch on, follow these steps until something appears in the display.
If the display is alright but the keys seem to have no effect:
Note. In this event you will lose any data stored in the Organiser.
|ROM||Model CM||32 Kbytes|
|Model XP||32 Kbytes|
|RAM||Model CM||8 Kbytes|
|Model XP||1632 Kbytes|
|EPROM||8/16/32/64 Kbytes (model CM.|
Up to 128 Kbytes model XP)
|Storage medium||EPROM (Erasable, Programmable, Read Only Memory)|
|Data retention||'Mean time to failure' 50 years at temperatures up to 100°C|
|Formatting||30 minutes in Psion Formatter - prepares Datapak for re-use|
|Life||Can be re-formatted up to 100 times|
|Memory capacity||8K Datapak||8192 bytes|
|16K Datapak||16384 bytes|
|32K Datapak||32768 bytes|
|64K Datapak||65536 bytes|
|128K Datapak||131072 bytes (Model XP only)|
Psion has a policy of continuous product development. Small modifications arising from this are not necessarily reflected in this manual
The Organiser's CPU (Central Processor Unit) is the HD6303X microprocessor. This advanced processor can be programmed directly, in its own language called machine language or machine code.
Machine language programs run far faster than OPL programs and take up less memory, but they are much more difficult to write and de-bug. Also, a simple mistake in a machine language program can easily wipe out all of the information stored in the internal memory of the Organiser, as these programs take over full control of the chip at the heart of the machine.
In case of such a problem, it is wise to save all important data to a datapack before testing machine language programs, so that all will not be lost it the machine loses all its data, or 'crashes'.
The following list of addresses are used by the Organiser to store certain system variables. These can be accessed by using the PEEKB, PEEKW, POKEB and POKEW commands:
|$0069,$006A||($04)||Horizontal scroll delay counter|
|$006B,$006C||($0A)||Vertical scroll delay counter|
|$0077||($0E)||Delay before keyboard auto-repeat|
|$0078||($00)||Keyboard auto-repeat counter|
|$007C||non-zero||Auto-switch off flag - zero deactivates auto-switch off|
|$20CB,$20CC||Frame cCounter, Increments every 50ms|
|$20CD,$20CE||($012C)||Default number of seconds to auto-switch off|
|$00A4||($00)||Buzzer mute - non-zero value mutes buzzer|
Your Psion Organiser II (excluding batteries) carries a one year warrany againt mechanical or electrical failure other than in the case of misuse or damage arising from negligence. There are no user-serviceable parts within your Organiser, and any attempt to dismantle or repair your Organiser other than by an appointed Psion Service Agent will invalidate this warranty. Fill in and return the reply-paid card immediately to register your warranty.
Should you experience any problems, consult this manual with particular reference to the troubleshooting section. If you find no solution to your problem send your Organiser in suitably protective packaging to:
18 Harcourt Street
We accept no responsibility for goods damaged in transit to us. This warranty does not affect your statutory rights.
A range of peripherals and program packs are available for your Organiser MK2. Datapaks and program packs, including The Concise Oxford Spelling Checker, Finance Pack, Maths Pack, RS232 cable, Bar Code Reader and Card Swipe Reader. The range of products is constantly being updated so contact Psion tor a full list of available products.
"Concise Oxford Dictionary" Copyright Oxford University Press.
ABS function ADDR function ALARM (2) mute APPEND command (2) APR Arithmetic operators precedence Array variables numeric string ASC function AT command ATAN function Auto scrolling Auto switch off (2)
BACK command Batteries Battery compartment BEEP command BREAK command
CALC (2) Character set Characters control user defined CHR$ function (2) CLOSE command (2) CLS command (2) Comparison operators CONTINUE command Contrast wheel (2) Control characters COPY (2) COPY command (2) COS function COUNT function CREATE command (2) Cursor keys CURSOR command
Data fields input to Data file names Datapak (2) changing formatting full new DATIM$ function DAY function DEG function DELETE command (2) Devices (2) DIARY (2) alarms (2) DIR (2) ERASE (2) FIND (2) GOTO (2) LIST (2) menu PAGE (2) RESTORE (2) SAVE (2) TIDY (2) DIR$ function DISP function Display (2) (3) DO/UNTIL command (2)
EDIT EDIT command Editing records EOF function ERASE (2) ERASE command (2) ERR function ERR$ function Error common handling messages (2) ESCAPE ON/OFF command EXE key EXIST function EXP function
Field definition names qualifiers File copying MAIN names logical FIND (2) FIND function (2) FIRST command (2) FIX$ function Floating point numbers FLT function FREE function
GEN$ function GET function (2) GET$ function GLOBAL command (2) (3) GOTO command (2)
HEX$ function HOUR function (2)
IABS function IF/ELSEIF/ELSE/ENDIF command (2) INFO (2) INPUT command Input routine INT function Integers INTF function
KEY function KEY$ function Keyboard (2) KSTAT command
LAST command LEFT$ function (2) LEN function LN function LOC function LOCAL command (2) LOG function Logical expressions file names operators Loops LOWER$ function
Machine language MAIN file Menu deleting items main (2) replacing items MENU function MID$ function (2) MINUTE function (2) MONTH function Mortgage calculator
NEXT command (2) NUM$ function Numbers floating point integer
OFF (2) OFF command ONERR command OPEN command (2) OPL OPL commands APPEND AT BEEP BREAK CLOSE CLS CONTINUE COPY CREATE CURSOR DELETE DO/UNTIL EDIT ERASE ESCAPE ON/OFF FIRST GLOBAL GOTO IF/ELSEIF/ELSE/ENDIF INPUT KSTAT LOCAL NEXT OFF ONERR OPEN PAUSE POKEB POKEW POSITION PRINT/LPRINT RAISE RANDOMIZE REM RENAME RETURN STOP TRAP (2) UPDATE USE WHILE/ENDWH OPL functions ABS ADDR ASC ATAN CHR$ (2) COS COUNT DATIM$ DAY DEG DIR$ DISP EOF ERR ERR$ EXIST EXP FIND FIX$ FLT FREE GEN$ GET GET$ HEX$ HOUR IABS INT INTF KEY KEY$ LEFT$ LEN LN LOC LOG LOWER$ MENU MID$ MINUTE MONTH NUM$ PEEKB PEEKW PI POS RAD RECSIZE REPT$ RIGHT$ RND SCI$ SECOND SIN SPACE SQR TAN UPPER$ USR USR$ VAL VIEW YEAR
PAUSE command PEEKB function PEEKW function Peripheral port PI function POKEB command POKEW command POS function (2) POSITION command (2) PRINT command PRINT/LPRINT command Procedure (2) editing errors names (2) parameters qualifiers quitting saving (2) translating PROG (2) COPY (2) DIR (2) EDIT (2) ERASE (2) LIST (2) menu NEW menu QUIT SAVE TRAN RUN (2) Program Program labels
RAD function RAISE command (2) RANDOMIZE command Record advice editing erasing (2) maximum size Records RECSIZE function REM command RENAME command REPT$ function RESET (2) RETURN command (2) RIGHT$ function (2) RND function Running procedures
SAVE (2) Saving procedures SCI$ function SECOND function Semi-colon SIN function SPACE function SQR function STOP command String concatenating slicing Structures Switching off Switching on
TAN function TIME (2) setting Top level menu Translating procedures TRAP command (2)
UPDATE UPPER$ function USE command (2) User defined characters USR function USR$ function
VAL function Variable arrays conversion declaring floating point global (2) (3) integer local names string type conversion Variables VIEW function
WHILE/ENDWH command (2) WHILE/ENDWH structure
Part No. 6100-0024