OPL has evolved from the Psion Organiser II through the MC and HC computers to the Series 3 and now Series 3a. This appendix explains the changes made. For more details of the following topics and keywords, look them up in the index or table of contents.
Bear in mind that some OPL keywords return or allow different values according to screen size and keyboard layout.
Note: the comparisons against HC and MC OPL in this appendix assume the original versions of these computers. Some of the Series 3/3a OPL features may be incorporated into future releases in the HC and MC ranges.
To create an OPL module, press the System button, and move the cursor to the Program icon. (You can also do this with Psion-Control-Word, as Control-Word is initially set to act like a `Program' button.) Select `New file' from the `File' menu, give the name to use, and then type in the module. The editing features are the same as in Word, but the `Paragraphs' and `Styles' menus are missing, and the `Word' menu has been replaced by a `Prog' menu, containing new programming options. Select its `Translate' option to translate the module, then the `Run' option to run it. You can also run the translated module from the System screen, as its name automatically appears under a `RunOpl' icon move the cursor right to the RunOpl icon, then down onto the module name, and press Enter.
Existing OPL modules are listed under the Program icon on the System screen. To edit one, move the cursor onto the module name and press Enter.
To stop a running program, press Psion-Esc.
The Series 3a screen is 480 points (pixels) wide by 160 points deep.
OPL programs can be translated as applications which appear in the System screen. This is done with the APP keyword. You can also select the type of application using keyword TYPE, and the icon using ICON, the filename extension of files to be listed under the icon in the System screen using EXT and the directory in which these files are stored using PATH.
If you use the `S3 Translate' option on the `Prog' menu, the Program editor will translate as if for the Series 3. The translated program can then be run on either a Series 3 or a Series 3a; on the latter it will run in compatibility mode.
If you use the `Translate' option on the `Prog' menu, the translated program will run only on the Series 3a.
Modules translated for the Series 3 (not the Series 3a) are also compatible with HC and MC computers, provided that they only use keywords also available on those machines. You can build code libraries which can be used on all four machines, bearing in mind differences between screen size, location of files etc.
There is more about compatibility with the Series 3 towards the end of this chapter. The information includes some rules for combining modules when some of them are translated for Series 3 and some for Series 3a.
Procedures translated on the Organiser need re-translation, as they will not run on the Series 3a.
The Series 3a uses the same MS-DOS filing system as the MC and Series 3, although for everyday use it `hides' the directories from you. The directories and file extensions concerned with OPL are:
Type of file Directory File extension
OPL modules \OPL .OPL translated modules \OPO .OPO data files \OPD .ODB bitmaps \OPD .PIC
More than one procedure may be stored in a single .OPL file, or module. The beginning of each procedure is identified by the line "PROC procedure name:" and the end of each procedure by the line "ENDP". So a module might look like this:
PROC oneroot: LOCAL x PRINT "Type a number:" INPUT x root:(x) GET ENDP
PROC root:(p) CLS PRINT "Root of",p,"is",sqr(p) ENDP
When you run the module, the first procedure in the module is executed. Any other procedures in the module are available to be called by the first procedure.
Procedures can be called from other modules only if you've loaded the modules with the new LOADM command. Up to 4 modules can be held in memory at any one time. Use UNLOADM to remove a module from memory.
Data files now have a special format. Records can be a maximum of 1022 bytes long.
The FIND function compares a search string against entire text fields. To find text anywhere within text fields, add an asterisk at either end of the string eg "FIND("*JONES*")".
When you use REM at the end of a line you need only precede it with a space, not a space and a colon. So these two lines are equivalent:
RAISE -37 :REM disk full
RAISE -37 REM disk full
No calculator memories are available to OPL on the MC (although they are on the Series 3/3a.)
The specification of the BEEP command has changed.
Different effects are produced by values below 32, used with "PRINT CHR$()". See the Character Set appendix for more details.
New functions and commands:
A new variable type has been added long integers, specified by adding an "&" symbol to the variable name instead of the "%" symbol, eg "price&", "x&(5)".
Long integers are 32-bit rather than 16-bit signed integers, giving the range +2,147,483,647 to -2,147,483,648 rather than +32767 to -32768.
Long hexadecimal constants should have an "&" instead of a "$" sign in front of them. Even when the constant fits into an integer, you can use "&" to widen the constant to 32 bits.
POKEL, POKEF and POKE$ have been added to POKEB and POKEW, and PEEKL, PEEKF and PEEK$ have been added to PEEKB and PEEKW. This means you can poke and peek the full range of value types strings, long integers etc.
There is a range of I/O file handling facilities, allowing you to open, read, write and position within any type of file.
To complement the keypress functions, KMOD allows you to detect any modifiers, such as Control, which have been pressed.
Many graphics commands are available. They can, for example:
The CURSOR command can be still be used to switch the text cursor on and off, but can also define the shape and position of a graphics cursor.
The gUPDATE command affects anything that displays on the screen. It may make a noticeable difference in speed if, for example, you are using a lot of PRINT commands.
When a program runs, it is given the full screen on which to display text. Use the SCREEN command to define a different window size for text display.
The SCREEN command can position the text window anywhere on the screen. You can also use SCREEN repeatedly to change the size of the window.
A new function, OS, allows you to call any interrupt service in the Operating System, and read all returned registers and flags.
GETEVENT and TESTEVENT give details of system events of any kind.
Many of the interface features of the Series 3 applications for example menus, dialog boxes, shadowed boxes and status windows are available via OPL keywords.
Several keywords have been added for OPAs (OPL applications).
The two colons at the end of the label in ONERR or GOTO are optional. The colons must still be used where the label itself occurs in the program.
You can pause a running program by pressing Control-S. It will be paused as soon as it next tries to display something on the screen. Press any other key to let the program resume running.
The EVAL function evaluates a string and returns the result as a floating-point number.
The VECTOR command allows you to jump to one of a list of labels. This can save cumbersome IF statements.
Procedures may now be called using a string expression for the procedure name.
BEEP may be used with the duration made negative. It will first check whether the sound system is in use (perhaps by another OPL program), and return if it is. This stops BEEP waiting until the sound system is free.
There are new graphics keywords gINVERT, gXPRINT, gBORDER and gCLOCK.
DATETOSECS and SECSTODATE convert between standard system dates / times and the number of seconds since midnight on 1/1/1970.
The calculator memories M0 to M9 are available to OPL.
MKDIR makes a new directory, RMDIR removes a directory, and SETPATH sets the current directory for file access.
The command line arguments of the OPL program you run, including its full pathname, are returned by CMD$.
Two new I/O commands, IOWAITSTAT and IOYIELD, have been added.
PARSE$ will produce a single full file specification from two separate parts, or break one down into its constituent parts.
A new SCREENINFO command provides information about the screen size and type. You can use it to write machine-independent programs, as described later in this chapter.
All appropriate graphics keywords can now draw in grey as well as black. To allow drawing in grey use "DEFAULTWIN 1". By default grey is not available as drawing grey as well as black uses more memory and takes longer.
TYPE supports new larger black/grey icons, and allows you to specify different icons for the Series 3 and Series 3a.
New FONT and STYLE keywords set the font and style for displaying text with PRINT (etc).
gFONT and FONT can access many new fonts which are built into the Series 3a ROM.
gCLOCK supports many more types of clocks.
A dialog on the Series 3 can have up to seven lines including the title, whereas a dialog on the Series 3a can have nine.
A menu on the Series 3 can have up to six options whereas a menu on the Series 3a can have eight. The MENU function allows you to set which menu and item should be highlighted initially.
Series 3 programs will always run correctly in compatibility mode but if retranslated (in normal Series 3a mode) may need changing as follows:
STATWININFO returns information about the sizes of status windows and/or the current status window.
gBUTTON draws keys such as those displayed in certain dialogs.
gDRAWOBJECT draws a graphics object. You can use this to draw the "lozenge" used to display the words `City' and `Home' in the World application.
gXBORDER draws bordered boxes, such as those used to display dialogs. (The gBORDER keyword works as it did on the Series 3.)
FINDFIELD finds text in a particular field, or group of fields.
BEEP cannot play tones as high as those played on the Series 3.
gPEEKLINE can now read from the screen as a whole.
CURSOR can display new kinds of cursors, and gINFO can return this (and other) information.
TYPE supports new actions and icon types for OPAs.
IOC performs an asynchronous I/O request, like IOA, but with guaranteed completion. IOCANCEL cancels any outstanding IOA or IOC.
A new set of keywords supports the definition of a sprite, which you can move around "on top of" the rest of the screen. The sprite can be animated, displaying a sequence of different bitmaps.
Cacheing keeping frequently used procedures in memory instead of loading them from file every time they are called can help increase the speed of OPL programs.
New keywords provide access to dynamic libraries (DYLs), to the memory allocator and to Operating System data file calls.
UADD and USUB allow addition and subtraction of pointers/addresses without the risk of `Integer overflow'.
GETEVENT now returns the event $405 when the date changes.
Compatibility between Series 3 and Series 3a
A program translated for the Series 3 can run on the Series 3a without retranslation the program runs in compatibility mode. This mode makes use of the fact that the Series 3a screen has exactly twice as many pixels as the Series 3 screen in both the horizontal and vertical directions: the Series 3a screen has 480x160 pixels and the Series 3 has 240x80 pixels. When a Series 3 program runs on the Series 3a, four pixels (2x2) are actually drawn or cleared for each pixel that would have been drawn or cleared on a Series 3. Also, all keywords that explicitly or implicitly specify a screen position (eg. gAT, gMOVE, gBOX and AT) are automatically rescaled.
One or two of the special symbols (characters between 0 and 31 in the character set) are different on the Series 3a. However, in compatibility mode the fonts have the same character set as on the Series 3.
A program translated for the Series 3a runs in normal mode on the Series 3a. It will not run on the Series 3.
If you wish to slow down a program such as one of the games on Psion's Games SSDs you can write a short OPL program to run in the background, like this:
proc slowdn: local i%,j print "Slow down S3a" call($138b) rem "unmark as active" while 1 i%=10 :j=j+1 while i% :i%=i%-1 :endwh if j=300000 j=0 :pause 2 else pause 1 endif endwh endp
If you change the number 10 assigned to "i%" at the top of the WHILE loop, you can control the amount by which the Series 3a slows down a bigger value slows it down by more, and a smaller value by less. You may need to use different values for different Series 3 programs.
Warning: running this program will cause the Series 3a to use more battery power.
The loop which "j" counts is designed to do a "pause 2" instead of a "pause 1", roughly every twenty five minutes. A "pause 2" gives just enough delay for the automatic turn off of the Series 3a to have a chance to work. Without this, automatic turn off cannot work.
Do not forget to exit the program from the System screen (use the Delete key) when you want to use the Series 3a at full speed again.
The rest of this section relies on the following important rules:
For this method to work you should not assume that the physical screen has a fixed number of pixels or that the text screen size and characters in its font have a fixed width and height. Use gINFO, SCREENINFO, gWIDTH and gHEIGHT to find out the values at runtime. eg. pixel "(120,0)" is half-way across the screen on the Series 3 but is only a quarter-way across on the Series 3a, whereas pixel "(gWIDTH/2,0)" is half-way across in both cases.
Clearly Series 3a keywords cannot be included in any program to be run on both machines. The following 'trick' may however prove useful. It relies on the failure to load an Series 3a module when running in compatiblitiy mode on the Series 3a (or when running on the Series 3 itself). The steps are:
1. Create a module containing procedures using Series 3a keywords which are needed when running in normal mode. For example, module "s3aprocs.opl" might contain:
PROC scrinfo:(pinfo%) SCREENINFO #pinfo% ENDP
PROC font:(font%,style%) FONT font%,style% ENDP
2. Translate for the Series 3a (it won't translate for the Series 3 anyway).
3. Call the procedures in "s3aprocs.opl" as follows to set up global variables containing text screen information if running in compatibility mode, simply set the globals to known values that apply on the Series 3:
LOCAL err%,info%(10),...This example assumes that the default font has not been changed using the "IOW(-2,7,17,...)" function (as described in the Series 3 Programming manual) when running on the Series 3 or in compatibility mode on the Series 3a. In normal mode on the Series 3a, you must use the FONT command instead.
TRAP LOADM "S3aprocs" IF ERR=0 OR ERR=-104 rem if not 'Incompatible translator' error rem or if already loaded, then in normal mode err%=ERR font%=$9a rem system font font:(font%,16) rem mono-ised style scrInfo:(ADDR(info%)) marginX%=info%(1) rem pixels from left of screen marginY%=info%(2) rem pixels from top of screen chrW%=info%(7) rem character width in pixels chrH%=info%(8) rem character height in pixels screenX%=gWIDTH/chrW% rem char screen width screenY%=(gHEIGHT+1)/chrH% rem char screen height IF err%-104 rem if loaded here UNLOADM "S3aprocs" ENDIF ELSE rem else on Series 3 or rem in compatibility mode rem so just use fixed values marginX%=0 rem no margins on Series 3 marginY%=0 chrW%=6 rem default console char width chrH%=9 rem ...and height screenX%=40 rem character columns screenY%=9 rem character rows font%=1 rem font ID = 1 on Series 3 ENDIF