Jaap's Psion II Page

When the LZ/LZ64 models were released, the manual for the CM/XP was completely re-written. Below is that renewed version of the CM/XP manual, which was used from 1989 onwards.


Psion Organiser II
Operating Manual


© Copyright Psion PLC 1988

All rights reserved. This document and the programs referred to herein are copyrighted works of Psion PLC, London, England. Reproduction in whole or in part including utilisation in machines capable of reproduction or retrieval, without the express permission of Psion PLC, is prohibited. Reverse engineering is also prohibited.

The information in this document is subject to change without notice.

Psion and the Psion logo are registered trademarks of Psion PLC.
Psion Organiser II, Datapak and Rampak are trademarks of Psion PLC.

V1 (Jan 89)
Part no. 6100-0024


Contents

The Psion Organiser II Where things are

Part 1: Using the Organiser

1 Getting started Fitting the battery Switching on The menu system Setting the time 2 Saving records What is a record? Getting used to the keyboard Saving a record 3 Finding and editing records Finding a record Looking at all the records Editing a record Erasing a record Copying a record to a different device 4 Alarms Setting an alarm Switching off an alarm Cancelling an alarm 5 The diary Moving through the pages Making a diary entry Setting an alarm on a diary entry The diary menu 6 The calculator Doing a calculation Calculator memories Editing a calculation Using a result again Built-in OPL functions in calculations OPL procedures in calculations

Part 2: Further Information

7 Customising the main menu 8 Storage devices Devices A: B: and C: Datapaks, Rampaks and internal memory The INFO Option The RESET Option 9 Records and files Copying records to different devices Files The COPY Option 10 Replacing the battery

Part 3: OPL (Organiser Programming Language)

11 Introduction to OPL The Prog menu Creating, saving and running a procedure EDIT, PRINT, DIR, ERASE, COPY 12 Procedures and variables 13 Loops and branches 14 Operators 15 Data file handling 16 Error handling 17 Example programs 18 OPL commands and functions Summary syntax List of commands and functions

Appendices

A Organiser character set B Technical Data C Technical programming D Error messages E Troubleshooting


INTRODUCTION

The Psion Organiser II is a powerful computer for your pocket.

It has its own internal memory which will retain information, even when the Organiser is switched off. In addition it has two devices which are the key to the open-ended power of the Organiser. These devices are the equivalent of disc drives on a desk-top computer. They can each hold a Datapak - for you to store your own information on, or a program pack - containing a program such as the Pocket Spreadsheet.

The internal memory of the Organiser will hold around 32000 characters of information (Model XP) or 8000 (Model CM) but the addition of one or more Datapaks can boost the storage capacity considerably - by up to 128000 characters per Datapak on Model XP or 64000 characters per Datapak on Model CM.

Datapaks provide a very secure means of storing data. Using them you can create a large and extremely secure personal information base.

The Organiser comes with a powerful set of utilities including:

The Organiser also has its own built-in programming language called OPL, specially designed to handle your database applications and to exploit all the machine's facilities to the full.

So the Organiser supersedes your personal filing system, clock, diary and calculator and puts unparalleled database processing power into the palm of your hand.

Peripherals and packs

Organiser peripherals allow you to print out information stored in your Organiser, connect it to another computer, send information over a telephone line, and much more. The range available includes:

Peripherals:
Printer
Mains adaptor
Comms Link - to link to a desk-top computer, modem or another printer
Organiser Developer - to debug OPL programs on a desk-top computer
Bar-code reader and card-swipe reader
Formatter - to clear and reformat Datapaks

Program packs:
Pocket Spreadsheet. (loads 1-2-3 files)
Oxford English Spelling Checker
Finance Pack
Maths Pack
Formulator

Storage packs:
Datapaks
Rampaks

The range is constantly expanding, so contact PSION at this address for a full list of available products:

PSION PLC
Psion House
Harcourt Street
London W1H 1DT
ENGLAND

As you learn about all the powerful facilities of your Organiser, don't be afraid to try things out - you can't harm the machine by pressing keys, so go ahead and fin out just what the Organiser can do for you.

Where things are

This is a rear view of the Organiser with the protective case removed. Devices B: and C:, which are protected by sliding covers, can each be fitted with a Datapak, a Rampak or a program pack.

This is a top view of the Organiser showing the Top Port which can be fitted with peripherals such as the Psion printer or the Comms Link:

Manual

The manual is divided into three parts:


PART 1: USING THE ORGANISER

1 Getting started

This chapter shows you how to fit the battery, switch on, choose an option from the main menu, set the time, and switch off again. There is a summary of how to do these things at the end.

Fitting the battery

The Organiser uses any 9 volt PP3 size battery. However, we recommend alkaline batteries, as they last longer.

To fit the battery:

If the battery only slides in half way, you have tried to put it in the wrong way round. Turn the battery over so that the other metal contact slides into the connector first and try again.

Warning: Never remove the battery from your Organiser or you will lose all your data. Even when the battery runs low, do not remove it until you have read Chapter 10 and you have a new one ready.

Switching on

To switch the Organiser on:

After the copyright message, the screen will show the main menu which looks like this:

FIND SAVE DIARY  CALC PROG ERASE

If you can't see anything on the screen, adjust the contrast using the contrast wheel on the right hand side of the case. You may need to adjust the contrast sometimes - for example when you switch between using the Organiser flat on a desk or holding it in your hand.

The menu system

You can already see six of the options available on the Organiser main menu. There are six more options available off the screen like this:

FIND SAVE DIARY  CALC PROG ERASE
TIME INFO ALARM COPY RESET OFF

When you select one of these options you access one of the Organiser's built-in utilities:

FIND, SAVE, and ERASE all access the database where you store information such as addresses.
CALC selects the calculator.
DIARY selects the diary.
PROG takes you to the Organiser programming language (OPL).
TIME selects the clock.
ALARM selects the alarm-setting facility.
INFO gives you a status report on memory and data.
COPY allows you to copy files of the database information.
RESET erases all data in the Organiser and resets it.
Off switches the Organiser off.

Moving around a menu

The first character of the first word on the screen is covered by a flashing block - this is called the cursor.

To move around the menu:

When the cursor is positioned on the last option visible on the screen, press → once more to see the next line of the menu.

Practice using all four arrow keys, ↑ ↓ ← and → to move between the different menu options.

Selecting options from the main menu

To select an option from the menu:

If there is more than one option starting with the same letter - as with Calc and Copy - pressing the first letter, C, only moves you between the two options. To choose one or the other, you need to press EXE when the cursor is on the one you want.

Getting back to the main menu

To get back to the main menu from any option:

Before you go on, practice moving from the main menu into the options and back again.

Setting the time

To select the Time option:

You have now entered the Time option, and the screen should look like this:

FRI 1 JAN 1988  00:00:00

To set the current time and date:

Note that the day of the week changes automatically whenever the date is changed. The day and date may not align correctly for you if you're not yet in the right month or year.

So, to change the month, year and time:

After setting the correct time and date:

The time is now set. You only need to reset it if you change time zones or the hour changes.

Whenever you want to know the correct time and date you can select TIME from the main menu.

Switching off

To switch off the Organiser you have to be on the main menu. So, if you are not on the main menu, press ON/CLEAR once or twice to get there.

Just press ON/CLEAR to switch on again.

Automatic switch-off

To conserve battery power, if you leave the Organiser on for five minutes without pressing any keys, it will switch itself off.

When this happens, don't worry. Just press ON/CLEAR once and the Organiser will come on again at the exact place it was when it went off. All your data is intact and you can carry on where you left off.

Summary

Switching on

  1. Press ON/CLEAR.

Selecting an option from the main menu

  1. Press the first letter of the option name.
or
  1. Use → to move onto the option and press EXE.

Setting the time

  1. Press T on the main menu.
  2. Press MODE.
  3. Use → to move between the sections and ↑ to change the settings.
  4. Press EXE to set the clock going.
  5. Press ON/CLEAR to get back to the main menu.

Switching off

  1. Press ON/CLEAR once or twice to get to the main menu.
  2. Press O.

2 Saving records

The Organiser comes equipped with a database where you can store all manner of information. This chapter shows you how to save a record. It also introduces you to the Organiser keyboard.

What is a record?

A record is a any piece of information such as a name and phone number, an account number, a stock number, or any other piece of data you store in the Organiser.

Choosing the SAVE option

To save a name, address, and phone number:

You could now start to type in a record like this one:

ABRAHAM LINCOLN, PRESIDENT TEL 01-010-0000 THE WHITE HOUSE WASHINGTON, DC

But as you're doing so, look through the keyboard section on the next page and take time to experiment and get the feel of the keys.

Getting used to the keyboard

As you type the first word the letters will appear to the right of the SAVE A: message on the screen.

When you want to start a new line, press ↓.

Practice using all the keys:

Letters

The letter keys normally produce capital (upper case) letters on the screen.

To type lowercase letters hold down SHIFT and press the CAP (↑) key.

To return to capital letters press SHIFT and CAP.

Numbers

If you hold down SHIFT and press one of the letter keys, you access the number or symbol marked above it.

By holding down SHIFT and pressing NUM the numbers and symbols are locked on, so that you don't have to hold down SHIFT all the time.

Return to letters by holding down SHIFT and pressing NUM again.

When typing letters the cursor is a flashing block.
When typing numbers the cursor is a line.

Delete

To delete mistakes, position the cursor with the arrow keys and use the DEL key.

DEL deletes the character to the left of the cursor.

To delete the character under the cursor hold down SHIFT and then press DEL.

Scrolling If you type in a line that is longer than the screen, the whole line is scrolled to the left as you type, like this:

←SAVE A:ABRAHAM LI
   

New line To start a new line un a record, press ↓.
Join lines To join up two lines of a record, place the cursor on the first character of the second line and press DEL once.

(You can't split one line into two separate lines, and you can't insert a new line into the middle of a record.)

Saving a record

When you are satisfied with what you have entered:

It can find be found at any time with the FIND option.

Abandoning the record

If you wish to abandon a half-finished record, and not save it:

Saving the record on a Datapak

If you have fitted a Datapak to your Organiser, you can save the record there.

When you have finished typing in the record but before you press EXE, press MODE, and the display will show which of the devices you are currently on.

The internal memory of the Organiser is device A:. If you have any Datapaks fitted, they are devices B: and C:

Normally, device A: is current and the screen looks something like this:

SAVE A:ABRAHAM L TEL 01-010-0000

SAVE B:ABRAHAM L TEL 01-010-0000

Or, if you have fitted the Datapak to the lower slot:

SAVE C:ABRAHAM L TEL 01-010-0000

If you have no packs fitted, pressing MODE has no effect.

Summary

Saving a record

  1. Press S on the main menu.
  2. Type in the record. (↓ starts a new line.)
  3. Press MODE if you need to change to device B: or C: to save on a Datapak.
  4. Press EXE to save (or ON/CLEAR to abandon).

The EXE, ON/CLEAR and MODE keys

EXE is short for execute. It is like the Enter key on some computers.

ON/CLEAR is used to clear the line where you are typing or to return to the main menu.

MODE is used to change the mode of operation - for example to be on another pack.


3 Finding and editing records

This chapter shows you how to find a record which you have saved, edit it and erase it. It also shows you how to copy a record to pack.

Finding a record

The screen looks like this:

FIND A:_  

(If you saved your record on a Datapak, press MODE to select the device you want to search.)

To find a record you just need to type in a search-clue. This is just a few of the characters in the record. For example, if you have saved Lincoln's address and phone number:

The screen then shows the record:

AHAM LINCOLN, PR TEL 01-010-0000

In the ABRAHAM LINCOLN example, the first line would be scrolling round and round as there is not enough room for it on the screen.

If the record that was found is not the one you are looking for, press EXE to see the next record the Organiser found containing the search-clue you entered.

If there are no more records which contain your search clue, this message is shown:

**************** **END OF PACK***

Press EXE again and the first matching record will be displayed once more. To return to the main menu, press ON/CLEAR once.

Looking at all the records

If you wish to browse through all the stored records, select FIND from the main menu, and press EXE without typing in a clue. The first record in the main file is displayed, and at each subsequent press of EXE, the next record is displayed.

After the last record has been displayed, the END OF PACK message is shown. Press EXE once more and you will return to the first record.

Again, to return to the main menu, just press ON/CLEAR once.

Editing a record

Records may at some time need to be altered - for example, when someone's telephone number changes. To edit a record:

You can now edit the record as you wish. Use the arrow keys to move the cursor to different points in the record, to insert or delete characters.

(See the Keyboard section in Chapter 2 if you are not used to the keys.)

Any of the lines can be altered, and you can add new lines onto the end of the record, although you cannot insert new lines between the original ones.

Cancelling your edits

If you make a mess of your changes, you can delete the version of the record you were editing - before you press EXE - by just pressing ON/CLEAR. The record will disappear and the screen will show:

SAVE A:  

Press ON/CLEAR to return to the main menu. The original record is still in memory, and you can find it again by selecting FIND once more.

Warning: If you press ON/CLEAR and then EXE when the screen shows the SAVE A: prompt, the original record will be erased from the Organiser memory too.

Erasing a record

If you want to erase a record:

You now have a chance to change your mind.

Either way, the screen will show the next matching record or the END OF PACK message.

Erasing multiple records

If you don't type in a search clue, but just press EXE when the screen shows ERASE A: you can go through all your records deciding to erase them or not.

Copying a record to a different device

If you wish to copy a record from, for example, the internal memory (A:) to Datapak B:

The record will be copied to the Datapak and the original will still be in the internal memory.

If you want to copy all the records to a different device, you use the COPY option on the main menu. See Chapter 9 for instructions.

Summary

Finding a record

  1. Press F on the main menu.
  2. Type in a search clue (or nothing if you want to look at all the records).
  3. Press EXE.

Editing a record

  1. Press F on the main menu.
  2. Type in a search clue.
  3. Press MODE when you're at the right record.
  4. Make the changes.
  5. Press EXE to save. (Or ON/CLEAR twice if you want to cancel.)

Erasing a record

  1. Press E on the main menu.
  2. Type in a search clue.
  3. Press EXE until you're at the right record.
  4. Press DEL then Y.

Copying a record to a different device

  1. Find the Record.
  2. Press MODE to select the device you want.
  3. Press EXE.

4 Alarms

This chapter shows you how to set an ordinary alarm and a repeating alarm. These alarms will sound even when the Organiser is switched off.

Setting an alarm

To set an alarm:

The screen looks like this:

1) FREE   press EXE to set

You can have up to 8 alarms set at any one time. They are numbered from 1 to 8; number 1 is shown initially.

The screen will then show the alarm number and the current day of the week and time, like this:

1) TUE 10.26  

You can set an alarm for any of the seven days starting with the current one. So, you can make individual settings for up to a week ahead.

Switching off an alarm

If you are using your Organiser when it is time for an alarm to go off, it will interrupt what you are doing, the alarm will sound, and a message like this will be displayed:

SEP:12:MON:15.30 ALARM

When the Organiser is off it is still keeping track of the time, so when your alarm is due to go off the Organiser switches itself on, the alarm sounds, and the message is displayed.

If you are not around to press any keys the Organiser will switch itself off automatically alter a few minutes.

Repeating alarms

You can make an alarm repeat weekly, daily (like an alarm clock) or hourly.

An "R" for repeat appears under the part of the time where the cursor is positioned.

Under the day - repeats weekly at that time of day.
Under the hour - repeats daily at that hour (like an alarm clock).
Under the minutes - repeats hourly at that number of minutes past the hour.

(To remove the "R" press MODE again before you press EXE to set.)

Cancelling an alarm

First select the alarm to cancel, by pressing A on the main menu and pressing ↓, if necessary, until you reach the alarm you want to cancel.

The screen shows:

1) FREE   press EXE to set

The alarm is cancelled and you can set the alarm again or return to the main menu with ON/CLEAR.

Summary

Setting an alarm

  1. Press A on the main menu.
  2. Use ↓ to select an alarm number then press EXE.
  3. Use → to move between the day, hour and minutes and ↑ to change the settings.
  4. If you want a repeating alarm, press MODE and use → to move the "R" marker.
  5. Press EXE.
  6. Press ON/CLEAR to return to the main menu.

Switching off an alarm

  1. Press ON/CLEAR.

5 The diary

The Organiser diary allows you to keep track of all your appointments. This chapter shows you how to make an entry and set an alarm for it and then how to use the diary more efficiently by using the options on the diary menu.

To get into the diary:

You enter the diary at the diary page for the current day and time. (There is a diary page for every thirty minutes.)

SEP:07:WED:09.30

Moving through the pages

To go to the diary page where you want to make an entry:

From the last day of the month you step to the first day of the next month. (To flick back through the days of the month use ←.)

On stepping forward from 31st December 1989, you will move to 1st January 1990 and vice versa.

The diary can be thought of as a large sheet of paper divided into boxes, rather like a year planner. The display screen acts like a window which can be moved across and up or down, viewing the contents of one box at a time:

SundayMondayTuesday
JAN:01:SUN:08.00 (A)don't smoke JAN:02:MON:08.00 JAN:03:TUE:08.00
JAN:01:SUN:08.30 JAN:02:MON:08.30 JAN:03:TUE:08.30
JAN:01:SUN:09.00 JAN:02:MON:09.00 JAN:03:TUE:09.00 (A)HEATHROW
JAN:01:SUN:09.30 JAN:02:MON:09.30 MEET BARRY NORMA JAN:03:TUE:09.30
JAN:01:SUN:10.00 (A)TURKEY JAN:02:MON:10.00 JAN:03:TUE:10.00

As you step through the diary pages, there will be nothing displayed on the bottom line of the screen if you haven't made any entries yet.

Making a diary entry

To make an entry when you're at the diary page you

The cursor appears 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:

JAN:02:MON:09.00 EDIT:TENNIS

If you type more than sixteen characters, the text will scroll to the left, as usual with long lines. So it is best to keep your diary entries short. The maximum length is 64 characters.

If you are not used to the Organiser keys, look at the Keyboard section in Chapter 2.

Setting an alarm on a diary entry

When you have typed in your entry, press EXE. You are asked whether you want to set an alarm to sound when that entry becomes due:

JAN:02:MON:09.00 ALARM Y/N

If you choose Y you are given the chance to decide how many minutes before the event you want the alarm to sound:

JAN:02:MON:09.00 MINUTES:15

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. To change this:

JAN:02:MON:09.00 (A)TENNIS

(If you make an entry in a diary page for a date which has passed, you will not be asked if you want an alarm!)

Switching off the alarm

If you are using your Organiser when it is time for an alarm to go off, it will interrupt what you are doing, the alarm will sound, and your diary entry will be displayed.

If the Organiser is off when an alarm becomes due, it switches itself on. Then the alarm process is just the same as above.

(After an alarm has gone off, the diary entry remains unless you delete it, but the alarm indicator at the beginning of the entry disappears.)

Cancelling a diary alarm

To remove an alarm from an entry, move to the relevant date and time and press EXE twice. This leaves you at the ALARM Y/N message. This time, press N and the alarm is cancelled.

The diary menu

The diary has its own sub-menu of options.

If you are not in the diary, select it from the main menu.

The screen shows the first six options, just like the main menu, and the other three are out of sight:

PAGE LIST FIND   GOTO SAVE TIDY RESTORE DIR ERASE

The diary menu options

There are two kinds of diary options: those which change your position in the diary and those which affect the diary as a whole.

1 Options which change your position

PAGE

This is the mode you are in when you first enter the diary. It allows you to make your entries and set an alarm which will sound when the entry becomes due.

You go back to the diary page you just left.

LIST

This is the mode for viewing only. You can list all your diary entries in order - but you cannot change them in this mode. Use it to scan through your diary, entry by entry.

You see the next diary entry.

You can control the scrolling of long entries with ← and →.

When you have seen the last entry, this message is shown:

END OF DIARY  

If you press EXE again you return to the first entry in the diary.

FIND

This option is just like the FIND option in the main menu - you can find any entry quickly using a search clue. You can then also change or delete it if you want to.

FIND:DEN  

(If you are shown the END OF DIARY message and you know that you made an entry containing the letters in your search clue, you may have missed it! Press EXE again to search right from the start of the diary.)

When you have found the entry, you can do either of the following:

  1. Press MODE to go back to PAGE mode (the way the diary is when you first enter it). You can then re-edit the entry by pressing EXE or delete it by pressing DEL.
  2. Press ON/CLEAR to go back to the diary menu.

GOTO

This option allows you to go straight to any date so that you can make an entry or change the one which is already there.

The screen shows the current date:

1989 SEP 07  

You return to PAGE mode, the way the diary is when you first enter it, and you can press EXE to edit to edit the entry or DEL to delete it.

2 Options which affect the diary as a whole

SAVE

This saves all the entries in your diary in a file on a Datapak or in the internal memory of the Organiser. It is most useful for storing an out-of date diary on a pack and thus freeing Organiser memory space.

To save all your entries:

SAVE A:  

(A filename may be up to eight characters long. It must begin with a letter.)

All your diary entries are saved to the device you chose under the file name you typed in.

The diary can then be loaded back into memory with the RESTORE option below - but be careful because it will then overwrite the current diary.

TIDY

Lets you tidy up the diary by deleting out-of-date entries. It makes sense to delete them every so often, as they take up memory space.

The screen shows:

SEP:07:WED:l7.30 DELETE UPTO Y/N

If you decide not to delete all of these entries, press N.

RESTORE

If a diary has been saved to a pack or to the internal memory under a file name, you can restore it with this option. However, be careful because if you restore a diary it will overwrite your current one.

The screen will show:

RESTORE A:  

The diary will be restored and will overwrite any current diary entries. You will be returned to the diary menu.

DIR

This allows you to see a directory of the names of all the saved diaries on a device.

The screen will show:

DIR A:  

When the required device is selected, press EXE and the name of the first diary saved on that device will be displayed.

When the name of the last diary on the current device has been displayed, the usual end of pack message is given.

ERASE

This is used to erase a whole diary. (You can't erase the current diary - only one which has previously been saved.)

The screen shows:

ERASE A:  

The diary is erased from the device and you are returned to the diary menu.

Summary

Making a diary entry

  1. Press D on the main menu.
  2. Use → and ↓ to get to the right page.
  3. Type in your entry and press EXE.
  4. Press Y if you want an alarm, and then use ↓, to set the warning time.

or

  1. Press N if you don't want an alarm.
  2. Press ON/CLEAR to return to the main menu.

Editing or deleting a diary entry

  1. Press D on the main menu.
  2. Press MODE.
  3. Press F on the diary menu.
  4. Type in a search clue and press EXE.
  5. Press MODE then EXE when you're at the entry you want to change. (Or MODE then DEL to delete the entry.)
  6. Edit the entry then press EXE. You can now choose whether you want an alarm.
  7. Press ON/CLEAR to return to the main menu.

6 The calculator

This chapter shows you how to do a simple calculation and then how to use the 10 memories, edit a calculation, and use a result again.

It then goes on to explain how to use the calculator in conjunction with OPL functions and procedures.

Doing a calculation

The screen shows:

CALC:  

In the calculator you don't need to use SHIFT to get numbers and symbols - they are on automatically. Therefore, you have to use SHIFT to type in letters. (If you are not used to the keys, look at the keyboard section in Chapter 2.]

The basic arithmetic operators, +, -, / (divide), * (multiply) and ** (raise to a power) are used in the same way as they would be in a written calculation. Any number of levels of brackets may be used.

To try out the calculator:

The screen shows:

4*7/9   =3.11111111111

Clearing the calculator

Clear the calculator by pressing ON/CLEAR.

Decimal places

Notice that the result 3.11111111111 was displayed with 11 decimal places. This is the normal setting. To change this to 3, type FIX=3 after the CALC: prompt and press EXE. (Remember that you have to press SHIFT to type letters.)

Do the calculation 4*7/9 again. The result is now 3.111. You can have from 0 to 11 decimal places. To return to the normal setting (11) type only FIX=

Calculator memories

Built into the Organiser are ten memories which can be used either in the calculator or in OPL.

You can store numbers in them for use in calculations. They can then be added to, subtracted from and cleared.

In the calculator and OPL they are referred to by the same names, M0 to M9. (Lower or upper case "m"s may be used.)

To store the result of a calculation to a memory:

M: press 0-9

M0: +,-,EXE,DEL

You now have four choices:

+Adds the current result to the total in the memory selected.
-subtracts the current result from the total in the memory selected.
EXEStores the current result to the memory overwriting the current contents.
DELETESets the contents of the memory to 0.

The four choices above all return you to the calculator. You can also just press ON/CLEAR to return to the calculator with no change to the memories.

To find out the contents of a particular memory:

Editing a calculation

A useful feature of this calculator is the ability to edit your original calculation. Do another calculation to try this out. When the result is displayed:

The result is erased and you can now edit the calculation on the top line.

Alternative ways to edit the calculation

Using a result again

You might decide to use the result from one calculation as part of another one. When the result is displayed:

The old result is shown on the top line with the number or symbol at the end.

Percentages

The percent key (%) does not operate in the same way as the percent key on ordinary calculators. So, you have to calculate percentages in longhand form. For example, to calculate 37% of 250 type in: 37/100*250 or .37*250

Exponent

You can use E as the exponent. For example, 3.6E4 represents 36000.

Built-in OPL functions in calculations

In your calculations, you can use any of the numeric functions of the Organiser Programming Language - even if you never use OPL otherwise. The numeric functions are listed at the beginning of Chapter 18. You can use them to do far more operations than are available on an ordinary calculator. For example:

SIN(PI/4)/(3.8*COS(1.2))

Here the SIN, CO5 and PI functions are used.

Another example might be to find the sine of 30°. This is typed in like this:

SIN(RAD(30))

The RAD function converts from degrees to the radians which the SIN function requires.

When you press EXE, if there is an error in your calculation, you get an error message and should, as the message says, press the space key and correct it. The cursor flashes on the unrecognised character.

For instance, if you included a character which was not a function name or an arithmetic operator, like this, the cursor would be flashing on the P:

10P/(22/7)

OPL procedures in calculations

In Chapter 17 there are example OPL procedures, including one to calculate ASIN and one to calculate ACOS.

If you have typed any OPL procedures into the Organiser, you can include the procedure names in your calculations (all procedure names end in a colon]. Put the value you want to operate on in brackets after the procedure name. In this example the value is 0.1:

ASIN:(0.1)

The value you want the procedure to operate on is called a parameter. You can use a memory name as a parameter:

ASIN:(M1)

Procedure names can be included in quite complex calculations. For example, if you had a procedure called FACT: which worked out the factorial of a number passed to it, then you could include this in your calculation like this:

587*2.883/(4+FACT:(3))

The value 3 is being passed to the procedure. The returned value is then added to 4 and the rest of the calculation performed on the result.

From the calculator, parameters are passed as floating point numbers. To pass an integer to a procedure, you must use the INT function like this:

5/3+PROC:(INT(10))

Part 3 of this manual shows you how to write your own OPL procedures, and there are examples in Chapter 17.

Summary

Doing a calculation

  1. Press C then EXE on the main menu.
  2. Type the calculation (without =).
  3. Press EXE.

Clearing the calculator

  1. Press ON/CLEAR.

Storing a result to memory

  1. Do the calculation.
  2. When the result is displayed, press MODE.
  3. Press a number from 0 to 9.
  4. Press EXE.

Editing a calculation

  1. Do the calculation.
  2. When the result is displayed, press EXE.
  3. Edit the calculation on the top line then press EXE to see the modified result.

Using a result again

  1. When the result is displayed, press the number or symbol you need next in the calculation.

Part 2
Further Information


7 Customising the main menu

These are the twelve standard options on the Organiser main menu:

FINDFor retrieving and/or editing records you have previously saved.
SAVEFor saving records either in the Organisers internal memory or a removable pack.
DIARYThe diary.
CALCThe calculator.
FROGOPL (the Organiser Programming Language)
ERASEFor erasing records from the Organisers memory or a pack.
TIMEThe clock.
INFOInformation on how much memory is occupied.
ALARMThe alarms.
COPYFor copying files of records from device to device.
RESETResets the Organiser, erasing all information in the internal memory.
OFFSwitches the Organiser off.

Customising the main menu

When you first switch on your Organiser, the menu options are in this order:

FIND SAVE DIARY  CALC PROG ERASE TIME INFO ALARM COPY RESET OFF

This is the default menu. However, you may change the order of the options and even delete the ones you never use.

The only menu item that cannot be deleted is OFF. Also you cannot put any other menu item after it; it's always the last.

You can replace a deleted item at a later date, but you don't have to put it back in the same place. So, you can arrange your menu in the order which suits you best.

For instance, if your chief use of the Organiser is as a diary, then it may make sense to put DIARY first on the menu, so you can just press EXE after switching your Organiser on.

Deleting menu items

To delete an entry from the main menu:

For example, if you want to delete RESET from the menu, you place the cursor on it, press DEL and the screen shows:

RESET   DELETE Y/N

You now have the chance to change your mind. Press N or ON/CLEAR and you return to the main menu without making any deletion. Press Y and the menu reappears without the RESET option displayed.

Replacing menu items

To replace a deleted menu item, either at the same place as before or in another position, position the cursor at the place on the menu where you want the item to be displayed.

INSERT ITEM  

The inserted item will then appear at that position in the menu, pushing the following items one position to the right. The item can now be selected as before.

Note: You can insert an OPL procedure into the main menu but not with the same name as one of the original default options. (OPL is covered in Part Three.)


8 Storage devices

Devices A: B: and C:

When saving data, the internal memory of the Organiser is known as Device A:, the upper external device is known as device B: and the lower as device C:.

Devices B: and C: are two external devices in the back of your Organiser. When you first purchase your Organiser, these two devices are fitted with covers to protect the electrical connections. You should always keep a pack or one of the covers on each device.

Devices B: and C: can hold a Datapak, a Rampak or a program pack, such as the Pocket Spreadsheet.

The Organiser checks which devices have Datapaks or Rampaks fitted, so when you go to SAVE or FIND a record and press MODE to change the device, you can choose only the relevant devices.

So, if you do not have any packs fitted, pressing the MODE key when trying to SAVE or FIND information will have no effect - you will remain with device A:.

Once you have made a device current, you continue using the same one unless you change to another.

Datapaks, Rampaks and internal memory

The internal memory of the Organiser and Rampaks are RAM:

Datapaks are EPROM:

The advantages of Datapaks are that they are more secure and are not affected when the battery runs low. They are thus excellent places to store data.

The advantages of Rampaks are that they use very little power and that data is really deleted, so you can edit things as many times as you like without using up any space. They are thus the best medium for writing programs. You should always back-up your valuable data to a Datapak or a desk-top computer to keep it more secure.

Fitting Datapaks

Avoid pressing any key while fitting or removing a Datapak. This is easily avoided by placing the machine face down one flat surface, as the keyboard is slightly recessed.

Use the white label on your Datapak to mark it for identification later.

Datapaks are available with capacities of approximately 8000, 16000, 32000, 64000 and 128000 characters, to suit whatever application you have in mind.

For instance, all the names, addresses and telephone numbers most people could ever need can comfortably be held in one Datapak (over 2000 entries of up to 30 characters each in a 64K Datapak).

Fitting Rampaks

Read the important information leaflet provided with your Rampak before you fit or remove a Rampak.

Sizing a new Datapak

The first time you try to perform any operation on a new Datapak, a message may be displayed to let you know that the Organiser is checking its size.

For example, after entering a record with the screen showing SAVE A: you can fit a new Datapak to device B: in order to save the record to that pack. The screen shows:

SAVE A:ABRAHAM L 01-010-0000

The screen shows:

SIZING PACK B: PLEASE WAIT

There is a short pause, and then the screen shows:

SAVE B:ABRAHAM L 01-010-0000

Any Datapak will only be sized once, so if you fit one which has already been sized you can go right ahead and use it.

Formatting a Datapak

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.

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 machine called the Psion Formatter.

The reformatted Datapak will be completely blank, and when reinserted into the Organiser, will be re-sized as if it were brand new.

If a Datapak is full because unwanted "erased" data is still occupying space, but the pack also contains some data you want to keep, copy all of it to another pack. The erased records and files are ignored, so only real data is copied across. The old pack can then be reformatted in the Psion Formatter.

Note that the white label on the underside of each Datapak is to protect it from excessive exposure to light. It must be removed before formatting can occur.

The INFO Option

The INFO option on the main menu tells you how much storage space is left in the internal memory of the Organiser and any packs that are currently in the devices.

The top line of the screen shows the number of free bytes (one byte stores one character) in the internal memory of the Organiser.

The Organiser model XP has 32000 bytes of internal memory, or RAM. However, 8000 bytes are reserved for other programs and peripherals, such as the Spreadsheet. So, memory size on an XP is about 24000 bytes. (On model CM 8192 bytes are available.)

The bottom line shows a scrolling display of the amounts of storage space used, in terms of percentages of the total available. Press ← to stop the line scrolling around and → to start it again.

If you had a number of diary entries and some other data stored on device A:, and some data stored on a Datapak in device B:, the bottom line would show something like this:

DIARY 4% PACK A: 15% PACK B: 36% FREE 81%

The amounts of storage space occupied here are:

Device A:Internal memory: 4% by the diary and 15% by other data stored on device A:
Device B:36% by various data

This leaves a total of 81% of the internal RAM free. A Datapak is not RAM so the percentage occupied on Device B: does not affect this figure.

Note: The current diary resides in the internal memory of the Organiser - unlike diaries stored on a Datapak with the diary SAVE option - so if you have a large current diary the amount of memory free for other activities is diminished.

The RESET Option

This option enables you to erase all the data in the internal memory of the Organiser. All diary entries are lost, along with any files or procedures saved on device A:. Data saved on packs is quite safe, of course, and is not affected by this option.

Select RESET from the main menu and the screen shows:

ALL DATA WILL BE LOST - PRESS DEL

If you do not want to reset the machine, press ON/CLEAR and you will be returned to the main menu and all data will be intact. Otherwise press DEL and the screen will show:

ARE YOU SURE   PRESS Y/N

If you press N or ON/CLEAR 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 Y. You will then return to the main menu.


9 Records and files

Hints about records

When you are entering information with the SAVE facility, think about making it easy to find again:

Size of Records

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.

Copying records to different devices

To copy a record from one device to another:

To copy all the records from one device to another, you use the COPY option on the main menu to copy all the data files. The next section explains this.

Files

A data file is a collection of records. When you save a record using the SAVE option from the main menu, the record goes into a file called MAIN. This is also where the FIND option looks for records.

The MAIN file will always exist on device A: and on any Datapak fitted to your Organiser. The file will be empty unless you have saved records to it.

In addition to the MAIN data file, extra data files can be created using the OPL programming language.

The COPY Option

The COPY option on the main menu is for copying data files from one device to another. You can copy files from the Organisers internal memory to one of the packs, and back again, or from one pack to another.

FROM  

After the FROM prompt you can type in a device name - A:, B: or C: (don't forget the colon), or a device name and a file name - for example A:MAlN. This is the source device and file.

TO  

Example: of copying files

FROM A:MAIN   TO B:

Copies the file called MAIN on A: to the pack on device B:

FROM A:MAIN   TO B:OLDMAIN

Copies the file called MAIN on A: to the pack on device B: - but gives the copy the name OLDMAIN.

FROM A:   TO B:

Copies all the tiles on A: to the pack on device B:

What happens when tiles are copied

So, if you already have some records in the file B:MAIN and in the file A:MAlN, 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 B:MAlN.


10 Replacing the battery

Information stored in the internal memory of the Organiser relies on the presence of the battery to keep it safe. This includes the diary, all the records you have saved on device A:, and any OPL procedures there. Data stored on Datapaks is quite secure however.

When the battery runs low, a BATTERY TOO LOW message is displayed on the Organiser's screen. This is displayed for four seconds and then the machine switches itself off.

You must replace the battery before you use the machine again.

Do not remove the old battery until you have a new one ready.

When the old battery is removed, you have a limited time to replace it with a new one, after which you lose the contents of the Organisers memory.

If you are saving information to a Datapak when the battery runs low, the record which is currently being saved is erase on the destination device then the low battery message appears and the machine switches off.

Psion Mains Adaptor

You can use the Psion Mains Adaptor to power your machine while you change batteries. This means that the power supply to the Organiser is uninterrupted and there is no hurry to fit the new battery.


Part 3: OPL
(Organiser Programming Language)

11 Introduction to OPL

OPL is the Organiser Programming Language. It has an extensive set of commands and functions suitable for all kinds of applications - including the manipulation of the files of data saved in the Organiser as records.

To enter OPL you simply select PROG from the main menu. You are immediately presented with a sub-menu, and you can start new programs or continue with old ones.

Once you have written programs in OPL you can run them from within PROG, or directly from the main menu, or even whilst you are working on the calculator or the Pocket Spreadsheet.

An OPL program consists of one or more procedures, each of which is typed in separately. A simple program may consist of a single procedure. More complex programs are normally made up of several, one of which is the main procedure.

The most efficient way to use OPL is to write short procedures which can be tested individually. Each one 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 chapter shows you how to write, save and run a simple procedure and covers all the options on the PROG menu.

The PROG menu

When you select PROG from the main Organiser menu, the screen looks like this:

EDIT LIST DIR   NEW RUN ERASE COPY

These options can be selected in the same way as the items on the main menu. Here is a summary of their uses:

EDIT Lets you alter and then re-save an existing procedure - allowing improvements. corrections and modifications to be made.
LIST Lists an existing procedure to an attached printer or computer.
DIR Displays a list of all procedures stored on the specified device A:, B: or C:.
NEW Lets you type in and save a new procedure.
RUN Executes an existing procedure.
ERASE Erases a procedure.
COPY Copies a procedure, or all procedures, to another device.

Creating, saving and running a procedure

This section shows how to create, save and run the simple procedure which follows. The section introduces you to the PROG menu and to the process of creating, saving and reusing a procedure.

CLOCK: CLS PRINT "IT IS NOW",HOUR;":";MINUTE GET

The procedure's name is CLOCK: It clears the screen, displays the current time, and waits for you to press a key.

1 Creating a new procedure

NEW A:  

The current device is shown after the word NEW; in this case it is device A: (the internal memory). If you want to work on a pack, press MODE to change device.

The first thing to type is the name for the procedure. This can be up to eight characters long and must start with a letter.

Press EXE, and the procedure name is shown on the top line of the screen, with a colon at the end of the name. The cursor is flashing at the end of it.

CLOCK:_  

If you are not used to the Organiser keys look at the Keyboard section in Chapter 2.

Note: in OPL you can use either upper case or lower case letters in any combination.

Press EXE to get a new line. The display scrolls leaving the cursor ready on a blank line.

PRINT "IT IS NOW",HOUR;":";MINUTE

Check that the line appears on the screen exactly as it does here. All computer languages are precise and even the spaces are important.

Here is an analysis of the line:

The first part, PRINT, is a command. PRINT makes what follows it print on the display screen.

This is followed by a space, and then a piece of text which has been enclosed in quotation marks - the text that will be printed out - "IT IS NOW". In computer terminology, any list of characters between quotation marks like this is called a string.

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 preceding text, separated from it by a space.

The next word, HOUR, is a function. This function finds out the current hour from the Organiser clock. Here it returns to the print command, which prints it out on the screen.

The next character, a semi-colon, means that the next thing to be printed is placed immediately after the previous thing, with no space.

The next item is another string. This time the string is just one character, a colon, but it must still be enclosed in quotation marks.

The final part of the line is the MINUTE function which returns the current minutes past the hour.

The last line, the GET function. waits for a key to be pressed on the keyboard before executing the rest of the program. This means that when the procedure is run. the message which is printed to the screen will remain there until you press a key - then there are no further instructions, so the program ends.

Editing a new procedure

At any time in the typing in of a procedure you can go back and make an alteration to a line by using the cursor keys.

Press ← and → to move along a line and ↑ and ↓ to move between lines.

If you need to insert a new line in between two existing lines, position the cursor on the start of the line where you want to insert a new one, then press EXE.

2 Saving and translating procedures

When a procedure has been typed into the Organiser, there are three options:

The TRAN SAVE QUIT menu

Press MODE to get to a menu of these options:

TRAN SAVE QUIT  

This is a sub-menu just like the PROG menu. The following diagram shows the difference between the three options.

QUIT

Select QUIT and you are prompted with the message ARE YOU SURE Y/N. Press N, and you are returned to the procedure editor. (If you pressed Y, the whole text of the procedure typed in so far would be discarded.)

Warning: Once a procedure has been abandoned with QUIT, there is no way to retrieve it again.

TRAN

Select TRAN and the procedure is translated internally into a form that OPL can execute.

When the procedure has been translated, the screen displays this prompt:

SAVE A:CLOCK  

You may now save the translated procedure to any available device. Press MODE to change devices then EXE to save.

When the translated version is saved, the original text is also saved. This means that there is now a version of the program which can be executed and a version which can be edited. These are both stored under the same procedure name.

Syntax errors

If you make a typing error in the procedure. OPL spots it when it is translated. If, for example, you typed the word PRONT instead of PRINT, or left out one of the sets of quotation marks around a string, then this message is displayed:

SYNTAX ERR   press space key

Now edit the line in the usual way until it reads correctly then press the MODE key to return to the TRAN/SAVE/QUIT menu and select TRAN again.

SAVE

If you had typed in part of a procedure and intended to return to it later to complete it or make alterations. you could use the SAVE option from the TRAN/SAVE/QUIT menu so as not to waste memory by producing an unnecessary translated version.

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.

Where you should save programs

The best place to save programs is the internal memory of the Organiser (device A:) or a Rampak. Then, if a procedure takes a couple of versions before it runs exactly as you require, each edit will not be using up space.

When a final version of a procedure has been produced on device A: it is a good idea to make another copy on a Datapak. Copying procedures is described at the end of this chapter.

3 Running a procedure

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 all the instructions in it. From the PROG menu, select RUN. The screen shows:

RUN A:CLOCK  

Press EXE to run the procedure. If you want to run this procedure another time, when you have not just saved it, the name will not automatically appear after the RUN prompt - you then have to type it in. If there is another procedure name there, clear the entry line first by pressing ON/CLEAR.

When CLOCK: is run, the screen will first clear and then show something like this, depending on the current time:

IT IS NOW 16:35 

The last line of the procedure was GET. This instruction simply waits until any key is pressed on the keyboard before continuing. So, when you press a key, the procedure finishes and you are returned to the PROG menu.

That was a simple example for your first procedure. There are more complex examples of OPL procedures in Chapter 17. The next section deals with the remaining options on the PROG menu.

EDIT, LIST, DIR, ERASE, COPY

Editing an old procedure

The EDIT option from the PROG menu allows you to return to an old procedure to change it or add to it. When selected from the menu. the screen shows:

EDIT A:  

Press MODE if you need to change device then type in the name of the procedure and press EXE.

When the procedure is complete. you should use the TRAN option from the TRAN/SAVE/QUIT menu to translate it, as described earlier. If you make a mess of the editing, select QUIT and this version of the procedure will be deleted and you can edit the original version again.

Printing a procedure

The LIST option is used to print out a listing of a procedure to a printer or another computer.

If you have not got a Psion Printer II, you will need the Psion RS232 Comms Link. This allows any serial printer to be connected to the Organiser or may be used to communicate with another computer.

Select LIST from the PROG menu. If no printer or computer is connected to the Organiser, a DEVICE MISSING error message is displayed. Press SPACE to return to the menu. If one is connected and you get this message, press ON/CLEAR on the main menu to load the device software.

See the Comms link manual for further details.

The procedure directory

The DIR option in the PROG menu shows you the directory of procedures stored on the various devices.

Select DIR from the PROG menu. The screen shows:

DIR A:  

If necessary, change the device with MODE, then press EXE. If there are any procedures stored on the current device, the first will be displayed. Each time you press EXE the next is displayed - until you get to the END OF PACK message.

Press ON/CLEAR to return to the PROG menu or EXE to repeat the directory list.

Erasing a procedure

The ERASE option from the PROG menu allows you to erase procedures from any of the devices. Select ERASE and the screen shows:

ERASE A:  

If necessary change device with MODE. You can new type in the name of a procedure to be erased from the current device, eg CLOCK. Press EXE and the screen shows:

ERASE A:CLOCK   ERASE Y/N

Press Y to confirm that you wish to erase that procedure, or N to cancel. Once the procedure is erased, it cannot be retrieved.

Copying a procedure

The COPY option in the PROG menu is used to make copies of procedures from one device to another.

Select COPY from the PROG menu and the screen will show:

COPY   OBJECT ONLY Y/N

Press Y 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 files - the translated version and the original editable version you typed.

If you are planning to erase the procedure from the internal memory after copying it to a pack, it is unwise to copy the object file only, unless you are certain you will never need to edit it.

However, 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 a similar way to the COPY option in the main menu.

If a procedure with the same name already exists on the destination device, it will be deleted - with no warning. There can only be one procedure with the same name on any one device.

Pausing and quitting procedures when running

To halt the execution of a procedure, first press ON/CLEAR. This will pause it indefinitely. You can then press any key to continue or Q to quit. The screen shows:

ESCAPE   IN A:procname

Now press the SPACE key to return to wherever the procedure was called from.

Summary

Entering and running a procedure

  1. Select PROG on the main menu.
  2. Select NEW.
  3. Type a name. Press EXE.
  4. Type in the procedure. (EXE starts a new line.)
  5. Press MODE.
  6. Select TRAN.
  7. Press MODE if you need to change device, then EXE to save.
  8. Select RUN to execute the procedure.

12 Procedures and variables

The previous chapter dealt with the mechanics of using the PROG menu. The next four chapters cover the basic concepts of OPL programming. If you are familiar with programming languages just skim through these chapters, or refer instead to the reference sections which follow.

Procedures generally consist of the four steps shown in this simplified example:

1Name SINE50:
2Declaration of variables LOCAL x
3Operations upon variables x=SIN(50)
4Communication of variables PRINT x

This chapter deals with these four steps.

1 Procedure names

e.g. print:, shares89:, TAXCALC:

2 Declaring variables

If you were adding together two numbers, in algebra you could write: 'x + y = z'.

In OPL you would write z=x+y, but first you would have to declare x, y and z as variables, in order to reserve memory space for them. You would do this:

  1. Declare the variables in order to reserve 3 spaces in memory, called x, y and z.

    LOCAL x,y,z

  2. Assign values to x and y.

    x=5 y=2

  3. Add x and y together and assign the result to z:

    z=x+y

A variable is therefore a named region of memory which at the very beginning of your procedure you declare. This means that you tell the Organiser you are going to use the variable so that it will have space to store the number or text you later assign to it. So in the SINE50 example, the line 'LOCAL x' reserves a memory space named x in which the value given to x in the next line can be stored.

Variable names

There are three kinds of variables identified when you declare them by the format of the variable name. The three kinds are:

Floating point variables e.g. x
Integer variables e.g. x%
String variables e.g. x$

All variable names may be up to 8 characters long. The first character must be a letter. The other characters may be letters or numbers but not symbols - except for the identifiers % and $ at the end.

Floating point variables

A floating point number is one which has a decimal point and then any number of digits after that point, e.g. 13.567 or 8. or 0.05319 or 6.0

You should declare a floating point variable when you know that the sort of value you are likely assign to it will be a floating point number.

A floating point variable name does not have any symbol at the end.

e.g. a, AGE, PROFIT89.

Floating point variables are stored to an accuracy of 12 digits and must be in the range ±9.99999999999E99 to ±9.99999999999E-99 and 0.

Integer variables

An integer is a whole number, eg. 6 or 13 or -3 or 11058

You should use integer variables wherever floating numbers are not necessary and speed or space are important. Integer arithmetic is faster than floating point and it occupies two bytes of memory instead of eight.

An integer variable name ends with a % sign. (The % sign is included in the 8 characters length.)

e.g. a%, AGE%, PROFI89%.

Integer variables must be in the range -32768 to +32767.

String variables

A string is a sequence of characters, alphabetic, numeric or symbolic, which is treated literally rather than being evaluated. Examples of strings are: "x + y =" and "01-345-2908" and "profit".

A string variable name ends with a $ sign. (The $ sign is included in the 8 characters length.)

e.g. a$, NAME$, MAN6$.

When declaring a string variable, you must state the maximum length of the string you expect to assign to it. So if you want to enter names up to 15 characters long as the value of NAME$, you have to declare NAME$(15). The number goes in brackets.

The maximum length of a string is 255 characters.

The LOCAL and GLOBAL commands

You must declare your variables immediately after the procedure name. You may list together all 3 types, in any order; they must be separated by commas with no spaces between - like this:

LOCAL x,y,a%,NAME$(15),YEAR3%

To declare variables you use either the LOCAL or the GLOBAL command like this:

LOCAL x,a%,list$(8)

or

GLOBAL x,a%,list$(8)

LOCAL and GLOBAL define the range the variables are to be active in. The basic difference is that:

For example, in the diagram below, the procedure PROCA: calls three other procedures X: Y: and Z:. At each stage a% has a new value passed on for the next procedure. In the end, the value 9 would be printed.

If you had declared a% not as a global but as a local variable, an error would have been reported when you tried to use it in procedure X:, since X: would not have recognised a%.

However, the danger with global variables is that you may get mistakes occurring if you accidentally use the same variable name twice. So, you should use the LOCAL command unless the GLOBAL one is required.

If OPL comes across a variable which isn't declared in that procedure, it assumes it has been declared in a previous procedure. OPL will then report a MISSING EXTERNAL error if it can't find the variable declared as a global variable in a calling procedure.

Other variables

Calculator memories

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 OPL.

Array variables

You may want to declare a large number of similar variables at the beginning of a program. It is helpful to declare whole groups at once. For this reason, OPL has another type of variable, called array variables.

The idea is simply that, instead of having to declare separately variables a, b, c, d and e, you can declare variables a1 to a5 in one go. In the case of numeric variables, that would look like this:

LOCAL a%(5) (integer variable array)
GLOBAL a(5) (floating point variable array)

Numeric array variables may be thought of as a list of numbers, each with the same name, but with a unique number (an index) to differentiate it from its neighbours. So you might have an array of integers with the variable name NUM%, with five values, numbered 1 to 5.

When the array is declared, the number in brackets is the number of elements in it. Here is a simple example assigning values to the elements of an integer array:

procname: GLOBAL 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)

This example just finds out the sum of the five elements in the array.

Floating point arrays are used in exactly the same way except that the % sign is omitted from the variable name.

String variables as well as numeric variables may be grouped into arrays. The difference is that with strings, you must declare the number of elements in the array and what the maximum length of the strings is to be - just as you do when you declare the length of an ordinary string variable.

For example GLOBAL ARRAY$(5, 10) allocates memory space for five strings, each up to ten characters in length, under the names ARRAY$(1), ARRAY$(2)...ARRAY$(5). As yet, each of the variables is empty (is a null string), but enough memory still has to be set aside to contain all of the five strings when full.

3 Operations upon variables

Once you have declared your variables you can perform any number of operations on them. This might be a combination of arithmetic operations, or you might pass the variables to other procedures for them to operate upon them, or use one of the OPL functions. These are all covered in detail in further sections of this manual. Whatever you do, however, you need to understand how your variables will react according to what type they are and how you combine them.

For example, you cannot divide a string variable by an integer variable. And if you mix integers and floating point variables in the same sum one may convert the other into its own type of variable. The following sections give details of what problems may arise and how to avoid them.

Mixing integers and floating point variables: automatic type conversion

In the procedure below there is a potential mistake in the third line after the name, where the integer variable y% is assigned a floating point value:

procname: GLOBAL x%, y% x%=7 y%=3.7+x% PRINT y% GET

OPL deals with this in the following way: instead of reporting an error, OPL carries out an automatic type conversion internally on the value assigned to the mismatched variable.

The right hand side of y%=3.7+x% is evaluated to 10.7. However, the fractional part of the number is dropped before the result is assigned to the left hand side, 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.

In the procedure below where only floating point variables are used. you can see that another type conversion is made, but does not cause the value to change:

procname: GLOBAL a,b,c a=1.2 b=2.7 c=3 PRINT a+b+c

In this procedure, the floating point variable c is given the integer value 3. An automatic type conversion is carried out in such cases. Here the result is converted to 3.0, so the real value of the variable remains the same.

If you assign a floating point number to an integer variable, then the automatic type conversion will generate an integer rounded down. So if you say a%=2.3 then the value of a% will be 2; but a%=2.9 would also give a% the value 2. And 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. This may not be desirable.

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.

It is possible to control how floating point numbers are rounded when convened. For example, if you wanted to round floating point numbers to the nearest half (so 2.4 would round to 2.5 and 2.2 to 2) then you might try the following statement:

r=INT(2*n+0.5)/2

where n is the number to be rounded.

This would produce the wrong result, though, To see why, substitute a trial value, say 3.4, instead of n:

INT(2*3.4+0.5) i.e. INT(7.3).

This returns the integer 7. But 7/2, when rounded down gives the integer 3, not 3.5.

To obtain 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:

r=INT(2*n+0.5)/2.0

will give the required result.

There is more about integers and floating point variables in the chapter on Operators.

Mixing strings and numbers

If you try to allocate a number to a suing 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. These are the SCI$, FIX$, GEN$ and NUM$ functions - dealt with in Chapter 18.

Concatenating strings

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 (concatenating strings) is just as simple.

Alternatively, you could give c$ the same value with the statement c$="DOWN"+"WIND".

When concatenating strings, don't forget that the result mustn't be longer than the maximum you declared the string could be.

Slicing strings

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. For example:

The MID$ function is a little different in that you must say at what character in the first string you want the new stung to start from, and how long the new string is to be. MID$ has the syntax:

MID$(<name of string to be cut from>,<position at which to start cut>,<length of string to be cut>)

So if a$="01-234-5782", the instruction b$=MID$(a$,4,3) would return the value 234 to b$. This is because you have taken the 3 characters starting at the character at position 4 of a$.

String slicing operations leave the original string unchanged - i.e. a$ would still have the value 01-234-5782 after b$ had gained the value 234. The exception would be when the left hand side of the equation is the same string as appears in the right hand side. Eg 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.

Note: 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. So, if you say a$="x""y""z", then the resulting value of as will be x"y"z.

4 Communication of variables

In the first example procedure at the beginning of this chapter, the statement PRINT x simply takes the value found in the memory space of variable x and prints it on the screen.

Values can also be passed between procedures. In the example on page 12-5, the procedure PROCA called the three other procedures X:, Y: and Z: which returned the adjusted value of a% back to PROCA:. The variable a% was declared global to allow this.

The rest of this chapter deals with two other ways of communicating values: entering values from the keyboard using the INPUT command, and passing values between procedures using parameters.

The INPUT command

Values can be entered from the keyboard using the INPUT command, as in the example below.

This simple procedure just asks you to enter a number. The number you enter is assigned to the variable x and is then printed out to the screen with a message:

INPUT: LOCAL x CLS PRINT "ENTER NUMBER" INPUT x CLS PRINT "YOU ENTERED",x GET

For full details of the INPUT command, see Chapter 18.

Procedure parameters

Values can be passed between procedures using parameters. In the VAT example below, the second procedure VAT1: is followed by a parameter name (p).

The last line of the first procedure PROC1: calls VAT1 with the value of x. The value of x is copied to the parameter p. VAT1: then prints out this value plus VAT at 15%.

PROC1: LOCAL x CLS PRINT "ENTER PRICE" INPUT x VAT1:(x)

VAT1:(p) CLS PRINT "PRICE INCLUDING VAT = ",p*1.15 GET

Multiple parameters

In this similar VAT example the second procedure VAT2: has two parameters.

The value of the price variable, x, is passed to the parameter pl and the rate of VAT is also a variable, r, which is passed to the parameter p2. VAT2 then prints out the price plus VAT at the rate specified.

PROC2: LOCAL x,r CLS PRINT "ENTER PRICE" INPUT x CLS PRINT "ENTER VAT RATE" INPUT r VAT2:(x,r)

VAT2:(p1,p2) CLS PRINT p1+p2/100*p1 GET

The RETURN command

This VAT example differs from the previous two in that control does not end with the second procedure but returns instead to the first.

The RETURN command is used to return the value of x plus VAT at r percent - to be printed out in PROC3:. This makes the procedure VAT3: more flexible because it is now just doing the calculation and not printing. This means it can be called by other procedures which need this calculation but do not necessarily need to print to the screen.

PROC3: LOCAL x,r CLS PRINT "ENTER PRICE" INPUT x CLS PRINT "ENTER VAT RATE" INPUT r CLS PRINT "PRICE INCLUDING VAT =",VAT3:(x,r) GET

VAT3:(p1,p2) RETURN p1+p2/100*p1

Procedures and menus

You can run procedures from the main menu or the PROG menu and you can also display a menu from within a procedure.

Chapter 7 describes how to insert a procedure name in the main menu. It is not possible to pass values to (or return them from) a procedure if it is run from a menu.

By using the MENU function in a procedure, you can make the procedure display a menu, from which selections can be made in the usual way. This is a useful tool for showing the choices available for differing courses of action.


13 Loops and branches

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; if you want to carry out an instruction more than once you must repeat it.

That is clearly very inefficient. A far more efficient method is for the program to be able to loop around a particular part as many times as you require, or until a certain condition is met.

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 structures. They operate in a similar way to each other, with one difference.

You can have up to eight loops nested within each other.

The DO/UNTIL loop

The following example is a small part of a procedure to illustrate how a DO/UNTIL loop works:

a%=10 DO PRINT "A=";a% a%=a%-1 UNTIL a%=0

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 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."

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 i subtracted from it. That now gives a% the value 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.

When a equals zero the loop is finished and the program continues with the instructions that follow UNTIL.

The WHILE/ENDWH loop

The WHILE /ENDWH structure operates in a very similar way. Here is an example:

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.

BREAK

The BREAK command can be used in conjunction with an IF statement to break out of a DO/UNTIL or WHILE/ENDWH loop. The program is sent to the instruction after the end of the loop.

Labels and jumps

Another command which can direct the program out of a straight sequence is GOTO. This makes the program jump to a different point. This point is a label.

In this example the program, on reaching the line containing the GOTO instruction. would jump to the line beginning with the label exit::.

GOTO exit:: PRINT "MISS THIS LINE" PRINT "AND THIS ONE" exit::

All labels must end with a double colon.

The label used must be in the same procedure as the GOTO command, and the jump is not conditional (it will always be executed).

Branches

The GOTO is one of the ways of branching within a procedure, but it is a fairly crude tool and if used indiscriminately, can lead to procedures which are difficult to read and debug.

A better way 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/ENDIF structure.

After all likely eventualities are catered for by the ELSEIF 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:

whatkey: GLOBAL g% g%=GET PRINT "THAT KEY IS" IF g%>64 AND g%<91 PRINT "UPPER CASE" ELSEIF g%>96 AND g%<123 PRINT "lower case" ELSE PRINT "NOT A LETTER" ENDIF GET

The program just waits for a key to be pressed at the keyboard, and then prints that it is either a lower or upper case letter. (If you don't realise the significance of the numbers 64 and 91 - see Appendix A.) If it is not a letter, then that is printed, as allowed for by the ELSE statement. The ELSE statement needs no condition as it allows for all 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.

It is also valid for the statement following the ELSE part of the structure to be on the same line as ELSE. So the line ELSE PRINT "NOT A LETTER" would have been quite valid.

Endless Loops

ESCAPE OFF, GET, KEY and INPUT must be used with caution in loops for the following reasons:

To halt the execution of a procedure, you normally press ON/CLEAR then Q.

To break out of a procedure which contains an ESCAPE OFF command - which stops the ON/CLEAR key pausing or halting procedures - you have to remove the battery from your Organiser in order to escape, and lose all the data in the internal memory.

To break out of a loop which use any function such as GET or KEY to read a keypress, you have to press ON/CLEAR quickly followed by Q and repeat this very quickly a few times. This may be very difficult to do.


14 Operators

These are the operators available in OPL. divided into three classes:

Arithmetic operators

+ add
- subtract
* multiply
/ divide
**raise to a power
- unary minus (make negative)

Comparison operators

>greater than
>=greater than or equal to
<less than
<=less than or equal to
=equal to
<>not equal to

Logical operators

AND
OR
NOT

Operator precedence

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.

Highest: -(Unary minus) NOT
**
* /
+ -
= > < <> >= <=
Lowest: AND OR

(The logical operators AND. NOT and OR are covered in greater depth later in this chapter.)

Using Brackets

An expression such as a+b+c presents no problems because whichever addition is done first, the result will be the same. However, you may want to enforce a different order of precedence upon an operation. For example.

a+b*c/d

would be evaluated in the order: b multiplied by c, then divided by d, then added to a. To change this order use brackets.

So, to perform the addition and the division before the multiplication, you would write the equation like this:

(a+b)*(c/d)

a%**b%**c%

b% will first be raised to the power of c% and the resulting value will be used as the power of a%.

When in doubt, simply use brackets; they also make the order in which the sum is worked out visible at a glance.

Precedence of integer and floating point values

You are free to mix floating point and integer values in an expression, but be aware how OPL handles the mixture:

but then

For example, your procedure might include the expression:

a%=b%+c

This mixture of variable types would be evaluated like this: b% is converted to floating point and added to c. The resulting floating point value is then automatically converted to an integer in order to be assigned to the integer variable a%.

So any fractional part of the result of the right hand side of the expression will be lost in the conversion to an integer. This may produce results you do not want, so be careful.

Logical expressions

The comparison operators and logical operators are based on the idea that a certain situation can be evaluated as either true or false. For example, if a%=6 and b%=8, a%>b% would be false. They are useful for setting up alternative paths in your procedures. For example you could say:

IF salary<expenses PRINT "bad" ELSEIF salary>expenses PRINT "good" ENDIF

If necessary, you can also make use of the fact that the result of these logical expressions is represented by an integer:

These integers can be returned to a variable or printed out to the screen to tell you whether a particular condition is true or false, or used in an IF or ELSEIF statement.

For example, in a procedure you might arrive at two sub-totals, a and b. You want to find out which is the greater. So include the statement

PRINT a>b

If zero is displayed, a and b are equal or b is the larger number but if -1 is displayed, 'a>b' is true - a is the larger number.

The following table gives examples of using each of the comparison operators:

ExampleResultInteger
Returned
<a%<bTrue if a% less than b-1
False if a% greater than or equal to b0
>a%>b%True if a% greater than b%-1
False if a% less than or equal to b%0
<=a<=bTrue if a less than or equal to b-1
False if a greater than b 0
>=a>=b%True if a greater than or equal to b%-1
False if a less than b 0
<>a$<>b$True if a$ not equal to b$-1
False if a$ equal to b$ 0
=a=bTrue if a equal to b-1
False if a not equal to b 0

You can use these operators with a mixture of floating point or integer values but not with a mixture of string and numeric values. So a$<b would be invalid.

The logical operators AND, OR and NOT have different effects depending on whether they are used with floating point numbers or integers:

1 When used with floating point numbers only, the logical operators have the following effects:

ExampleResultInteger
Returned
a AND bTrue if both a and b are non-zero-1
False if either a or b are zero0
a OR bTrue if either a or b is non-zero-1
False if both a and b are zero0
NOT aTrue if a is zero-1
False if a is non-zero0

2 When used with integer values only, AND, OR and NOT are bitwise logical operators.

The way the Organiser represents integer numbers is in a 16-bit binary code, like this:

0000000000000111

This is the number 7 (in base 10).

The Organisers numerical range is +32767 to -32768. 32767 is the largest number that can be represented with 15 binary bits. The 16th bit is used to say whether the number is negative or positive.

As the operators are bitwise they perform the operation on first the first bit, then the second, up to the sixteenth bit of the binary numbers.

AND

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.

These are the sixteen bits of the binary representations of 10 and 12.

12 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0

The AND operator acts on each pair of corresponding binary digits in the two numbers, each pair producing one digit of the four-digit answer. Thus. working from left to right - discounting the first 12 bits:

1 AND 11
1 AND 00
0 AND 10
0 AND 00

The result is therefore the binary number 1000, or 8 in decimal notation.

OR

What result would the statement PRINT 12 OR 10 give? Again, write down the numbers in binary notation and apply the operator to each corresponding pair of digits:

1 AND 11
1 AND 01
0 AND 11
0 AND 00

The result is the binary number 1110, or 14 in decimal.

NOT

The NOT operator is different in that it works on only one number. It returns the one's complement of the number, i.e. it replaces the zeroes in the binary number with ones, and the ones with zeroes.

So if 7 looks like this:

0000000000000111

NOT 7 will look like this:

1111111111111000

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.


15 Data file handing

When you use the SAVE option from the main menu your records are saved in a file called MAIN. You can access this file and the records in it from OPL. You can also create other files and then manipulate them. This chapter explains how to do this.

There is also an example at the end of Chapter 17 of a data file handling program made up of 5 procedures. It may be a good idea to refer to that program while you read this chapter.

Files, records and fields

The data file MAIN and any extra ones you create contain records which are divided into fields. When you save a record from the main menu with the SAVE option, you start a new field every time you start a new line by pressing ↓.

In a name and address file, in each record, there might be a name field, a telephone number field, and separate fields for each line of the address.

Creating a data file

Before you can start to enter data into a new data file. you must create that file on one of the devices using the CREATE command.

The CREATE command must be supplied with a number of parameters, in the following format:

CREATE "<dev>fname",logname,fldnm1,fldnm2

"<dev>fname", is the device (A:. B: or C:) which the file is to be on, and then the file name. This all goes in quotes as a string, e.g. "a:clients". You can also assign this device and file name string to a string variable (e.g. cl$="a:clients") and then use the variable name (cl$) as the parameter. The file name may be up to 8 characters long.

logname is the logical file name. This may be A, B, C or D. You use this logical file name to refer to the file from within the program.

fldnm1, fldnm2 are 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 8 characters long including any qualifier used.

An example of a CREATE command might be:

CREATE "a:clients",B,nm$,tel$,ad1$,ad2$,ad3$

When a file has been created, it is automatically open. This means records can be saved to it immediately. It also becomes the current file which means that when you use one of the commands for manipulating records, they operate on this file.

Adding records to a file

You add records to a data file field by field. First you assign some values to the current field names, then you use the APPEND command to add them to the file.

Assigning values to field names

The field names act in a similar way to variables, and can be assigned values and used in INPUT statements. The field name must be used with the logical file name like this:

INPUT B.name$

or this

B.name$="MR Bruno"

where B is the logical file name and name$ is the name of the field. These are separated by a full stop.

Appending the fields

When you have assigned values to the fields, you add them to the open file with the APPEND command. They are always added as the last record in the data file. If the file is a new one, this will be the first record.

The APPEND command has no parameters - the field values are automatically added to the file in the correct order and format.

If you try to assign a text string to a numeric field name, an error will be reported.

See the second procedure (insert:) in the data file handling program at the end of Chapter 17 for an example of adding records to a data file.

At any time while a data file is open, 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. However, in order to operate on a particular field, you must make the record containing it the current one.

Changing the current record

Before you can erase a record or operate on the fields in it you must make it current. You can change the current record by using any of the six commands and functions below.

FIRST moves to the first record in a file.

NEXT moves to the following record in a file. If the end of the file is passed, NEXT does not report an error. The current record will then be null. This condition can be tested for with the EOF function.

BACK 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.

LAST moves to the last record in the file.

POSITION moves to a particular record. 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.

FIND moves to the record which contains a search string you specify.

Finding a record

The FIND function acts like the FIND facility in the main menu. The difference is that whereas the main menu FIND prints the record found on the screen, this function makes the record the current one so that you can operate on it: editing it, erasing it, or just displaying it.

For example, 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%. If the number returned is zero, it means that the string was not found.

The procedure called search: at the end of Chapter 17 is an example of how to find and edit records.

Erasing a record

To erase a record, make that record current by use of one of the commands FIRST, NEXT, BACK, LAST, POSITION or FIND and then use the ERASE command. This removes the current record from the file and renumbers the ones that follow.

The final procedure (erase:) in the group of data file procedures at the end of Chapter 17 is an example of how to find and erase records.


16 Error handling

This chapter covers commonly made errors, then error trapping. There is a list of the OPL error messages in Appendix D.

Common errors

All programming languages are very particular about the way commands and functions are used. especially in the way program statements are laid out.

Below are a number of errors which are easy to make in OPL. The incorrect statements are boxed and the correct versions are on the right.

Punctuation errors

Omitting the colon between statements on a multi-statement line:

IncorrectCorrect
a$="text" PRINT a$a$="text" :PRINT a$

Omitting the colon after a called procedure name:

IncorrectCorrect
proc1:proc1:
GLOBAL a,b,cGLOBAL a,b,c
..
..
proc2proc2:

Omitting one or more of the colons after a label:

IncorrectCorrect
proc1:proc1:
GOTO below:GOTO below::
..
..
below::below::

Omitting the space before the colon between statements on a multi-statement line:

IncorrectCorrect
proc1:proc1:
a$=b$:PRINT a$a$=b$ :PRINT a$

Parameter errors

Passing a floating point value to a procedure which requires an integer - here the procedure proc2:(x%). This may occur when calling a procedure from the calculator or from another procedure.

IncorrectCorrect
2*6+proc2:(3)2*6+proc2:(INT(3))

Passing an integer to a procedure which requires a floating point value - here the procedure proc3:(x)

IncorrectCorrect
proc1:proc1:
..
..
proc3:(2/3)proc3:(2.0/3)

Passing the wrong number of parameters to a procedure - here, the procedure proc4:(x,y)

IncorrectCorrect
proc1:proc1:
..
proc4:(3.7)proc4:(3.7,2.5)

Integer size error

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:

IncorrectCorrect
proc1:proc1:
LOCAL a%LOCAL a
a%=100*2468a=100*2468

Structure errors

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 eight structures deep. Attempting to nest to a greater depth than this will cause an error. Mixing up the three structures eg, by matching up DO with WHILE, will also cause an error:

IncorrectCorrect
proc1:proc1:
..
DODO
..
WHILE a>2UNTIL a<=2

Run-time errors

If an error occurs when you run a program, the program stops and an error message is displayed. For example, here a call has been made to a procedure called subproc: which does not exist:

MISSING PROC   SUBPROC

Press ON/CLEAR or SPACE and you are asked whether you want to EDIT the procedure. If you say yes and the source code is available, you are returned to the OPL editor to correct the offending line.

When you have done this, press MODE to return to the TRAN/SAVE/QUIT menu, and either translate, save or quit the procedure. If you quit at this stage, the edits you have made are abandoned and the old version of the procedure remains on the current device.

Error trapping

In the case of the run time errors described above, the program stops to display the error message. There are ways of avoiding this by trapping errors and dealing with them yourself within the program - but they put you in full control and must be used carefully. The tools used to control errors are ONERR, TRAP, ERR, ERR$ and RAISE:

ONERR label:: and ONERR OFF

ONERR, is used to redirect program control to a label if an error occurs. This is useful if you want to provide your own error handling routine, such as printing out a message for an error you anticipate.

ONERR is followed by the label name which must end in two colons. The label itself must occur somewhere in the same program - but not necessarily the same procedure.

In the example below, LPRINT is being used to print to an attached printer. Normally, when LPRINT is used and no printer is connected, the message DEVICE MISSING is displayed. This procedure supplies a more precise message, CONNECT PRINTER, to make sure the person running it understands.

ONERR noprint:: LPRINT "Memo" LPRINT "Dear Sir" RETURN noprint:: ONERR OFF PRINT "CONNECT PRINTER" GET

The first line causes the program to jump to the label noprint:: if an error occurs. If there is no printer connected, the first LPRINT command causes such a jump and the message "CONNECT PRINTER" is displayed. If there is one connected. "Memo" and "Dear Sir" are printed out and the lines after the label are never executed, because of the RETURN before it.

ONERR should be cancelled with ONERR OFF.

ONERR OFF

Notice that the first instruction after the label noprint:: is ONERR OFF. This is very important because if you don't do this after the ONERR label:: command is used. all subsequent program errors - even in other procedures called - result in the program being directed to the same label. This diagram illustrates how two completely different errors cause a jump to the same label, and cause the same explanatory message to be printed out:

Risks of ONERR label::

As all errors go back to the same label unless you switch ONERR OFF, it is very easy to create an endless loop by mistake. If this happens. you cannot press ON/CLEAR and Q to break out, as this just makes control go to the label as any other error would - so. you have to take the battery out of the Organiser, and lose everything in the internal memory. To avoid this:

TRAP

TRAP traps errors on a specified command only, so it doesn't need to be cancelled like ONERR does. It can be used with any of the commands listed below:

APPEND BACK CLOSE
COPY CREATE DELETE
ERASE EDIT FIRST
INPUT LAST NEXT
OPEN POSITION RENAME
UPDATE USE

The trap command immediately precedes any of these commands, separated from it by a space - e.g:

TRAP INPUT a%

When INPUT is used without TRAP and a text string is entered when a number is required, the display just scrolls up and a question mark is shown, prompting for another - valid - entry. When you put TRAP in front of INPUT, the command is executed in the usual way, but if an error occurs the next line of the program is executed as if there had been no error. The next line in the example below is a helpful message.

proc: LOCAL a% start:: PRINT "ENTER AGE", TRAP INPUT a% IF ERR=252 PRINT "NUMBER NOT WORD" GOTO start:: ENDIF

The sample above also uses the ERR function.

The ERR function

When errors occur in a program, the number of the error is accessible by using the ERR function. This means that you can be absolutely sure which error you are dealing with.

The anticipated error in the lines below is 246 (NO PACK). If 246 occurs when trying to open the MAIN file on pack B: a helpful error message is printed out. However, just in case a different error occurs, the next lines (ELSE :PRINT ERR$(ERR) make sure that the standard error message for that error is printed.

TRAP OPEN "B:MAIN",A,a$ IF ERR=246 PRINT "NO PACK IN B:" ELSE PRINT ERR$(ERR) ENDIF

The OPL error messages are listed in Appendix D.

RAISE

If you are using commands to trap errors and handle them yourself, then at some during the development stage of your program you need to test your error handling routines. An easy 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. For example, this statement causes the NO PACK error to be generated:

RAISE 246

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 to 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 use an ONERR statement in the top level procedure, then when you RAISE an error at the lowest level, the program control will return to the label specified in the ONERR statement. even though it is several jumps back in the sequence of procedures.


17 Example programs

This chapter contains example programs written in OPL. The programs are not intended to demonstrate all the features of OPL, but they should give you a few hints. To find out more about a particular command or function, refer to chapter 18.

Each of the procedures must be entered separately, you can't enter two procedures in one block. Chapter 11 explains how to type in, translate, save and run a procedure.

Uppercase, lowercase

In the listings here, variables are shown in lowercase and commands and functions in uppercase. However, it doesn't matter which you use when you enter procedures into the Organiser:

Spaces

Be careful to type in the necessary spaces:

Remarks

Lines beginning with the command REM are remarks: they are there to explain things. They do not affect the way a procedure runs and you don't have to type them in if you don't want to.

1 Dice

This procedure turns the Organiser into a dice. When the program is run, a message is displayed saying that the dice is rolling. You then press S to stop it. A random number from one to six is displayed and you choose whether to roll again or not.

dice: LOCAL dice%,key% KSTAT 1 top:: CLS :PRINT "**DICE ROLLING**" PRINT "PRESS S TO STOP" DO dice% = (INT(RND*6+1)) UNTIL KEY$="S" CLS PRINT "***** ";dice%'" ******" BEEP 50,100 PRINT "ROLL AGAIN Y/N" label:: key%=GET IF key%=%Y GOTO top:: ELSEIF key%=%N RETURN ELSE GOTO label:: ENDIF

Variables
dice% is a random number from 1 to 6.
key% is the ASCII value of the keypress read by the GET function.

Random numbers
This is how dice: displays 1, 2, 3, 4, 5 or 6 randomly. The RND function returns a random floating point number, between 0 and 1 (not including 1). It is then multiplied by 6 and 1 is added (so that you get numbers from 1 to 6 instead of from 0 to 5). It is rounded down to a whole number by using the INT function. This number is then assigned to dice%.

Identifying keypresses of Y and N
The ASCII value of the character on the key you press is returned by the GET function and assigned to key%. In OPL you get the ASCII value of any character by putting % in front of it, so %Y is the ASCII value of Y and %N is the ASCII value of N. In case you had the keyboard set to lowercase, KSTAT 1 is used at the start of the procedure to set it to uppercase,. so that you are not pressing y and n.

2 Status report

This procedure acts rather like the INFO option on the main 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. When you run it, press any key to see the next line of information.

status: LOCAL a$(8),dev%,b$(5),c$(6),dev$(2),num% a$="Memory:" :b$="MAIN" :c$="FREE" PRINT "Model:", num%=PEEKB($FFE8) REM SFFE8 is a memory address IF num%=0 PRINT "CM" PRINT a$,"8K" ELSE PRINT "XP" PRINT a$, IF num%=1 PRINT "16K" ELSEIF num%=2 PRINT "32K" ENDIF ENDIF :GET :dev%=%A REM %A is the ASCII value of A DO dev$=CHR$(dev%)+":" IF EXIST(dev$+b$) OPEN dev$+b$,A,f$ PRINT c$,dev$:SPACE CLOSE :GET ENDIF dev%=dev%+1 UNTIL dev%=%D

Variables
a$, b$ and c$ are "Memory", "MAIN" and "FREE".
dev% is the ASCII value of A, then B, then C.
dev$ is the letter A, then B, then C plus a ":".
num% is the number, found in a memory address, which shows which Organiser you have.

How it finds out the type of Organiser
The PEEKB command is used to look in a specific memory address ($FFE8). The number returned shows which type of Organiser you have.

How it finds out the free space on each device
The SPACE command is used to see how much space is free on each device. A file has to be open in order to use the SPACE function, so the MAIN file is OPENed first on each device.

To go through each device, dev% is first assigned the value %A, the ASCII value for A. This is then stepped up by the line dev%=dev%+1, to the values %B, then %C. The loop stops at the value %D.

The ASCII values are converted to the letters A, B, and C by the CHR$ function and together with a ":" are assigned to dev$. So dev$ is A: then B: then C:.

3 Mortgage calculator

This program calculates monthly mortgage payments. When you run it, you have to enter me amount of the loan, the interest rate and the term in years. Then you specify the source of the loan by selecting from a menu. The program does not allow for tax relief.

The program is made up to two procedures - mortgage: and q: - a general input routine. You must type each one in separately. The input routine could be called by any procedure which needs to prompt the user to enter a floating point number.

mortgage: LOCAL num%,loan,x,term,rate,pay,ques$(2) CLS PRINT "EVALUATE MONTHLY" PRINT "MORTGAGE PAYMENT" PAUSE 30 ques$=CHR$(63)+" " REM CHR$(63) is a "?" - See Appendix A loan=q:("ENTER LOAN"+ques$) DO rate=q:("INTEREST RATE % "+ques$) UNTIL rate>0 AND rate<99 DO term=q:("ENTER TERM (YRS)"+ques$ UNTIL term>.5 AND term<100 num%=MENU("BUILDING-SOCIETY,BANK,OTHER") IF num%=0 :RETURN :ENDIF rate=rate/100 :x=1+11*(num%/2) pay=loan*rate/12/(1-((1+rate/x)**(-x*term))) CLS :PRINT "MONTHLY PAYMENT",FIX$(pay,2,-8) GET RETURN

q:(a$) LOCAL z CLS :PRINT a$,CHR$(16); INPUT Z CLS RETURN(z)

Variables
loan, term, rate and pay are the amounts of the loan, the term in years, the interest rate and the monthly payments.
ques$ is "? ".
num% is the number of the menu item you choose.
x is a variable used in the calculation at the end
z is the variable used for the values you input when q is running.

Calling q:
The main procedure mortgage: calls q: three times. passing it a string to be printed out as a prompt. The text string is passed to q: as a parameter. The values returned are assigned to the variables loan, rate, and term.

How "?" is printed
The CHR$ function converts the ASCII value 63 to the question mark character.

How the input routine beeps
The CHR$ function converts the value 16 to the beep control character. This is then "printed" out.

4 Stopwatch

This procedure provides a seconds and minutes stopwatch. Press any key to start the program then, when the stopwatch is running, press S to stop and L to record a lap. If you press S to stop, you then have three options: R restarts counting, Z resets the watch to zero and E ends.

The procedure cancels the Organiser's normal automatic switch-off. So don't leave it running.

watch: LOCAL k$(1),s%,secs%,mins% POKEB $007C,0 REM this poke cancels automatic switch-off CLS :PRINT "S=STOP, L=LAP" PRINT "PRESS ANY KEY... GET :CLS zero:: mins%=0 :secs%=0 :s%=SECOND loop:: k$=KEY$ IF UPPER$(k$)="S" GOTO pause:: ENDIF IF UPPER$(k$)="L" AT 1,2 :PRINT "LAP: ";mins%;":"; IF secs%<10 :PRINT "0"; :ENDIF PRINT secs%:" "; ENDIF IF SECOND<>s% s%=SECOND :secs%=secs%+1 IF secs%=60 :secs%=0 :mins%=mins%+1 :ENDIF PRINT CHR$(14)+"MINS",mins%,"SECS", IF secs%<10 :PRINT "0"; :ENDIF PRINT secs%; ENDIF GOTO loop:: pause:: PRINT CHR$(15)+"RESTART/ZERO/END"; k$=UPPER$(GET$) PRINT CHR$(15); IF k$="R" GOTO loop:: ELSEIF k$="Z" CLS :GOTO zero:: ELSEIF k$<>"E" GOTO pause:: ENDIF POKEB $007C,5

Variables
k$ is used for the keypresses read by KEY$ and GET$.
s% is the actual number of seconds past the minute at the start of the procedure.
secs% is the seconds shown counting up.
mins% is the minutes shown counting up.

How the stopwatch counts up
The actual number of seconds past the minute is read from the system clock by the SECOND function and assigned to s% at the start. Then the SECOND function is used again, and if it is no longer equal to s% - i.e. when a second has elapsed, 1 is added to sec% and s% is assigned the actual number of seconds again. Whenever secs% is 60, it is reset to 0 and 1 is added to mins%.

Reading lowercase as well as uppercase keypresses
If you have the keyboard set to lowercase and so press s, for example, instead of S, this is converted to S by the UPPER$ function. This is used throughout the procedure whenever a keypress is read.

Cancelling automatic switch off
This is done by poking the value 0 at address $007C.

5 Noises Off

The procedure below may be used to mute all audible alarms and beeps from the Organiser. Use the same procedure again to switch the sound on again.

mute: PRINT "Sound now <"; IF PEEKB($A4)=0 POKEB $A4,l PRINT "OFF>" ELSE PRINT "ON>" POKEB $A4,0 ENDIF PRINT "Press any key"; GET

How the sound is muted
$A4 is the memory address of the Organiser buzzer. If you poke any non zero value into this address, you switch the sound off. When you poke zero into it you switch the sound on again. This procedure peeks into the memory address first to see if it contains zero or not and then pokes 1 or 0 as appropriate. There are a few useful memory addresses in Appendix C.
Note: You shouldn't use POKEB and POKEW unless you know exactly what you are doing.

6 Password

This procedure can be used to provide a degree of security to information in your Organisers internal memory. When you type the procedure in, substitute your own password in quotes, e.g. "SESAME". for the string "YOURPASSWORD".

When you run it, the machine switches off. When you press ON/CLEAR, switching the machine back on, the procedure is still running and the password is requested. If you don't enter the correct one, the machine switches off again.

Warning: If you run this procedure then forget the password, or if you make a mistake when typing it in, you may lose all data in the internal memory.

password: LOCAL pass$(20) ONERR start:: start:: DO OFF CLS :PRINT "Enter password" INPUT pass$ UNTIL UPPER$ (pass$) ="YOURPASSWORD"

Variables
pass$ is the string you specify as your password.

The ONERR command
This procedure shows the usefulness and the risks of the ONERR command. Normally. if an error occurs when a procedure is running (such as BATTERY TOO LOW, if the battery is running out or ESCAPE, if ON/CLEAR is pressed), the procedure is interrupted and an error message displayed. This is not desirable here, as it would mean that the program stopped, the Organiser came on again and anyone could access your data. So ONERR off is used. However, if you forget the password, you won't be able to press ON/CLEAR to break out and the program will loop round forever. You would have to remove the battery to stop it, and thus lose all data in the internal memory. Normally it is good practice to use ONERR OFF when you have dealt with an error at a label.

7 Chase Game

The next three procedures make up a game which demonstrates the use of user defined graphics (UDG's). Each procedure must be typed in separately.

The object of the game is to avoid being caught by the pursuer. Your movable man can jump between the two lines of the display: 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 ON/CLEAR and to restart press it again. To quit out of the game press ON/CLEAR then Q, then ON/CLEAR again when you see the ESCAPE message.

game: LOCAL a$(1),b$(1),c$(1),d$(1),e$(2),f$(1) LOCAL g$(32),h$(1) LOCAL a%,b%,c%,x%,y%,z%,sc%,b1%,f% igame: CURSOR OFF a$=CHR$(0) :b$=CHR$(1) c$=CHR$(2) :d$=CHR$(3) e$=CHR$(4)+CHRS(6) :f$=CHR$(5) g$=REPT$(CHRS(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%=l :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

Game Initialiser

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)

Game UDG's (User Defined Graphics)

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%

User defined graphics

The main procedure, game:, calls igame: which then calls udg: 8 times in order to set up the graphics characters used in the game. The last call to udg: in igame: is the one which sets up the little man. User defined characters are explained in Appendix A.

8 Acos and Asin

Here are two programs to calculate ACOS and ASIN. Once entered and translated they can be called from within the calculator - e.g. ASIN:(0.1)

acos:(n1) IF n1=1 RETURN 0 ELSEIF n1=-1 RETURN PI ELSEIF ABS(n1)>1 CLS PRINT "OUT OF RANGE ";CHR$(16) PAUSE 12 RETURN ELSE RETURN (PI/2)-ATAN(n1/SQR(1-n1*n1)) ENDIF

asin:(n1) IF ABS(n1)=1 RETURN nl*PI/2 ELSEIF ABS(nl)>1 CLS PRINT "OUT OF RANGE ":CHR$(16) PAUSE 12 RETURN ELSE RETURN ATAN(n1/SQR(1-n1*n1)) ENDIF

9 FIND on all the packs

This procedure searches for a string, like the FIND option on the main menu does. But it automatically searches on device A: then B: then C: - looking in the file called MAIN on each device. When you run the procedure, you enter a search-clue and then press EXE to see the first matching record. You can then press any key (except the arrow keys) to see the next matching record. If you press ON/CLEAR, you return to the PROG menu.

packfind: LOCAL search$(254),recnum%,key%,dev% dev%=65 ESCAPE OFF AT 1,1 PRINT "Find:"; TRAP INPUT search$ IF ERR=206 RETURN ENDIF DO TRAP OPEN CHR$(dev%)+":MAIN",A,a$ IF ERR=246 CLS :AT 1,1 PRINT "*** NO PACK ***" AT 1,2 PRINT "** IN SLOT ";CHR$(dev%);": **" PAUSE 20 GOTO nextpak:: ENDIF CLS AT 1,1 PRINT "Searching Pak ";CHR$(dev%);"=" PAUSE 15 WHILE NOT EOF recnum%=FIND(search$) IF recnum%<>0 key%=DISP(-1,"") IF key%=1 REM 1 is the code for ON/CLEAR RETURN ENDIF ENDIF NEXT ENDWH CLOSE nextpak:: dev%=dev%+1 UNTIL dev%=68 CLS PRINT REPT$("*",18);"END OF PACK***" PAUSE 25 RETURN

Variables
search$ is the search clue you enter.
recnum% is the record number returned by FIND.
key% is the code number, returned by DISP, of the key you press when a record is displayed.
dev% is the device - A, B, then C.

Searching the MAIN files
The OPEN command opens the MAIN file - allowing access to the records in it.

The device variable, dev%, is used with a ":" as the device name in the OPEN command, dev% is first assigned the value 65 - this is the ASCII code for A. The function CHR$ converts this to the letter A. To search on devices B and C, the value of dev% goes up to 66, then 67. Then the searching stops.

The FIND function finds the record containing the search clue and makes it the current record. The DISP function displays the current record and returns the number of any key you press. If that number is 1 (ON/CLEAR) then the program ends and you RETURN to the PROG menu.

Error handling
Normally ON/CLEAR pauses the execution of a procedure so that Q can be pressed to quit. At the start of this procedure ESCAPE OFF is used. This means that ON/CLEAR does not pause the program, and can thus be read by the DISP function and cause a RETURN to the PROG menu.

Because ESCAPE OFF is used, the INPUT command is TRAPped and followed by the instruction that if you press ON/CLEAR to escape (Error number 206), you RETURN to the PROG menu.

The OPEN command is also TRAPped. Here, if a NO PACK error (246) occurs, a message is printed explaining this.

10 Data file handling procedures

The main procedure below creates a data file called addr on device A:, to contain names. addresses, post codes and telephone numbers. It is followed by 4 other procedures which allow you to insert, search for, alter and erase records in the file. When you run files:, a menu giving you a choice of these options is displayed.

Each of these 5 procedures must be typed in separately.

files: LOCAL m% IF NOT EXIST("A:ADDR") CREATE "A:ADDR",A,n$,ad1$,ad2$,ad3$,pc$,tel$ ELSE OPEN "A:ADDR",A,n$,ad1$,ad2$,ad3$,pc$,tel$ ENDIF top:: m%=MENU("INSERT,SEARCH,ALTER,ERASE,QUIT") IF m%=0 :STOP ELSEIF m%=1 :insert: ELSEIF m%=2 :search: ELSEIF m%=3 :alter: ELSEIF m%=4 :erase: ELSEIF m%=5 :STOP ENDIF GOTO top::

insert: PRINT "ENTER NAME" :INPUT A.n$ CLS :PRINT "ENTER STREET" :INPUT A.ad1$ CLS :PRINT "ENTER TOWN" :INPUT A.ad2$ CLS :PRINT "ENTER COUNTY" :INPUT A.ad3$ CLS :PRINT "ENTER PCODE" :INPUT A.pc$ CLS :PRINT "ENTER TELNUM" :INPUT A.tel$ APPEND RETURN

search: LOCAL recnum%,search$(30) top:: FIRST :CLS :PRINT "FIND:"; TRAP INPUT search$ IF ERR=206 RETURN ENDIF recnum%=FIND(search$) IF recnum%=0 CLS :PRINT "NOT FOUND" :PAUSE 20 GOTO top:: ENDIF DO DISP(-1,'"W :NEXT :recnum%=FIND(search$) IF recnum%=0 :CLS PRINT REPT$("*",18);"END OF PACK***" PAUSE 20 :RETURN ENDIF UNTIL EOF RETURN

alter: LOCAL recnum%,search$(30),key% top:: FIRST :PRINT "ALTER:"; :TRAP INPUT search$ IF ERR=206 :STOP :ENDIF recnum%=FIND(search$) IF recnum%=0 CLS :PRINT "NOT FOUND" PAUSE 20 :GOTO top:: ENDIF DO ask:: KSTAT 1 :AT 1,2 :PRINT "EDIT Y/N" key%=VIEW(1,A.n$) IF key%<>%Y AND key%<>%N GOTO ask:: ELSEIF key%=%Y :CLS EDIT A.n$ :EDIT A.ad1$ EDIT A.ad2$ :EDIT A.ad3$ EDIT A.pc$ :EDIT A.tel$ :UPDATE :NEXT ELSE :NEXT :recnum%=FIND(search$) IF recnum%=0 CLS :PRINT "NOT FOUND" :PAUSE 20 :RETURN ENDIF ENDIF UNTIL EOF

erase: LOCAL recnum%,search$(30),key% FIRST :CLS :PRINT "ERASE:"; TRAP INPUT search$ IF ERR=206 :STOP :ENDIF recnum%=FIND(search$) IF recnum%=0 CLS :PRINT "NOT FOUND" :PAUSE 20 ENDIF DO IF recnum%=0 CLS :PRINT "NOT FOUND" :PAUSE 20 :RETURN ENDIF ask:: KSTAT 1 :AT 1,2 :PRINT "ERASE Y/N" key%=VIEW(1,A.n$) IF key%<>%Y AND key%<>%N GOTO ask:: ELSEIF key%=%Y ERASE ELSEIF key%=%N NEXT :recnum%=FIND(search$) ENDIF UNTIL EOF

Variables
m% is the number of the menu item you select
recnum% is the record number returned by FIND.
search$ is the search clue you enter.
key% is the ASCII value of the key you press whilst the found record is displayed. (%Y is the ASCII value of Y, %N is the ASCII value of N.)

Creating the data file
The first procedure, files:, creates or opens a file called addr on device A: with 6 fields for each record. The six field names are n$ for the name, ad1$, ad2$. and ad3$ for each line of the address, pc$ for the post code and tel$ for the phone number. The file is given the logical name A.

Inserting records
Notice how in insert: the 6 fields of the record are input one by one. The field names are used like variables and preceded by the logical file name (A) and a full stop. Then the APPEND command is used: this is necessary to actually add the record to the end of the file.

Displaying the current record
When a record containing a particular string has been found by FIND it becomes the current record. DISP with -1 as the first parameter, displays it.

In the procedure alter:, VIEW is used to display just the first field of the record, while you decide whether to edit it. If you choose to, each field is then displayed by the EDIT function, which allows you to alter what is on the screen.


18 OPL commands and functions

Summary

Here is a summary of the OPL commands and functions to give you an idea of what is available. This is followed by an alphabetic list which deals with each command and function in detail.

Structures

DO/UNTIL Loops until a condition is met
GOTO label:: Branches to a label
IF/ELSEIF/ELSE/ENDIF Acts conditionally
WHILE/ENDWH Loops while a condition is met
BREAK Exits from loop
CONTINUE Goes to the test condition of loop

General commands

AT Positions the cursor
BEEP Sounds the buzzer
CLS Clears the display
CURSOR ON/OFF Sets the cursor
EDIT Allows a string to be edited on the screen
ESCAPE ON/OFF Allows user to break out of program
GLOBAL Declares variables for all procedures called
INPUT Allows data to be input
KSTAT Sets the keyboard status
LOCAL Declares variables for current procedure only
OFF Turns the organiser off
PAUSE Pauses the program
PRINT Prints to the screen
LPRINT Prints to an attached printer or computer
RANDOMIZE Sets a new sequence of random numbers
REM Precedes a programmer's remark
RETURN Returns to the calling procedure
STOP Exits from OPL

Error handling commands

ONERR label:: Goes to label on error
ONERR OFF Cancels ONERR label::
RAISE Generates an error
TRAP Traps errors on a specified command

Data file handling commands

APPEND Appends current field values to current file
CLOSE Closes a file
COPY Copies a file
CREATE Creates a file
DELETE Deletes a file
ERASE Erases a record
FIRST/LAST/NEXT/BACK Select first/last/next/ previous record
OPEN Opens a file
POSITION Selects a record by number
RENAME Renames a file
UPDATE Updates a record
USE Changes current file

Memory address commands

POKEB Writes a byte to an address
POKEW Writes an integer to two successive addresses

General functions

CHR$ Returns a character with a specified ASCII code
FIX$ Returns a number as a fixed point decimal
FREE Returns the amount of free internal memory
GEN$ Returns a number as a string
GET Waits for a keypress. Returns the ASCII value of the key
GET$ Waits for a keypress. Returns the key as a string
KEY Returns the ASCII value of the key pressed
KEY$ Returns the key pressed as a string
NUM$ Returns a number as an integer
MENU Displays a menu
SPACE Returns free memory space on a device
VIEW Displays a scrolling string on the screen

Error handling functions

ERR Returns error number
ERR$ Returns error message

Data file handling functions

COUNT Returns the number of records in a file
DIR$ Returns file name
DISP Displays a record
EOF Tests for end of file
EXIST Checks to see if a file name exists
FIND Finds a record containing a string
POS Returns the current record number
RECSIZE Returns bytes occupied by the current record

Numeric functions

ABS Returns the absolute (unsigned) value of a floating point number
ATAN Returns the arctangent of a number
COS Returns the cosine of a number
DEG Converts from radians to degrees
EXP Returns e raised to the power you specify
FLT Converts an integer into a floating point number
IABS Returns the absolute (unsigned) value of an integer
INT Returns a rounded down integer number
INTF As above, but returns a floating point number
LN Returns the natural log of a number
LOG Returns the base 10 log of a number
PI Returns Pi (3.14159265135...)
RAD Converts from degrees to radians
RND Returns a random floating point number
SIN Returns the sine of a number
SQR Returns the square root of a number
TAN Returns the tangent of a number
HEX$ Converts an integer into a hexadecimal string

Date functions

DATIM$ Returns the date and time as a string
SECOND/MINUTE/HOUR/DAY/MONTH/YEAR Return information from the clock as numbers

String handling functions

ASC Returns the ASCII value of the first character of a string
LEFT$/MID$/RIGHT$ Select characters from strings according to their position
LEN Returns the length of a string
LOC Returns the location of a string within a string
LOWERS/UPPER$ Convert a string to lower/upper case
REPTS Returns repetitions of a specified string
VAL Converts a numeric string into its floating point value

Memory address functions

ADDR Returns the address of a variable
PEEKB Returns the value stored at an address
PEEKW Returns the value stored at two consecutive addresses

Microprocessor functions

USR Passes values to the microprocessor and returns an integer
USR$ Passes values to the microprocessor and returns a string

Command syntax

Most OPL commands require one or more arguments after them. The arguments may be either literal values or variables.

The following method of specifying the syntax of a command is 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)

<log> Logical file name (A, B, C or D).

<statement list> One or more OPL statements on one or more lines of the procedure.

Function syntax

Functions are used to produce values which can then be assigned to a variable or combined with commands such as PRINT. For example:

The instruction y%=YEAR will assign the integer value 1990 (or whatever the current year is) to the variable y%

The instruction PRINT YEAR will display the number 1990 on the screen

The method of specifying the syntax is the same as for commands.

You can tell what the return type of the function is by the type of the receiving variable shown in the syntax:

Numeric functions which return a floating point value look like this: f=FUNCTION.

Numeric functions which return an integer look like this f%=FUNCTION.

String functions look like this: f$=FUNCTION$.

List of commands and functions

 
ABS
Syntax:a=ABS(<exp>)
Returns the absolute value. i.e. without any sign, of a floating point number. E.g. ABS(-10) is 10.
See also IABS.
 
ADDR
Syntax:n%=ADDR(<var>)
Returns the address at which the variable inside the brackets is stored in memory. You can use an array as the variable, e.g. a%=ADDR(array()), but you can't specify individual elements of an array.
 
APPEND
Syntax:APPEND
Appends the current field values to the end of the current file as a new record.
See also UPDATE.
 
ASC
Syntax:a%=ASC(<exp$>)
Returns the ASCII value of the first character of a string expression.
If you just need the ASCII code for one particular character you can use the % sign. For example, a%=%G returns the ASCII code for the letter G to the variable a%.
 
AT
Syntax:AT <exp1%>,<exp2%>
Positions the cursor at the screen position you specify. <exp1%> is the number of characters across the screen in the range 1 to 16, and <exp2%> (1 or 2) indicates the top or bottom line.
 
ATAN
Syntax:a=ATAN(<exp>)
Returns the arctangent of the expression inside the brackets. The expression represents an angle expressed in radians.
 
BACK
Syntax:BACK
Makes the previous record in the current data file the current record. If the current record is the first record in the file then the current record does not change.
 
BEEP
Syntax:BEEP <exp1%>,<exp2%>
Sounds the internal buzzer of the Organiser. The sound duration is <exp1%> milliseconds. The frequency of the sound is determined by the equation (Frequency = 921600/(78+2*<exp2%>)Hz). Alternatively, the control character 16 can be used in conjunction with the PRINT command and the CHR$ function to sound the buzzer, i.e: PRINT CHR$(16)
 
BREAK
Syntax:BREAK
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).
 
CHR$
Syntax:u$=CHR$(<exp%>)
Returns the ASCII character with the value of the expression inside the brackets. You can use it to print characters unavailable from the keyboard - for example, the instruction PRINT CHR$(63) prints the question mark character. See Appendix A for more information.
 
CLOSE
Syntax:CLOSE
Closes the current file.
See also OPEN, CREATE, DELETE, USE.
 
CLS
Syntax:CLS
Clears the screen. and returns the cursor to the first character space on the top line.
 
CONTINUE
Syntax:CONTINUE
Returns program control to the test expression of either a DO/UNTIL or a WHILE/ENDWH loop. E.g:

DO <statement list> IF <exp> CONTINUE ENDIF <statement list> UNTIL <exp>

In the example, the CONTINUE command will be executed if the expression following the IF statement is true. If this happens, program control will then be transferred to the test expression following the UNTIL instruction.

 
COPY
Syntax:COPY "<dev1>fname1","<dev2>fname2"
COPY "<dev1>fname1","<dev2>"
COPY "<dev1>","<dev2>"
Copies data files from one device to another. There are three variations:

1 In the first example, a file on one device is copied to a file on another device with a different filename. An example might be:

copy "a:clients","b:client88"

If there is already a file on the destination device with the name <fname2>, then the records in the file being copied over are appended to it. Otherwise a new file is created with that name and the records written to it.

2 In the second example, the file name on the destination device is taken to be the same as that on the source device.

3 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 had on the source device.

 
COS
Syntax:c=COS(<exp>)
Returns the cosine of the expression inside the brackets. The expression represents an angle expressed in radians.
 
COUNT
Syntax:c%=COUNT
Returns the number of records in the current file.
See also POS, POSITION.
 
CREATE
Syntax:CREATE "<dev>fname",<log>,fld1,fld2
Creates a data file on device <dev>, with the name fname, the logical file name <log>, and up to 16 fields as specified by fld1, fld2 etc. The logical file name may be A, B, C or D and is used to refer to the file within the program. Each newly created file is automatically OPEN, and up to four files may be open at any one time.
An example of the command might be:

create "a:clients",b,name$,phone$,address$

In this example a data file is created on device A: with the name clients and the logical name B. Each record in the data file can have up to three fields.
See also OPEN, CLOSE, DELETE, USE.

 
CURSOR ON/OFF
Syntax:CURSOR ON or CURSOR OFF
Switches the cursor on or off. The default setting is CURSOR OFF.
 
DATIM$
Syntax:d$=DATIM$
Returns the current date and time from the system clock in string format: e.g:
"MON 17 FEB 1986 16:25:30"
See also SECOND, MINUFE, HOUR, DAY, MONTH, YEAR.
 
DAY
Syntax:d%=DAY
Returns the current day of the month (1 to 31).
See also SECOND, MINUTE, HOUR, MONTH, YEAR, DATIM$.
 
DEG
Syntax:d=DEG(<exp>)
Converts from radians to degrees. Returns the value of the expression in the brackets, representing an angle measured in radians, as a number of degrees.
See also RAD.
 
DELETE
Syntax:DELETE "<dev>fname"
Deletes a data file with the name fname from device <dev>. The file must be closed before this command is given.
See also CREATE, OPEN, CLOSE, USE.
 
DIR$
Syntax:d$=DIR$("<dev>")
d$=DIR$("")
Returns the name of a data file:

1 DIR$(<dev>) returns the name of the first data file on the device specified in the brackets. The device name (A, B or C) must be enclosed in double quotation marks and brackets. E.g: d$=DIR$("A")

2 Subsequent uses of this function with a null string in the brackets will return the names of the following files on the device, until there are no files left on that device, when the function will return a null string.

 
DISP
Syntax:d%=DISP(<exp%>,<exp$>)
Displays a string or a record according to the value of <exp%>. The value of <exp%> may be -1, 0 or 1.

If <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.

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 is 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 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. (13 is the code for the EXE key - see Appendix A for more details.)
See also VIEW and EDIT.

 
DO/UNTIL
Syntax:DO
  <statement list>
UNTIL <exp>
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.
 
EDIT
Syntax:EDIT <var$>
Displays a string which you can edit on the screen using the cursor keys and DEL. <var$> can be a string variable name or a field name.

When you have finished editing, press EXE to return the edited string. If you press EXE before you have made any changes, then the same string will be returned as was included inside the brackets. If you press ON/CLEAR during editing, the string will be cleared and new text may be typed. However, if the TRAP command is used with this command and ON/CLEAR is pressed twice, the string will be cleared and then control will pass on to the next line of the procedure with the ESCAPE error condition being set.
See also DISP and VIEW.

 
ELSE See IF.
 
ENDIF See IF.
 
ENDWH See WHILE.
 
EOF
Syntax:e%=EOF
Tests for the End Of File. Any program instruction which tries to read past the last record in a data file will result in the end of file (EOF) being reached. This can be tested for like this:

DO <statement list> UNTIL EOF

The EOF function returns -1 (True) if the end of file condition has been reached, or 0 (False).

 
ERASE
Syntax:ERASE
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 this command, the current record will be null and EOF will return true.

 
ERR
Syntax:e%=ERR
Returns the number of the last error which occurred. Appendix D has a list of all the error messages in numeric order. The number returned will be in the range 0 to 255. If 0 is returned, there is no error.
See also ERR$, RAISE, ONERR.
 
ERR$
Syntax:e$=ERR$(<exp%>)
Returns an error message as a string. <exp%> can either be a number - e.g. e$=ERR$(240), to return the message for error number 240, or ERR - i.e. e$=ERR$(ERR), to return the message for the last error which occurred. If the number is outside the range 195 to 255. the string returned is "*** ERROR ***". The error messages are listed in Appendix D.
See also ERR, ONERR, RAISE.
 
ESCAPE OFF/ ESCAPE ON
Syntax:ESCAPE OFF or ESCAPE ON
Disenables and enables the ON/CLEAR key. You can normally press ON/CLEAR to pause a running program, and then Q to quit. ESCAPE OFF cancels the use of the ON/CLEAR key to pause.

ESCAPE ON lets the ON/CLEAR key pause the program again. This is the default state.

Warning: If your program enters a loop which has no logical exit, and ESCAPE OFF has been used, you won't be able to quit the program unless you remove the battery from the Organiser. All data in the RAM of the machine will then be lost.

 
EXIST
Syntax:e%=EXIST("<dev>fname")
Tests for the existence of a file called fname on device <dev>. Returns logical true if the file exists and logical false otherwise - so EXIST can be used on an IF statement, for example:

IF EXIST("a:clients") <statement list> ENDIF

See also DIR$.

 
EXP
Syntax:e=EXP(<exp>)
Returns the value of the arithmetic constant e (2.71828...) raised to the power of <exp>.
 
FIND
Syntax:t%=FIND(<exp$>)
Searches the current data file for the string inside the brackets. If found, it returns the record number where the string occurs, and makes the record the current record. If the string is not found, zero is returned.
See also NEXT.
 
FIRST
Syntax:FIRST
Makes the first record in a data file the current record.
See also ERASE, NEXT, POSITION, LAST, BACK, POS.
 
FIX$
Syntax:f$=FIX$(<exp>,<exp1%>,<exp2%>)
Returns a string representation of <exp>, with <exp1%> decimal places in a field which is <exp2%> characters wide. If <exp2%> 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$.

 
FLT
Syntax:f=FLT(<exp%>)
Converts the integer expression inside the brackets into a floating point number.
 
FREE
Syntax:f%=FREE
Returns the number of free bytes in the internal memory of the Organiser.
See also SPACE.
 
GEN$
Syntax:g$=gen$(<exp>,<exp%>)
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$.
 
GET
Syntax:g%=GET
Waits for a key to be pressed and returns the ASCII value or special code for that key. For example, if the A key is pressed in lower case mode, the integer returned is 97. If the EXE key is pressed, the integer returned is 13. See Appendix A for tables of ASCII values and special key codes.
See also GET$, KEY, KEY$, PAUSE.
 
GET$
Syntax:g$=GET$
Waits for a key to be pressed and returns that key as a string. For example, if the A key is pressed in lower case mode. the string returned is "a".
See also GET, KEY, KEY$.
 
GLOBAL
Syntax:GLOBAL var1,var2%,var3$(length),var4(n)
Used to declare variables which will be available in the current procedure and any procedures below it in the program.

Variable names ending with no sign are floating point variables; those ending with a percent sign (%) are integers; those ending with a dollar sign ($) are string variables. String variable names must be followed by the maximum length of the string in brackets.

The last variable in the example above is a floating point array. The number following it in brackets is the number of elements in the array. Array variables may be of any of the three types.

Variable names may be up to 8 alphanumeric characters long, the first of which must be a letter. The length includes the % or $. More than one GLOBAL or LOCAL statement may be used but they must be the first instructions in the procedure. See the chapter on variables for more information.
See also LOCAL.

 
GOTO
Syntax:GOTO label::
Sends program control to the line containing the label name label:: The label must be in the current procedure, and must end with a double colon. Labels may be up to 8 characters long excluding the colons.
 
HEX$
Syntax:h$=HEX$(<exp%>)
Returns the hexadecimal (base 16) version of the integer expression inside the brackets. For example: HEX$(255) will return "FF",
 
HOUR
Syntax:h%=HOUR
Returns the number of the current hour from the system clock (0 to 23).
See also SECOND, MINUTE, DAY, MONTH, YEAR, DATIM$.
 
IABS
Syntax:i%=IABS(<exp%>)
Returns the absolute value, ie. without any sign, of an integer. E.g. IABS(-10) is 10.
 
IF/ELSEIF/ELSE/ENDIF
Syntax:IF <exp>
  <statement list>
ELSEIF <exp>
  <statement list>
ELSE
  <statement list>
ENDIF
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 statement list must be followed by an ENDIF.

The ELSEIF statement is optional. but if it is included, and the following expression returns logcal true - while none of the previous ones have, then the next list of statements are executed. There may be more than one ELSEIF, each with its own list of statements.

The ELSE statement is optional. 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.

 
INPUT
Syntax:INPUT <var%>
INPUT <var>
INPUT <var$>
INPUT <logfile>.fieldname
Allows data to be input from the keyboard during program execution. There are four variations.

The variable supplied must have been declared previously with a GLOBAL or LOCAL command, 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 command may be entered.

If inappropriate input is entered - for example a string when the input command specifies an integer variable - a "?" is displayed and the user is given another chance to make an entry. 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 (no. 206) being set.

 
INT
Syntax:i%=INT(<exp>)
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 Organisers integer range.
See also INTF.
 
INTF
Syntax:i=INTF(<exp>)
Used in the same way as the INT function, but the value returned is a floating point number. You may need this when an integer calculation may exceed the Organiser's integer range, for example: PRINT INTF(32000)*100
 
KEY
Syntax:k%=KEY
Returns the ASCII value of any key pressed. If no key has been pressed, zero is returned. This command does not wait for a key to be pressed.
See also PAUSE, GET, GET$, KEY$.
 
KEYS
Syntax:k$=KEY$
Returns a string containing the key pressed. If no key has been pressed, a null string is returned. This command does not wait for a key to be pressed.
See also KEY, GET, GET$.
 
KSTAT
Syntax:KSTAT <exp%>
Sets the state of the keyboard to SHIFT mode. CAPS mode etc. <exp%> is a number from 1 to 4 according to the following table:

1 Alpha - upper case
2 Alpha - lower case
3 Numeric - upper case
4 Numeric - lower case

 
LEFT$
Syntax:a$=LEFT$(<exp$>,<exp%>)
Returns the leftmost <exp%> characters from the string specified by <exp$>.
See also RIGHT$, MID$, LOWER$, UPPER$, REPT$, LEN, LOC.
 
LEN
Syntax:a%=LEN(<exp$>)
Returns the length of the string expression inside the brackets.
 
LN
Syntax:a=LN(<exp>)
Returns the natural (base e) logarithm of the expression inside the brackets.
See also LOG.
 
LOC
Syntax:a%=LOC(<exp1$>,<exp2$>)
Returns the position in <exp1$> where <exp2$> occurs. If the second string expression does not occur in the first string expression, then the value zero is returned.

E.g. LOC("STANDING","AND") would return the value 3 because the substring "AND" starts at the third character of the main string.

See also LEFT$, RIGHT$, MID$, LEN, LOWER$, UFPER$, REPT$.

 
LOCAL
Syntax:LOCAL var1%,var2,var3$(length),var4(n)
Used to declare variables which will only be available in the current procedure. Other procedures may use the same variable names for other uses. See GLOBAL for more details on declaring variables.
 
LOG
Syntax:a=LOG(<exp>)
Returns the base 10 logarithm of the expression inside the brackets.
See also LN.
 
LOWER$
Syntax:a$=LOWER$(<exp$>)
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$.
 
LPRINT
Syntax:LPRINT <exp>,<exp%>;<exp$>
Prints numbers or text to a printer. If there is no printer attached, a DEVICE MISSING error is reported.

If items to be printed are separated by commas, there is a space between them when printed. If they are separated by semi-colons, there are no spaces. A final semi-colon makes the next items printed with an LPRINT command start immediately after these. A final comma has the same effect but inserts a space. Otherwise the next line in used.

The PRINT command operates like LPRINT, but displays on the screen rather than listing to a printer.

 
MENU
Syntax:m%=MENU(menu$)
Displays a menu of items. 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 and EXE or the initial letter of the selected item, and returns the number of the item selected (1 to...). If ON/CLEAR is pressed, 0 is returned.
 
MID$
Syntax:m$=MID$(<exp$>,<exp1%>,<exp2%>)
Returns a string comprising <exp2%> characters of <exp$>, starting at the character at position <exp1%>.
See also LEFT$, RIGHT$, LOWER$, UPPER$, REPT$, LEN, LOC.
 
MINUTE
Syntax:m%=MINUTE
Returns the current minute number from the system clock (0 to 59).
See also SECOND, HOUR, DAY, MONTH, YEAR, DATIM$.
 
MONTH
Syntax:m%=MONTH
Returns the current month from the system clock (1 to 12).
See also SECOND, MINUTE, HOUR, DAY, YEAR, DATIM$.
 
NEXT
Syntax:NEXT
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 is a null and the EOF function returns true.
See also FIRST, LAST, BACK, POSITION, POS.
 
NUM$
Syntax:n$=NUM$(<exp>,<exp%>)
Returns a string representation of the floating point number <exp> as an integer in a field <exp%> characters wide. If <exp%> is negative then the string is right justified. If the number will not fit in the field width specified then the returned string will contain asterisks.
See also FIX$, GEN$, SCI$.
 
OFF
Syntax:OFF
Switches off the Organiser. If the ON/CLEAR key is pressed, program execution will start again at the program line following the OFF command.
 
OPEN
Syntax:OPEN "<dev>fname",<log>,fld1,fld2
Opens an existing data file on device <dev>, with the logical file name <log>, with the field names as specified by fld1, fld2 etc. That file may then be referred to by the logical file name (A, B, C or D) for all file handling operations. Up to 4 files can be open at once. For more details see the section on opening a file in the data file handling chapter.
See also CREATE, CLOSE, DELETE, USE.
 
ONERR
Syntax:ONERR label:: and ONERR OFF
If an error occurs during program execution, the ONERR label:: instruction transfers program control to the line containing the label.
The ONERR OFF instruction cancels the ONERR label:: statement, so that any errors occurring below the ONERR OFF statement are no longer referred to the label:: It is advisable to put the command ONERR OFF immediately after the label.
 
PAUSE
Syntax:PAUSE <exp%>
Pauses the program according to the value of <exp%>. If <exp%> is:

0 Waits for a key to be pressed.
>0 Pauses the program execution for <exp%> twentieths of a second.
<0 Pauses the program execution for <exp%> (made positive) twentieths of a second or until a key is pressed.

So PAUSE 100 would cause the program to pause for five seconds.

In the first two cases. the key pressed is stored in a buffer. It is wise to remove this with the KEY function like this:

<statement list> PAUSE 0 KEY <statement list>

The procedure stored in the buffer from the PAUSE 0 command is taken as the input for KEY.

 
PEEKB
Syntax:p%=PEEKB(<exp%>)
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.
 
PEEKW
Syntax:p%=PEEKW(<exp%>)
Returns the value of the two byte integer stored at addresses <exp%> and <exp%>+1.
 
PI
Syntax:p=PI
Returns the value of Pi (3.14... ).
 
POKEB
Syntax:POKEB <exp1%>,<exp2%>
Writes the number <exp2%>, which must be in the range 0 to 255, into the memory address <exp1%>, which must be an integer. Addresses above 32767 are addressed by negative values or hexadecimal numbers. E.g. $FFFF = -1, which corresponds to address 65535. Warning: Casual use of this command can result in the loss of all data in the Organiser.
 
POKEW
Syntax:POKEW <exp1%>,<exp2%>
Writes the integer <exp2%> into two successive memory addresses, starting with the address <exp1%>, with the most significant byte in the lower address.
Warning: casual use of this command can result in the loss of all data in the Organiser.
 
POS
Syntax:p%=POS
Returns the record number of the current record in the current data file.
See also POSITION, NEXT, ERASE, APPEND, UPDATE.
 
POSITION
Syntax:POSITION <exp%>
Makes record number <exp%> the current record in the current data file. If <exp%> is greater than the number of records in the file then the EOF function will return true.
See also FIRST, NEXT, LAST, BACK, POS.
 
PRINT
Syntax:PRINT <exp>,<exp%>;<exp$>
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 are no spaces.

A final semi-colon indicates that anything to be printed by the next PRINT statement will start immediately after what is printed by this PRINT statement. A final comma indicates that anything to be printed by the next PRINT statement will follow on the same line with a space inserted between the items. Otherwise the next line is used.

The LPRINT command operates in the same way as the PRINT command except all output is sent to a printer. If there is no printer connected. a DEVICE MISSING error will be reported.

 
RAD
Syntax:n=RAD(<exp>)
Converts <exp> from degrees to radians.
See also DEG.
 
RAISE
Syntax:RAISE <exp%>
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 to use as <exp%> is 192 to 255. Refer to the chapter on error handling for more explanation. A full list of error numbers and messages is in Appendix D.
See also ONERR, ERR, ERR$.
 
RANDOMIZE
Syntax:RANDOMIZE <exp>
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.
See also RND.
 
RECSIZE
Syntax:%RECSIZE
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 date added to it without over-stepping this limit.
 
REM
Syntax:REM text
The REM statement precedes a remark you include to explain how a program works. The Organiser ignores all text after the REM statement up to the end of that line.
 
RENAME
Syntax:RENAME "<dev>fname1","fname2"
Renames a file on device <dev> called fname1 as the file fname2.
 
REPT$
Syntax:r$=REPT$(<exp$>,<exp%>)
Returns a string comprising <exp%> repetitions of <exp$>.
See also LEFT$, RIGHT$, MID$, UPPER$, LOWER$, LEN, LOC.
 
RETURN
Syntax:RETURN or RETURN <exp>
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 alter the RETURN command like this: RETURN <exp%> or RETURN <exp> or RETURN <exp$>

You can make sure a procedure is only able to return a particular type of value by using an identifier as the last character of the procedure name. For example, proc$: can only return a string.

 
RIGHT$
Syntax:r$=RIGHT$(<exp$>.<exp%>)
Returns the rightmost <exp%> characters of <exp$>.
See also LEFT$, MID$, REPT$, LEN, LOC.
 
RND
Syntax:r=RND
Returns a random floating point number in the range 0 (inclusive) to 1 (exclusive).
See also RANDOMIZE.
 
SCI$
Syntax:s$=SCI$(<exp>,<exp1%>,<exp2%>)
Returns a string representation of <exp> in scientific format, to <exp1%> decimal places in a field of width of <exp2%> characters. For example:

SCI$(123456,2,8) = "1.23E+05"
SCI$(1,2,8) = "1.00E+00"
SCI$(123456789,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$.

 
SECOND
Syntax:s%=SECOND
Returns the current number of seconds from the system clock (0 to 59).
See also MINUTE, HOUR, DAY, MONTH, YEAR.
 
SIN
Syntax:s=SIN(<exp>)
Returns the sine of the expression inside the brackets. The expression represents an angle expressed in radians.
 
SPACE
Syntax:s=SPACE
Returns the number of free bytes on the current device. There must be a file open on the device first.
See also FREE.
 
SQR
Syntax:s=SQR(<exp>)
Returns the square root of the expression inside the brackets.
 
STOP
Syntax:STOP
Halts execution of the language and returns the Organiser to the point where that program was started. e.g. the main menu or the calculator.
 
TAN
Syntax:t=TAN(<exp>)
Returns the tangent of the expression inside the brackets. The expression represents an angle expressed in radians.
 
TRAP
Syntax:TRAP <command>
TRAP may precede any of these commands: (APPEND/BACK/CLOSE/COPY/CREATE/ DELETE/ERASE/EDIT/FIRST/INPUT/LAST/ NEXT/OPEN/POSITION/RENAME/UPDATE/USE) For example, TRAP FIRST. Any error resulting from the execution of the command will be trapped - the next program line will be executed regardless of whether the error would normally have caused an error message to be displayed.
 
UNTIL See DO.
 
UPDATE
Syntax:UPDATE
The current record in the current file is deleted and the current field values are appended as a new record at the end of the file.
See also APPEND.
 
UPPER$
Syntax:u$=UPPER$(<exp$>)
Converts any lower case characters in the string expression inside the brackets to upper case. Returns the completely upper case string.
See also LOWER$.
 
USE
Syntax:USE <log>
Selects for use the data file with the logical file name <log> (A, B, C or D), which must previously have been opened with the OPEN or CREATE command.
See also OPEN, CLOSE, CREATE, DELETE.
 
USR
Syntax:u%=USR(<exp1%>,<exp2%>)
The value of <exp2%> is passed to the D register and the value of <exp1%> is passed to the PC register of the HD6303X microprocessor. The microprocessor then executes the machine language program starting at the address <exp1%>. At the end of the routine, the value in the X register is passed back to the language as an integer. Warning: Casual use of this function can result in the loss of all data in the Organiser.
See also USR$, ADDR.
 
USR$
Syntax:u$=USR$(<exp1%>,<exp2%>)
The value of <exp2%> is passed to the D register and the value of <exp1%> is passed to the PC register of the HD6303X microprocessor. The microprocessor then executes the machine language program starting at the address <exp1%>. 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. Warning: Casual use of this command can result in the loss of all data in the Organiser.
See also USR, ADDR.
 
VAL
Syntax:v=VAL(<exp$>)
Returns a floating point number which is the value of the string expression inside the brackets. E.g. VAL("470.0") would return the value 470.0. The string cannot contain any non-numeric characters. Scientific notation is allowed, so VAL("1.3E10") would return the value 1.3E10.
 
VIEW
Syntax:v%=VIEW(<exp%>,<exp$>)
Displays <exp$> on line number <exp%> (1 or 2) on the screen. <exp$> can be a string, a string variable, or a field name.

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 or 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 and EDIT.

 
WHILE/ENDWH
Syntax:WHILE <exp>
  <statement list>
ENDWH
This structure is started by the WHILE command which precedes a numeric 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.

 
YEAR
Syntax:y%=YEAR
Returns the current year from the system date (1900 to 1999).
See also SECOND, MINUTE, HOUR, DAY, MONTH, DATIM$.

Appendix A
Organiser character set

The CHR$ function

The full character set of the Organiser is shown in the table overleaf. The more common characters can obviously just be typed from the keyboard. However, there are others which do not appear on the keys. These are accessed via the OPL CHR$ function.

Printing non-keyboard characters

By supplying the CHR$ function with the appropriate number from the table overleaf, you can print out to the screen or the printer, or assign to string variables, any of the characters shown. For example, to print out a question mark the instruction is: PRINT CHR$(63)

Finding out the ASCII code of a keyboard character

You can find out the ASCII value of any of the characters on the keyboard at any time without looking at the table. You do this by typing the % sign followed by the character in the calculator. For example if you type %P in the calculator, the number 80 is returned.

 

The table shows the characters which have the ASCII codes 32 to 255.
When writing to the screen:
The codes 0 to 7 are for user-defined characters.
The codes 8-16 are for control characters.

Accessing the ASCII value

It is often useful to access the ASCII value of a character - for example if you want to know whether a user has typed in Y or N and you can't remember the ASCII codes for Y and N.

To do this you can use the % sign and the character, e.g. %Y. The example below is part of a procedure in which you are asked whether or not you want to erase something. If you type N the program stops. If you type Y another procedure called erase: is called. If you type a key other than Y or N the procedure goes to a label in order to give you another chance.

PRINT "ERASE Y/N" label:: g%=GET IF g%=%N :STOP ELSEIF g%=%Y :erase: ELSE GOTO label:: ENDIF

Numbers returned by GET and KEY

When the GET and KEY functions are used, the ASCII code for the character on the key is normally returned. The keys not in the ASCII set return these numbers:

1 ON/CLEAR
2 MODE
3
4
5
6
7 SHIFT and DEL
8 DEL
13EXE

User defined characters

For the screen. the numbers 0 to 7 are reserved for user-defined characters. That means that you can define the pattern of dots which appear on the screen when you print those characters with the CHR$ function.

The pound sign below can easily be defined using the program opposite.

Each character is defined line-by-line by a series of eight bytes, which must be poked into memory address $181, starting with the top line of the character. From each of the eight bytes which make up the characters, the least significant five bits 16 to 1 are used (because the characters are only five dots across.)

The program below called define: makes it easy to define these characters. When it is run, it will insert the character you give it into memory where it will remain until you use the program again to change it.

To define the pound character as character number 1, you would enter the number 1 in response to the first prompt then the numbers 6, 9, 9, 12, 8, 24, 31 and 0 in response to the prompts to enter the byte numbers.

define: LOCAL numb%,count%,byte%(9) start:: PRINT "CHAR NUMBER"+CHR$(63); INPUT numb% count%=1 DO PRINT "ENTER BYTE NO. ";Count% INPUT byte%(count%) count%=count%+1 UNTIL count%=9 PRINT "SAVING CHAR..." POKEB $180,64+(numb% AND 7)*8 count%=1 DO POKEB $181,byte%(count%) count%=count%+1 UNTIL count%=9

Then when you want to print the pound character use the instruction:

PRINT CHR$(1)

Note. On the Organiser, the bottom line of any character is best left blank to allow room for the underscore cursor to be clearly distinguished from the character itself.

Control characters

For the screen, the numbers 8 to 16 have special uses. These do not produce a visible character, but may be used to affect parts of the screen in the ways listed:

CHR$(8) Moves the cursor 1 character to the left.
CHR$(9) Moves the cursor to the next tab position. (The tabs are at position 9 and position 17 on the Organiser screen.)
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 and moves the cursor to the bottom left.
CHR$(16) Sounds the Organiser's buzzer.

Appendix B
Technical Data

Dimensions (with protective case closed)

Length - 142.0 mm Width - 78.0 mm Depth- 29.3 mm

Weight (as sold)

250 grams.

Display

Two line by sixteen character alphanumeric dot-matrix liquid crystal display.

Keyboard

A total of thirty six keys including editing, cursor, alphabetic, numeric, MODE and ON/CLEAR.

Microprocessor

HD6303X Frequency 3.6864 MHz.

Memory

Model XPROM 32KRAM 32K
Model CMROM 24KRAM 8K
Extra EPROM 8/16/32/64/128K - from Datapaks.
Extra RAM 32K - from Rampak.

Clock

Real time clock with 32768 Hz crystal frequency source.

Datapaks

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)

Rampaks

Storage medium - battery backed-up RAM.
Capacity - 32768 bytes.

Power

Standard alkaline 9 volt long-life battery. Mains adaptor available.

Psion has a policy of continuous product development. Small modifications arising from this are not necessarily reflected in this manual.


Appendix C
Technical programming

Memory addresses

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:

ADDRESS DEFAULT USE
$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 counter - increments every 50ms
$20CD,$20CE ($012C) Default number of seconds to auto-switch off
$00A4 ($00) Buzzer mute - non-zero value mutes buzzer

The Organiser memory maps are shown overleaf.



Organiser memory maps

Hexadecimal numbers

To get a hexadecimal number in OPL, prefix it with a $ identifier - for example $FF.

Machine language programming

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 debug. 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.

To avoid this, it is wise to save all important data to a pack before testing machine language programs, so that all will not be lost if the machine loses all its data, or 'crashes'.


Appendix D
Error messages

The error messages are listed first in alphabetic order and then in numeric order. Error trapping is covered in Chapter 16.

Error messages in alphabetic order

ARG COUNT ERR   205
An incorrect number of arguments has been supplied to a procedure.
BAD ARRAY SIZE   215
An array has been declared with an illegal number of elements, eg GLOBAL name$(0,15).
BAD ASSIGNMENT   208
An attempt has been made to assign a value to the wrong type of variable - for example by the statement a$=4.3
BAD CHARACTER   219
A non-valid character such as ? or @ has been included in a calculation string or an expression.
BAD DECLARATION   216
A variable has been declared incorrectly - eg GLOBAL name$(300) - where the length of the string exceeds the maximum allowed.
BAD DEVICE CALL   231
Occurs if an illegal operation is requested of a device.
BAD DEVICE NAME   243
A device name other than A, B or C has been used.
BAD FIELD LIST   207
Any file must contain at least one and not more than sixteen fields. Occurs when an attempt is made to exceed these limits.
BAD FILE NAME   236
A file name has been specified which does not conform to the rules. (Max 8 characters. alphanumeric starting with a letter.)
BAD FN ARGS   226
An illegal number or type of arguments has been supplied to a function. eg LOG(-1) or LEN(a).
BAD IDENTIFIER   222
An incorrectly formed variable name has been used. eg name$$.
BAD LOGICAL NAME   209
An illegal logical name has been specified; ie, not A, B, C or D.
BAD NUMBER   218
A number which cannot be evaluated properly has been used. eg 2.3.4
BAD PROC NAME   197
Occurs when an invalid procedure name is given in the NEW option in the PROG menu or inserted in the main menu.
BAD RECORD TYPE   237
Occurs only when running machine language programs.
BATTERY TOO LOW   194
The battery is low. Switch off and see Chapter 10 for instructions on replacing the battery.
DEVICE LOAD ERR   229
A program or peripheral pack has been removed during its verification by the Organiser or the pack has become corrupted.
DEVICE MISSING   230
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.
DEVICE READ FAIL   193
Usually occurs when a pack is faulty or when trying to copy from a copy-protected pack.
DEVICE WRITE FAIL   192
Usually occurs when a pack is faulty or when an attempt is made to write to a write-protected pack such as the Spreadsheet.
DIRECTORY FULL   233
No device may contain more than 110 files. An attempt has been made to create a file which exceeds this limit.
DIVIDE BY ZERO   251
An attempt has been made to divide by zero.
DUPLICATE NAME   214
The file, procedure or variable name given is already in existence on the current device.
END OF FILE   238
Occurs when an attempt is made to read past the end of a data file.
ESCAPE   206
The ON/CLEAR key followed by Q has been pressed during program execution. halting that program.
EXPONENT RANGE   253
A number has exceeded the exponent limit of plus or minus 99.
FIELD MISMATCH   201
Occurs when a field variable used does not match any of those in any logical file.
FILE EXISTS   235
An attempt has been made to create a file or procedure under a name which already exists on that device.
FILE IN USE   199
An attempt has been made to open a file which is already open, or to delete a file which is open.
FILE NOT FOUND   234
An attempt has been made to access a file which does not exist on the specified device.
FILE NOT OPEN   196
An attempt has been made to write to or read from a file which is not open.
FN ARGUMENT ERR   247
The wrong type of argument has been passed to a function or a user's procedure.
INTEGER OVERFLOW   195
The range of numbers allowed for integer variables (-32768 to +32767) has been exceeded.
MENU TOO BIG   202
The string supplied to the MENU function is too large and must be shortened.
MISMATCHED "   221
Occurs when quotation marks are not paired up correctly.
MISMATCHED ()'s   227
Brackets have not been paired up correctly.
MISSING COMMA   210
A comma has been omitted from a list of items which should be delimited by commas throughout.
MISSING EXTERNAL   204
A variable has been encountered which has not been declared in a calling procedure as a global variable and has not been declared in the current procedure as a local or global variable.
MISSING LABEL   211
An attempt has been made to GOTO a label which does not exist in the current procedure.
MISSING PROC   203
A procedure has been called which does not exist on any device.
NAME TOO LONG   223
The specified file, procedure or variable name exceeds the maximum number of characters allowed: eight characters including the $ or % qualifier.
NO ALLOC CELLS   255
Seen only when running machine language routines which access internal buffer space.
NO PACK   248
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.
NO PROC NAME   217
An externally created program file has been introduced which does not have a valid procedure name as its first line.
NUM TO STR ERR   250
Only occurs when calling operating system machine language routines.
OUT OF MEMORY   254
Either the internal memory of the machine is fully occupied by programs, diary entries and the data files, or the current program has used up all available memory.
PACK CHANGED   242
Occurs when calling operating system machine language routines or when a pack is changed in the middle of a COPY.
PACK FULL   239
An attempt has been made to write to a Datapak which is already full.
PACK NOT BIANK   241
Datapak needs to be re-formatted as residual data is still present.
PAK NOT COPYABLE   232
An attempt has been made to copy a pack which is copy-protected.
READ ONLY PACK   244
An attempt has been made to write to a program pack. These may be read from, but not written to.
READ PACK ERROR   200
The data in a Datapak cannot be read and the pack needs re-formatting.
RECORD TOO BIG   198
No record may exceed a total of 254 characters.
STACK OVERFLOW   249
Will only occur when users machine language program destroys the Organiser's stack.
STACK UNDERFLOW   248
As above.
STRING TOO LONG   220
A string has been produced which exceeds the space allocated with the GLOBAL or LOCAL commands. eg: LOCAL a$(10) A$="123456789ABCDEF"
STR TO NUM ERR   252
A non-numeric string has been passed to the VAL function.
STRUCTURE ERR   213
An IF/ENDIF, WHILE/ENDWH or DO/UNTIL structure has been incorrectly nested.
SUBSCRIPT ERR   225
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.
SYNTAX ERR   228
A syntax error has been detected during the translation of a procedure.
TOO COMPLEX   212
Structures within a procedure have been nested too deeply. The limit is 8.
TYPE MISMATCH   224
A value has been assigned to variable of the wrong type. eg a$=12 or a="text", or a procedure parameter has been given a value of the wrong type.
UNKNOWN PACK   240
A pack not supported by the Organiser II has been fitted to one of the devices.
WRITE PACK ERR   245
The Organiser cannot write data to one of the Datapaks. Try re-fitting it.

Messages in numeric order

192  DEVICE RED FAIL
Usually occurs when a pack is faulty or when trying to copy from a copy-protected pack.
193  DEVICE WRITE FAIL
Usually occurs when a pack is faulty or when an attempt is made to write to a write-protected pack such as the Spreadsheet.
194  BATTERY TOO LOW
The battery is low. Switch off and see Chapter 10 for instructions on replacing the battery.
195  INTEGER OVERFLOW
The range of numbers allowed for integer variables (-32768 to +32767) has been exceeded.
196  FILE NOT OPEN
An attempt has been made to write to or read from a file which is not open.
197  BAD PROC NAME
Occurs when an invalid procedure name is given in the NEW option in the PROG menu or inserted in the main menu.
198  RECORD TOO BIG
No record may exceed a total of 254 characters.
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.
200  READ PACK ERROR
The data in a Datapak cannot be read and the pack needs reformatting.
201  FIELD MISMATCH
Occurs when a field variable used does not match any of those in any logical file.
202  MENU TOO BIG
The string supplied to the MENU function is too large and must be shortened.
203  MISSING PROC
A procedure has been called which does not exist on any device.
204  MISSING EXTERNAL
A variable has been encountered which has not been declared in a calling procedure as a global variable and has not been declared in the current procedure as a local or global variable.
205  ARG COUNT ERR
An incorrect number of arguments has been supplied to a procedure.
206  ESCAPE
The ON/CLEAR key followed by Q has been pressed during program execution, halting that program.
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.
208  BAD ASSIGNMENT
An attempt has been made to assign a value to the wrong type of variable - for example by the statement a$=4.3
209  BAD LOGICAL NAME
An illegal logical name has been specified; ie. not A, B, C or D.
210  MISSING COMMA
A comma has been omitted from a list of items which should be delimited by commas throughout.
211  MISSING LABEL
An attempt has been made to GOTO a label which does not exist in the current procedure.
212  TOO COMPLEX
Structures within a procedure have been nested too deeply. The limit is 8.
213  STRUCTURE ERR
An IF/ENDIF, WHILE/ENDWH or DO/UNTIL structure has been incorrectly nested.
214  DUPLICATE NAME
The file, procedure or variable name given is already in existence on the current device.
215  BAD ARRAY SIZE
An array has been declared with an illegal number of elements. eg GLOBAL name$(0,15).
216  BAD DECLARATION
A variable has been declared incorrectly - eg GLOBAL name$(300) - where the length of the string exceeds the maximum allowed.
217  NO PROC NAME
An externally created program file has been introduced which does not have a valid procedure name as its first line.
218  BAD NUMBER
A number which cannot be evaluated properly has been used. eg 2.3.4
219  BAD CHARACTER
A non-valid character such as ? or @ has been included in a calculation string or an expression.
220  STRING TOO LONG
A string has been produced which exceeds the space allocated with the GLOBAL or LOCAL commands. eg:
LOCAL a$(10)
A$="123456789ABCDEF"
221  MISMATCHED "
Occurs when quotation marks are not paired up correctly.
222  BAD IDENTIFIER
An incorrectly formed variable name has been used. eg name$$.
223  NAME TOO LONG
The specified file. procedure or variable name exceeds the maximum number of characters allowed: eight characters including the $ or % qualifier.
224  TYPE MISMATCH
A value has been assigned to variable of the wrong type. eg a$=12 or a="text", or a procedure parameter has been given a value of the wrong type.
225  SUBSCRIPT ERR
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.
226  BAD FN ARGS
An illegal number or type of arguments has been supplied to a function. eg LOG(-1) or LEN(a).
227  MISMATCHED ()'s
Brackets have not been paired up correctly.
228  SYNTAX ERR
A syntax error has been detected during the translation of a procedure.
229  DEVICE LOAD ERR
A program or peripheral pack has been removed during its verification by the Organiser or the pack has become corrupted.
230  DEVICE MISSING
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.
231  BAD DEVICE CALL
Occurs if an illegal operation is requested of a device.
232  PAK NOT COPYABLE
An attempt has been made to copy a pack which is copy-protected.
233  DIRECTORY FULL
No device may contain more than 110 files. An attempt has been made to create a file which exceeds this limit.
234  FILE NOT FOUND
An attempt has been made to access a file which does not exist on the specified device.
235  FILE EXISTS
An attempt has been made to create a file or procedure under a name which already exists on that device.
236  BAD FILE NAME
A file name has been specified which does not conform to the rules. (Max 8 characters. alphanumeric starting with a letter.)
237  BAD RECORD TYPE
Occurs only when running machine language programs.
238  END OF FILE
Occurs when an attempt is made to read past the end of a data file.
239  PACK FULL
An attempt has been made to write to a Datapak which is already full.
240  UNKNOWN PACK
A pack not supported by the Organiser II has been fitted to one of the devices,
241  PACK NOT BLANK
Datapak needs to be re-formatted as residual data is still present.
242  PACK CHANGED
Occurs when calling operating system machine language routines or when a pack is changed in the middle of a COPY.
243  BAD DEVICE NAME
A device name other than A, B or C has been used.
244  READ ONLY PACK
An attempt has been made to write to a program pack. These may be read from, but not written to.
245  WRITE PACK ERROR
The Organiser cannot write data to one of the Datapacks. Try re-fitting it.
246  NO PACK
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.
247  FN ARGUMENT ERR
The wrong type of argument has been passed to a function or a user's procedure.
248  STACK UNDERFLOW
As above.
249  STACK OVERFLOW
Will only occur when users machine language program destroys the Organiser's stack.
250  NUM TO STR ERR
Only occurs when calling operating system machine language routines.
251  DIVIDE BY ZERO
An attempt has been made to divide by zero.
252  STR TO NUM ERR
A non-numeric string has been passed to the VAL function.
253  EXPONENT RANGE
A number has exceeded the exponent limit of plus or minus 99.
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.
255  NO ALLOC CELLS
Seen only when running machine language routines which access internal buffer space.

Appendix E
Troubleshooting

Missing item on main menu

1 Place the cursor at the position in the menu where you want the item to be.

2 Press MODE and the screen shows:

INSERT ITEM  

3 Type in the name of the missing item and press EXE.

The name will reappear, pushing the items that follow to the right.

OUT OF MEMORY message

If you are get this message, it means that you must free some internal memory. Do this by tidying the diary, or erasing unwanted records or procedures.

To tidy the diary:

1 Press MODE from within the diary to get the diary menu.

2 Press T and check that the date on the top line is the current one, so that you will delete only out-of-date entries. Then press Y to confirm.

If you still get the OUT OF MEMORY message try erasing unwanted records or procedures - you can copy them onto a Datapak first if you want to keep them.

BATTERY TOO LOW message

When you get this message it means that your battery is about to run out. The Organiser switches itself off when this happens, and you should not switch it on again. Do not remove the battery until you are ready to put a new one in.

The battery goes in with the + connector first.

When you have the new battery ready you can replace it as follows with the machine switched off:

1 Remove the old battery.

2 Fit the new one within 90 seconds or all the data in the internal memory will be deleted.

If you use the Psion Mains Adaptor you can power the Organiser from the mains whilst you change the battery. There is then no time limit.

Keypress beeps

If you are typing and keypresses start being ignored and cause a beep. you are trying to enter too many characters. The limit is 64 characters in a diary entry and 254 characters on a maximum of 16 lines in a database record.

Question mark "?" on screen

If a "?" appears on the screen, an OPL program is using the INPUT command and you have entered inappropriate data - for example text when a number was expected. Try again with the right kind of data.

Stuck in an OPL program

You can usually break out of a running OPL program by pressing ON/CLEAR followed by Q. However, if an OPL program has a loop in it which reads keys with a command such as GET, KEY or INPUT, it may be very hard to break out in this way. Try pressing ON / CLEAR followed by Q repeatedly and very rapidly.

(OPL programs should be designed to avoid this situation.)

PSION Service Department

If you believe that you have a faulty Datapak or Organiser contact the Psion service department:

Psion PLC
Service Department
Standard Road
London NW10 6EU
Tel: 01 965 8626


Index

!

$ sign for hexadecimal numbers C-3 for string variables 12-4 on procedure name 12-16 % sign for integer variables 12-3 on procedure name 12-16 used to access ASCII values A-3 ? character printing A-1 ? sign appears on screen what to do E-1 £ sign printing A-4

A

aborting running procedures 11-13 ABS function (OPL) syntax an summary 18-8 ADDR function (OPL) syntax and summary 18-8 addresses, in memory C-1 alarms 4-1 to 4-4 cancelling 4-3 example program to mute 17-10 on diary entries 5-3 repeating 4-3 switching off 4-2 AND, logical operator explained 14-6 APPEND command (OPL) explained 15-4 syntax and summary 18-8 ARG COUNT ERR D-1 arithmetic operators 14-1 array variables 12-6 example integer array 12-6 ASC function(OPL) syntax and summary 18-8 ASCII codes accessing with % A-3 table of A-2 ASCII values, accessing A-3 AT command (OPL) syntax and summary 18-9

ATAN function (OPL) syntax and summary 18-9 auto scrolling 3-2 auto switch off 1-6

B

BACK command (OPL) explained 15-5 syntax and summary 18-9 BAD ARRAY SIZE D-1 BAD ASSIGNMENT D-1 BAD CHARACTER D-1 BAD DECLARATION D-1 BAD DEVICE CALL D-2 BAD DEVICE NAME D-2 BAD FIELD LIST D-2 BAD FILE NAME D-2 BAD FN ARGS D-2 BAD IDENTIFIER D-2 BAD LOGICAL NAME D-2 BAD NUMBER D-2 BAD PROC NAME D-3 BAD RECORD TYPE D-3 battery fitting 1-1 replacing 10-1 time limit on replacing 10-1 voltage 1-1 BATFERY TOO LOW D-3 BEEP command (OPL) syntax and summary 18-9 beeping keyboard what to do E-2 branches 13-4 BREAK command (OPL) explained 13-3 syntax and summary 18-9 breaking out of OPL program E-1

C

calculator 6-1 to 6-7 decimal places 6-2 memories 6-2 operators in 6-1 OPL functions in 6-5 OPL procedures in 6-6 percentages in 6-4 calculator memories as OPL variables 12-6 CAP key 2-2

characters accessing ASCII code A-3 control A-6 printing non-key ones A-1 program for defining A-5 user defined A-4 user-defined, example 17-12 CHRS function (OPL) explained A-1 syntax and summary 18-10 clock setting 1-5 technical details B-1 See TIME CLOSE command (OPL) explained 15-8 syntax and summary 18-10 CLS command (OPL) explained 11-4 syntax and summary 18-10 commas, in OPL syntax 11-4 concatenating strings 12-11 CONTINUE command (OPL) syntax and summary 18-10 control characters A-6 COPY main menu option 9-3 PROG menu option 11-12 COPY command (OPL) syntax and summary 18-11 copying files 9-3 procedures 11-12 records 3-5 COS function (OPL) syntax and summary 18-11 COUNT function (OPL) syntax and summary 18-12 CREATE command (OPL) explained 15-3 syntax and summary 18-12 CURSOR command (OPL) syntax and summary 18-12

D

data files 15-1 to 15-8 creating in OPL 15-3 example program for handling 17-19 Datapaks changing 8-2 explained 8-2 formatting 8-4 new 8-3 saving records on 2-4 sizing 8-3 technical details B-2 date setting 1-5 DATIM$ function (OPL) syntax and summary 18-12 DAY function (OPL) syntax and summary 18-13 decimal places setting in calculator 6-2 declaring variables explained 12-2 LOCAL and GLOBAL 12-4 DEG function (OPL) syntax and summary 18-13 DEL key 2-3 DELETE command (OPL) syntax and summary 18-13 deleting all data 8-6 DEVICE LOAD ERR D-3 DEVICE MISSING D-3 DEVICE READ FAIL D-3 DEVICE WRITE FAIL D-3 devices 8-1 diary 5-1 to 5-12 alarms 5-3 editing entries 5-7 erasing out-dated entries 5-9 making an entry 5-2 menu 5-5 moving thro the pages 5-1 saving to a Datapak 5-9 diary menu DIR 5-10 ERASE 5-11 FIND 5-7 getting to 5-5 GOTO 5-8 LIST 5-6 PAGE 5-6 RESTORE 5-10 SAVE 5-9 TIDY 5-9 dimensions of Organiser B-1 DIR diary menu 5-10 PROG menu option 11-11 DIR$ function (OPL) syntax and summary 18-13 directory of diaries 5-10 of procedures 11-11 DIRECTORY FULL D-4 display technical details B-1 DIVIDE BY ZERO D-4 DO/UNTIL command (OPL) syntax and summary 18-15 DO/UNTIL commands (OPL) explained 13-1 syntax and summary 18-10 DUPLICATE NAME D-4

E

EDIT PROG menu option 11-10 EDIT command (OPL) syntax and summary 18-15 editing diary entries 5-7 procedures 11-10 records 3-3 ELSE statement (OPL) syntax and summary 18-22 END OF FILE D-4 EOF function (OPL) syntax and summary 18-16 ERASE diary menu 5-11 main menu 3-4 PROG menu 11-11 ERASE command (OPL) explained 15-6 syntax and summary 18-16 erasing all data 8-6 procedures 11-11 records 3-4 ERR function (OPL) explained 16-8 syntax and summary 18-16 ERR$ function (OPL) syntax and summary 18-17 error messages 16-8 errors common OPL errors 16-1 generating and debugging 16-8 messages 16-8 run-time 16-4 ESCAPE D-4 ESCAPE ON/OFF command (OPL) risks of 13-5 syntax and summary 18-17 escaping from procedures 11-13, 13-5, E-1 EXE key 1-4 EXIST function (OPL) syntax and summary 18-18 EXP function (OPL) syntax and summary 18-18 EXPONENT RANGE D-4

F

FIELD MISMATCH D-4 fields field names 15-3 field qualifiers 15-3 handling in OPL 15-2 input to 15-4 FILE EXISTS D-4 FILE IN USE D-5 FILE NOT FOUND D-5 FILE NOT OPEN D-5 files changing current in OPL 15-8 closing in OPL 15-8 copying from main menu 9-2 copying to/from Datapak 9-3 creating in OPL 15-3 example program for handling 17-19 handling in OPL 15-1 to 15-8 opening in OPL 15-7 FIND diary menu 5-7 main menu 3-1 FIND function (OPL) explained 15-6 syntax and summary 18-18 finding diary entry 5-7 records 3-1 FIRST command (OPL) explained 15-5 syntax and summary 18-18 FIX$ function (OPL) syntax and summary 18-19 FIX= in calculator 6-2 floating point variables explained 12-5 precedence in OPL 14-3 range 12-3 rounded down 12-10 type conversion 12-8 FLT function (OPL) syntax and summary 18-19 FN ARGUMENT ERR D-5 formatting Datapaks 8-4 FREE function (OPL) syntax and summary 18-19

G

GEN$ function (OPL) syntax and summary 18-19 GET function (OPL) accessing ASCII codes A-3 explained 11-5 numbers returned by A-3 syntax and summary 18-20 GET$ function (OPL) syntax and summary 18-20 GLOBAL command (OPL) explained 12-4 syntax and summary 18-20 GOTO command (OPL) explained 13-3 syntax and summary 18-21 GOTO, diary menu 5-8

H

HEXS function (OPL) syntax and summary 18-21 hexadecimal numbers C-3 HOUR function (OPL) explained 11-4 syntax and summary 18-21

I

IABS function syntax and summary 18-21 IF/ELSEIF/ELSE command (OPL) explained 13-4 IF/ELSEIF/ELSE/ENDIF command (OPL) syntax and summary 18-22 INFO, main menu option 8-5 INPUT command (OPL) explained 12-13 in example input routine 17-7 syntax and summary 18-23 INT function (OPL) syntax and summary 18-23 INTEGER OVERFLOW D-5 integer variables explained 12-3 range 12-3 type conversion 12-8 INTF function (OPL) syntax and summary 18-24

J

joining lines 2-3 jumps in procedures 13-3

K

KEY function (OPL) numbers returned by A-3 syntax and summary 18-24 KEYS function (OPL) syntax and summary 18-24

keyboard beeping, what to do E-2 getting used to 2-2 KSTAT command (OPL) syntax and summary 18-24

L

labels with ONERR command 16-5 labels with GOTO command 13-3 LAST command (OPL) explained 15-5 LEFT$ function (OPL) explained 12-11 syntax and summary 18-25 LEN function (OPL) syntax and summary 18-25 LIST diary menu 5-6 PROG menu option 11-10 listing procedures 11-10 LN function (OPL) syntax and summary 18-25 LOC function (OPL) syntax and summary 18-25 LOCAL command (OPL) explained 12-4 syntax an summary 18-26 LOG function (OPL) syntax and summary 18-26 logical expressions in OPL 14-4 logical file names 15-3 logical operators 14-7 to 14-8 with floating point values 14-6 with integer values 14-6 loops 13-1 to 13-5 breaking out of 13-5 endless, how to avoid 13-5 maximum nested 13-1 low battery 10-1 LOWER$ function (OPL) syntax and summary 18-26 lowercase letters typing in 2-2 LPRINT command (OPL) syntax and summary 18-26

M

machine language C-3 main file copying to Datapak 9-2 main menu 1-4 customising 7-1 deleting options from 7-2 missing item E-1 replacing options 7-3 selecting options from 1-4 summary of options 7-1 memories calculator as OPL variables 12-6 in calculator 6-2 memory what to do when out of 12-1 memory maps C-1 MENU function (OPL) syntax and summary 18-27 MENU TOO BIG D-5 messages error 16-8 microprocessor, technical details B-1 MID$ function (OPL) explained 12-11 syntax and summary 18-27 MINUTE function (OPL) syntax and summary 18-27 MISMATCHED " D-5 MISMATCHED ()'s D-5 MISSING COMMA D-6 MISSING EXTERNAL D-6 MISSING LABEL D-6 MISSING PROC D-6 MONTH function (OPL) syntax and summary 18-27

N

NAME TOO LONG D-6 names of procedures 12-1 of variables 12-2 NEW option 11-3 NEXT command (OPL) explained 15-5 syntax and summary 18-28 NO ALLOC CELLS D-6 NO PACK D-6 NO PROC NAME D-7 NOT, logical operator explained 14-6 NUM key 2-2 NUM TO STR ERR D-7 NUM$ function (OPL) syntax and summary 18-28 numbers typing in 2-2

O

object files copying 11-12 OFF command (OPL) syntax and summary 18-28 OFF main menu option 1-6 ONERR command (OPL) explained 16-5 syntax and summary 18-29 OPEN command (OPL) explained 15-7 syntax and summary 18-29 operators available in OPL 14-1 in the calculator 6-1 precedence in OPL 14-2 OPL commands APPEND 18-8 AT 18-9 BACK 18-9 BEEP 18-9 BREAK 18-9 CLOSE 18-10 CLS 18-10 COPY 18-11 CREATE 18-12 CURSOR 18-12 DELETE 18-13 DO/UNTIL. 18-15 EDIT 18-15 ERASE 18-16 ESCAPE ON/OFF 18-17 FIRST 18-18 GLOBAL 18-20 GOTO 18-21 IF/ELSEIF/ELSE/ENDIF 18-22 INPUT 18-23 KSTAT 18-24 LOCAL 18-26 LPRINT 18-26 NEXT 18-28 OFF 18-28 ONERR 18-29 OPEN 18-29 PAUSE 18-30 POKEB 18-31 POKEW 18-32 POSITION 18-32 PRINT 18-32 RAISE 18-33 RANDOMIZE 18-33 REM 18-34 RENAME 18-34 RETURN 18-34 STOP 18-37 TRAP 18-37 UPDATE 18-38 USE 18-38 WHILE/ENDWH 18-40 OPL functions ABS 18-8 ADDR 18-8 ASC 18-8 ATAN 18-9 CHR$ 18-10, A-1 COS 18-11 COUNT 18-12 DATIM$ 18-12 DAY 18-13 DEG 18-13 DIR$ 18-13 EOF 18-16 ERR 18-16 ERR$ 18-17 EXIST 18-18 EXP 18-13 FIND 18-13 FIX$ 18-19 FLT 18-19 FREE 18-19 GEN$ 18-19 GET 18-20 GET$ 18-20 HEX$ 18-21 HOUR 18-21 IABS 18-21 INT 18-23 INTF 18-24 KEY 18-24 KEY$ 18-24 LEFT$ 18-25 LEN 18-25 LN 18-25 LOC 18-25 LOG 18-26 LOWER$ 18-26 MENU 18-27 MID$ 18-27 MINUTE 18-27 MONTH 18-27 NUM$ 18-23 PEEKB 18-31 PEEKW 18-31 PI 18-31 POS 18-32 RAD 18-33 RECSIZE 18-34 REPT$ 18-34 RIGHT$ 18-35 RND 18-35 SCI$ 18-36 SECOND 18-36 SIN 18-36 SPACE 18-36 SGN 18-37 TAN 18-37 UPPER$ 18-33 USR 18-38 USR$ 18-39 VAL 18-39 YEAR 18-40 OPL functions in calculator 6-5 OR, logical operator explained 14-6 OUT OF MEMORY D-7 what to do E-1

P

PACK CHANGED D-7 PACK FULL D-7 PACK NOT BIANK D-7 PAGE, diary menu 5-6 PAK NOT COPYABLE D-7 parameters explained 12-14 multiple 12-15 returning 12-16 passwords example program to set 17-10 PAUSE command (OPL) syntax and summary 18-30 PEEKB function (OPL) syntax and summary 18-31 PEEKW function (OPL) syntax and summary 18-31 percentages in calculator 64 PI function (OPL) syntax and summary 18-31 POKEB command (OPL) syntax and summary 18-31 POKEW command (OPL) syntax and summary 18-32 POS function (OPL) explained 15-5 syntax and summary 18-32 POSITION command (OPL) explained 15-5 syntax and summary 18-32 pound sign printing A-4 PRINT command (OPL) explained 11-4 syntax and summary 18-32 printing procedures 11-10 procedure names length and format 12-1 procedures copying 11-12 creating 11-2 editing new 11-5 editing old 11-10 erasing 11-11 escaping from 11-13, 13-5 examples 17-1 to 17-22 in calculator 6-6 introduction to 11-1 listing/printing 11-10 names 11-3 names format 12-1 quitting out of 11-13, 13-5 running 11-9 running from menus 12-17 saving 11-7 to 11-8 translating 11-5, 11-7 PROG TRAN/SAVE/QUIT menu 11-6 PROG menu summary of 11-2 program labels 13-3 programs See procedures programs, examples 17-1 to 17-22

Q

question mark printing A-1 QUIT, PROG option 11-6 quitting running procedures 11-13, 13-5 quotation marks in strings 12-12

R

RAD function (OPL) syntax and summary 18-33 RAISE command (OPL) explained 16-8 syntax and summary 18-33 Rampaks explained 8-2 RANDOMIZE command (OPL) syntax and summary 18-33 READ ONLY PACK D-7 READ PACK ERROR D-8 RECORD TOO BIG D-8 records abandoning 2-3 adding to file in OPL 15-4 changing current in OPL 15-5 copying to/from Datapak 3-5, 9-2 editing 3-3 erasing 3-4 erasing in OPL 15-6 finding 3-1 finding in OPL 15-6 hints about 9-1 maximum size 9-1 saving 2-1

RECSIZE function (OPL) syntax and summary 18-34 REM command (OPL) syntax and summary 18-34 RENAME command (OPL) syntax and summary 18-34 repeating alarms 4-3 REPT$ function (OPL) syntax and summary 18-34 RESET, main menu option 8-6 RESTORE, diary menu 5-10 RETURN command (OPL) explained 12-16 syntax and summary 18-34 RIGHT$ function (OPL) explained 12-11 syntax and summary 18-35 RND function (OPL) syntax and summary 18-35 RUN PROG menu option 11-9 running procedures 11-9

S

SAVE diary menu 5-9 main menu 2-1 PROG menu 11-8 saving diaries 5-9 procedures 11-7 to 11-8 records 2-1 records on a Datapak 2-4 SCI$ function (OPL) syntax and summary 18-36 search-clue 3-1 SECOND function (OPL) syntax and summary 18-36 semi-colons, in OPL syntax 11-4 SHIFT key 2-2 SIN function (OPL) syntax and summary 18-36 sizing Datapaks 8-3 slicing strings 12-11 SPACE function (OPL) syntax an summary 18-36 SQR function (OPL) syntax and summary 18-37 STACK OVERFLOW D-8 STACK UNDERFLOW D-8 STOP command (OPL) syntax and summary 18-37 STR TO NUM ERR D-8 STRING TOO LONG D-8 string variables explained 12-4 strings concatenating 12-11 explained 11-4 maximum len 12-4 quotation marks in 12-12 slicing 12-11 STRUCTURE ERR D-8 SUBSCRIPT ERR D-8 switching off automatically 1-6 manually 1-6 switching on 1-2 SYNTAX ERR D-9 system variables C-1

T

TAN function (OPL) syntax and summary 18-37 TIDY, diary menu 5-9 TIME, setting 1-5 TOO COMPLEX D-9 TRAN, PROG option 11-7 translating procedures 11-7 TRAP command (OPL) explained 16-7 syntax and summary 18-37 trapping errors in OPL 16-4 type conversion, automatic 12~8 type conversion, string/numeric 12-10 TYPE MISMATCH D-9

U

UDGs example program using 17-12 program for defining A-5 UNKNOWN PACK D-9 UPDATE command (OPL) syntax and summary 18-38 UPPER$ function (OPL) syntax and summary 18-38 USE command (OPL) explained 15-8 syntax and summary 18-38 user defined characters explained A-4 program for defining A-5 user defined graphics example program using 17-12 USR function (OPL) syntax and summary 18-38 USR$ function (OPL) syntax and summary 18-39

V

VAL function (OPL) syntax and summary 18-39 variables 12-2 array 12-6 explained 12-2 floating point 12-3 GLOBAL v LOCAL 12-5 Int./floating pt. conversion 12-8 Integer 12-3 names 12-2 operations upon 12-8 string 12-4 VIEW function (OPL) syntax and summary 18-40

W

weight of Organiser B-1 WHILE/ENDWH command (OPL) explained 13-1 syntax and summary 18-40 WRITE PACK ERR D-9

Y

YEAR function (OPL) syntax and summary 18-40