The Psion Documentation Project

Welcome to the Psion Documentation Project

Take a look at the Books to get started!

This is the Psion Documentation Project. It is currently very early alpha! There are probably huge mistakes with the documentation you will find here and it's currently not very well organised.

This is where you come in.

Accounts are currently issued on an invite-only basis, but will soon be opened up to the public.

This project is run by the same people as The Last Psion Project, an attempt to reinvigorate passion for Psion's SIBO/EPOC16 platform, as well as develop hardware and software. While The Last Psion's focus is on the 16 bit machines, we want this site to cover all machines with the Psion logo and their clones (Acorn).

Do you have any original Psion source code?

The Last Psion Project is looking for any and all source code used within Psion during the early 90s, including the source for the EPOC16 operating system. We are also looking for internal documentation. Please get in touch!

 

This open source project is sponsored by HostPresto!

Device driver interfaces

This document describes all known functions for all known device drivers. It does not include file IO, even when done through the same interfaces.

The device drivers documented are:

ID Description
SND: Sound device
TIM: Timer device
ALM: Alarm device
WLD: World device
TTY: Serial port device (including IR)
PAR: Parallel port device
FRC: Free running counter
XMD: XModem driver
YMD: YModem driver
WLS: Workabout laser scanner
AIR: AccessIr driver
N/A Console device

Types of device driver

On the Series 3, much functionality, including the filing system, is provided via device drivers. There are three kinds of device drivers:

Only logical device drivers need to know about physical device drivers; all user applications operate through logical device drivers.

For example, the 3-Link pod and cable might be accessed through a physical device driver called TTY.LNK: (all physical device drivers have a two part name). This is automatically loaded the first time that the logical device driver TTY: is opened, and TTY: will use it to actually communicate with the pod.

When TTY: is opened, the kernel will return a handle. Read and write operations on that handle will send data directly to and from the port. Alternatively, the XMD: device driver could be stacked on top of TTY: on that handle. Once this has been done, read and write on that handle will now be done via the XMD: driver, which wraps the data in the XModem protocol and calls the TTY: driver to do the actual output. There is no limit to how many device drivers can be stacked upon one another.

Opening a handle

A base logical device driver is opened with the IOOPEN keyword or the IoOpen system call; a stacked logical device driver is opened with IoOpen. The name is examined to see whether it has a colon as the fourth character but not the fifth; if so, it is split into a device name and a channel name. The kernel then checks that the logical device exists; if not, or if the name does not have the correct form, it prefixes FIL: to the name and tries again (FIL is the filing system logical device driver). For example:

Example Device Channel Name
SND: SND Blank
TTY:A TTY A
FIL:A:XXX FIL A:XXX
HELLO.TXT FIL HELLO.TXT
ROM::XXX FIL ROM::XXX
FIL:TTY: FIL TTY:
QXV: FIL QXV:

The last example assumes there is no QXV device driver

The filing system and the FIL: driver are described in the Psionics file FILEIO. All other known drivers are described here.

IOOPEN and IoOpen are passed a mode to open the device or file. Drivers other than the filing system and those specifically mentioning it ignore the mode. It is recommended that a mode of -1 be used, as this is always rejected by the
filing system; thus an error in the device name or a missing driver will be detected. Note that the IOOPEN keyword uses a qstr, while the IoOpen system call uses a cstr.

A driver may refuse to open a given channel name, or all channels, more than a certain number of times without closing some first. For example, a TTY driver might only allow one open handle at a time for each port.

In OPL there are two special handles that do not need to be opened:

Using the device driver

Once a device driver has been opened, it is accessed with the keywords IOW, IOA, and IOC (Series 3a only). These keywords offer the same services, and differ only in the way completion is indicated.

Each call is passed a function number and two parameters for passing other information. The latter identify blocks of memory; the actual argument can be either the name of an OPL variable (typically the first element of an array),
in which case that variable marks the start of the block, or it can be the # operator applied to the address of the block. The former is equivalent to #ADDR(variable).

If the parameter is shown as "unused", then any variable or value can be used, as it will be ignored; it is often convenient to use #0 as such an argument.

Unless stated otherwise, a successful call returns zero, and an unsuccessful call some non-zero error code.

Standard functions

These functions apply to all drivers.

Function 1 (read) and Function 2 (write)

These functions are equivalent to the IOREAD and IOWRITE keywords. They read or write up to the specified number of bytes from or to the device; in the case of function 1, the count is changed to the actual amount read.

These functions can be used with any handle that is using a driver labelled as a data device (such as the serial port device or the XModem driver).

Function 3

This will close the handle; it is equivalent to the IOCLOSE keyword.

Function 4

This will cancel any uncompleted function on the handle; the function will complete immediately, with the status variable set to -48 ("I/O cancelled"). A signal will still be generated, and must be collected with IOWAITSTAT or IOWAIT.

Sound device (SND:)

The sound device has the name SND:. There are no channel names. Only one handle can be open at a time, and so the device should be closed as soon as possible.

Function 1 (sound channel 1) and Function 2 (sound channel 2)

This function is supported by the HC, MC, and Series 3a only.

This plays a sequence of notes on the specified sound channel. The note information is an array of words, two per note; the first is the frequency of the note (in Hz), and the second the duration in beats (see function 7). The sound will not start until both these functions have been called (thus ensuring the sound is synchronised on both channels). The function completes when the specified channel finishes playing, even if the other has not.

Function 7

The characteristics of the sound system are set according to the block:

The beats per minute is only supported by the HC, MC, and Series 3a. On the Series 3a, volumes 1 and 2 are identical, as are 4 and 5. On the Series 3t, volumes 0 and 5 are unavailable.

Function 8

The block is filled in with information about the sound channel, using the same format as function 7.

Function 9

The specified alarm is played; this function completes when the sound has completely played.

Function 10

This generates DTMF dialling sounds. The number contains the digits to be dialled (0 to 9, *, #, and A to F can be used; E is the same as *, and F the same as #). The parameter block has the format:

Timer device (TIM:)

The timer device has the name TIM:. There are no channel names.

Several channels may be opened at the same time by the same process.

Function 1

This will complete after the specified delay. Time when the machine is switched off is not counted as part of the delay. Changing the system clock will not affect the completion of this function.

Function 2

This will complete at the specified time. If the machine is switched off at that time, it will switch back on. Changing the system clock will affect the completion of this function.

Alarm device (ALM:)

The alarm device has the name ALM:. There are no channel names.

Function 1 (display date only) and Function 2 (display date and time)

This schedules an alarm, which causes a message box to be shown at some later time. The time specification block has the format:

The message (maximum 64 characters) is shown in the message box.

The function completes when the alarm goes off. If the machine is switched off at that time, it will switch back on. Changing the system clock will affect the completion of this function.

Function 10 (display date only) and Function 11 (display date and time)

These functions are supported by the Series 3a only.

This schedules an alarm, which causes a message box to be shown at some later time. The time specification block has the format:

Offset Length Description
0 4 abstime when the alarm should sound
4 4 abstime to be displayed in the message box
8 qstr name of alarm sound

These functions are identical to functions 1 and 2, except that the alarm sound is specified by the call. The sound name may be one of the following:

World device (WLD:)

The world device has the name WLD:. There are no channel names.

This device gives access to the World database. This includes the built-in database and any one world file. If the World application is running, this is the file it currently has open. Otherwise it is the last world file to be open,
or the world file opened with function 21.

World files have a format which varies from version to version of the operating system, and are limited to 32 entries. This is because the file is mapped into kernel address space and accessed directly, rather than being loaded in the usual manner.

Several functions use a "city name block". This is a 42 byte block with the format:

Offset Length Description
0 21

name of a city (cstr)

21 21

name of a country (cstr)

Unless stated otherwise, the country is that in which the city lies.

Many functions establish or use a searching order. This can be set to:

Search order is cyclic: The last city or country is followed by the first.

Function 10

This locates a city whose name begins with the clue (the search is done with folded strings, so "lon" will find London, but "ond" will not). If successful, the city block is filled in with the city, and city order is set.

Function 11

This locates a country whose name begins with the clue (the search is done with folded strings, so "lon" will find London, but "ond" will not). If successful, the city block is filled in with the capital city of the country, and country order is set.

Function 12

This locates either the city whose name is in the city part of the block, or, if the city part is an empty string, the capital city of the country whose name is in the country part of the block (in either case, the string must be exact after folding). If successful, the block is filled in, and city or country order (according to what was searched for) is set.

Function 13 (next city) and Function 14 (previous city)

These functions fill the block with the next (or previous) city in the current search order.

Function 15

This function fills the block with the home city; city order is set.

Function 16

This function sets the home city to the last city returned.

Function 17

This function fills the block with the capital city of the default country; city order is set.

Function 18

This function sets the default country to that of the last city returned.

Function 19

This function generates a diallable number (up to 24 characters) from the original number (up to 128 characters), using the following rules:

For example, abc,123,456xx789 generates "123,456". Assuming that the default country is the UK and the default city is in the USA, abc00-34 56x78 generates "01144003456".

David said that this just generates the dial string

David implied this also does [country]

Function 20

Argument 1 = 0 or 1

Adds or updates the city described by the information block (in the format of function 22) to the open world file.

Argument 1 = 2

The current item is deleted from the open world file if it is in it, not the current home city, and not a capital city of an added country. The function returns 1 if the entry was hiding an entry in the ROM database, and 0
otherwise.

Argument 1 = 3

Adds or updates the country described by the information block (in the format of function 23) to the open world file. All cities in the country will have their GMT offset and DST rule updated to match the data.

Function 21

This function opens, creates, or replaces a world file for use. The modes have the meanings described in the Psionics file FILEIO. If the last returned city is in the database, it is no longer valid (but functions 13, 14, and 25 still
work). The default extension is .WLD.

Function 22

This function fills the buffer with information about the last city returned:

Offset Length Description
0 21 (cstr) city name
21 21

(cstr) country name

43 1 DST rule: 0 = none, 2 = European, 4 = North, 8 = South
44 2 minutes ahead of GMT for city
46 2 city latitude in minutes north (negative means south)
48 2 city longitude in minutes west (negative means east)
50 17 (cstr) dial code from home city
67 9 (cstr) area code of city
76 2 X coordinate of city on map (in pixels)
78 2 Y coordinate of city on map (in pixels)

Function 23

This function fills the buffer with information about the country of the last city returned:

Offset Length Description
0 21 (cstr) city name
21 21 (cstr) country name
43 1 DST rule: 0 = none, 2 = European, 4 = North, 8 = South
44 2 minutes ahead of GMT for capital city
46 5 (cstr) national dialling code
51 5 (cstr) international dialling code
56 5 (cstr) country code

Function 24

This function does a calculation on the contents of the information block. The function should be called with the status set to 1. If it returns successfully, then, as long as the status is non-zero, it should be called again. When the
status is zero, the calculation has completed. Intermediate stages may use extra internal memory, so if you wish to abandon the calculation partway, use function 4 to cancel (this can be done at any time) rather than just stopping.

The initial value of the information block should be:

Offset Length Description
42 1 units (0 = miles, 1 = km, 2 = nautical miles)
43 1 DST rule: 0 = none, 2 = European, 4 = North, 8 = South
44 2 minutes ahead of GMT for city
46 2 point latitude in minutes north (negative means south)
48 2 point longitude in minutes west (negative means east)

The final value of the information block is:

Offset Length Description
0 2 distance in stated units from home city to point
2 2 sunrise time at point in minutes past midnight
4 2 sunset time at point in minutes past midnight
6 2 0 = times valid, 1 = light all day, -1 = dark all day

Function 25

This function returns the next city in the same country as the last city returned (using city order).

Serial port device (data device) (TTY:)

The serial port device has the name TTY:. The channel name is a single letter from A to Z, identifying the particular port to use. Which ports are actually provided depends on the specific system.

On the Series 3t and 3a, the two RS-232 ports are channels A and B. On those machines with an infra-red port, it is channel I.

An open serial port can be read and written with IOREAD and IOWRITE, or with IOW functions 1 and 2.

Function 7

This function sets various characteristics of the serial port. The control block has the format:

Offset Length Description
0 1 transmit baud rate
1 1 receive baud rate
2 1 Framing
3 1 0 = no parity, 1 = even parity, 2 = odd parity
4 1 handshaking
5 1 XON character (usually 17)
6 1 XOFF character (usually 19)
7 1 Flags
8 4 terminating mask

The terminating mask specifies which of the characters with codes 0 to 31 terminate a read. For example, if bits 10 and 13 are set, then a read on the port will terminate after reading a byte with value 10 or 13.

Baud Rates (Offset 0 and 1)
ID Baud rate (bps)
1 50
2 75
3 110
4 134
5 150
6 300
7 600
8 1200
9 1800
10 2000
11 2400
12 3600
13 4800
14 7200
15 9600
16 19200
17 38400
18 57600
19 115200
Framing (Offset 2)
Bit(s) Description
0-3 number of data bits minus 5 (e.g. 3 means 8 bits)
4 0 = 1 stop bit, 1 = 2 stop bits
5 parity bit enabled if set
Handshaking (Offset 4)
Bit(s) Description
0-1 3 = XON handshaking, 0 = no XON handshaking
2 0 = RTS handshaking, 1 = no RTS handshaking @@@@
3 1 = DSR handshaking, 0 = no DSR handshaking

(Any combination of XON, RTS, and DSR can be set at once.)

Flags
Bit Offset 0: Speed Supported (baud)
0 Ignore parity errors

Function 8

This function fills the control block with the current settings (see function 7).

Function 9

This function discards any buffered input and any error state. Any handshaking is set to restart reception.

Function 10

The count is set to the number of bytes buffered and waiting to be read.

Function 11

The first byte of the control block is set to indicate the state of the modem control lines:

Value Description
0 set if CTS active
1 set if DSR active
2 set if DCD active

The second byte specifies the new setting for the DTR line:

Value Description
0 leave unchanged
1 set DTR active
2 set DTR inactive

Function 12

The information block is filled in to indicate which facilities are supported by the port.

Offset Length Description
0 4 Speed Supported (baud)
1 2 Feature Supported
Speed Supported in baud (Offset 0)
Bit Offset 0: Speed Supported (baud)
0 50
1 75
2 110
3

134

4 150
5 300
6 600
7 1200
8 1800
9 2000
10 2400
11 3600
12 4800
13 7200
14 9600
15 19200
16 38400
17 57600
18 115200
Offset 4: Feature Supported
Bit Offset 4: Features Supported
0 supports 5 bits
1 supports 6 bits
2 supports 7 bits
3

supports 8 bits

4 supports 2 stop bits
5 supports even parity
6 supports odd parity
7 supports mark parity
8 supports space parity
9 supports setting DTR
10 supports different transmit and receive baud rates
11 supports soft XON/XOFF characters

Parallel port device (data device) (PAR:)

The parallel port device has the name PAR:. The channel name is a single letter from A to Z, identifying the particular port to use. Which ports are actually provided depends on the specific system. A port will consume power while open.

An open parallel port can be written with IOWRITE, or with IOW function 2.

No other functions are available on the Series 3.

Free running counter (FRC:)

The Free running counter has the name FRC:. There are no channel names. It is only available on the Series 3a. Only one process may have the FRC open at a time, and so it should be closed as soon as possible.

In the following description, an "FRC-tick" is 1/1024 seconds.

Function 1

The current setting of the counter is placed in the word. If the counter is in mode 1, the count is then reset to zero (the counter continues counting). This call will not complete while the counter is zero.

Function 15

Starts the counter from zero. Mode 0 means that the counter will increment every FRC-tick. Mode 1 means that the counter will increment at every N FRC-ticks, where N is the step time. Any uncompleted function on the counter will be completed.

XModem and YModem drivers (data device) (XMD: and YMD:)

The XModem driver has the name XMD: and the YModem driver the name YMD:. There are no channel names. Both are stacked on to another data device.

Once stacked, the driver will use the underlying device to transfer data using the XModem (single transfer) or YModem (multiple transfer) protocol. These protocols have a number of variants:

Function 1 is used to receive data. The initial value of the length argument will be ignored, and a whole frame (128 or 1024) bytes will be placed in the buffer, which must therefore be large enough. When an end-of-file message is received, the function will fail with error -36.

Function 2

Function 2 is used to send data. The length is used as follows:

If the length is any other value, the specified amount of data is transferred, followed by enough 0x1A bytes to fill a frame (a short frame if the length is less than 128, and a long frame otherwise).

With YModem, the first frame must be a short frame with the following contents, in order:

The last field or fields may be omitted, provided that the name is present. The rest of the frame must contain only zero bytes. A frame consisting only of 128 zero bytes indicates that there are no more files.

Function 10

This establishes a connection with the other end of the link. The direction indicates which way the file transfer will take place. The mode is one of the following values:

If long frames are to be rejected while receiving:

XModem:

YModem:

If long frames are to be accepted while receiving:

XModem:

YModem:

With YModem, this function must be called for each file.

Function 11

This disconnects an existing connection while leaving the driver attached. With YModem, this function should not be called between files.

Workabout laser scanner (WLS:D)

The laser scanner has the device name WLS: and channel name D (that is, it is opened as WLS:D). Only one handle can be open at a time. Furthermore, opening the device activates the scanner for 5 seconds, after which it will no longer read and should be closed; it should also be closed after a successful read.

Reading from the device returns a string which is not terminated (the amount of data read gives the length). There are no other IO functions known.

AccessIR device (data device) (AIR:)

The AccessIR device has the name AIR:. There are no channel names. Only one handle can be open at a time, and so the device should be closed as soon as possible.

On the Series 3c, the device is built-in to the kernel and is always available. On the Siena it is provided as a separate file called ACCESSIR.LDD, and is only available once it has been loaded with system call DevLoadLDD.

There is a separate IR protocol stack process. This must be started by executing the program SYS$IRDA.IMG (from ROM:: on the 3c) in the normal way (system calls FilExecute and ProcResume).

Function 4 has the side effect of disconnecting from the remote machine if a connection is established.

Function 5

Waits for a connection from another machine, completing when another machine connects successfully. If the call is successful, the buffer is filled with a cstr containing information from the other machine (up to 56 characters excluding the terminating zero) and the call returns the maximum amount of data that may be sent in a single write.

Function 6

Searches the physical neighbourhood for machines willing to accept an IrDA connection. The second argument is overwritten with the actual number of machines found, and 36 bytes are placed in the buffer for each machine:

Offset Length Description
0 4 Unknown
4 4 machine address
8 4 Unknown
12 23 (cstr) machine nickname (up to 23 characters)

Function 7

The device is initialised ready to connect to the specified machine.

Function 8

Connects to the specified application on the selected machine. If the connection is successful, the buffer is filled with the information passed from the other machine (up to 60 bytes). The application name is limited to 25 characters excluding the terminating zero. If this call is successful, it returns the maximum amount of data that can be sent in a single write.

Console device

This is a special device that does not need to be opened; it has the handle -2.

The console device outputs text in the text area (as set by the SCREEN keyword), and many of its functions duplicate OPL keywords. Up to 255 characters may be written to the device, and the corresponding text will be output. Certain characters have the following meaning:

Character Meaning
7 beep
8 backspace
9 go to next tab stop (multiple of 8 characters)
10 go down one line
11 go down one line
12 go down one screen
13 go to start of the line

If the text will not all fit in the current line, what happens depends on the auto-wrap and scroll lock flags (defined below). If auto wrap is on, moving past the end of the line moves to the beginning of the next line. Otherwise further characters overwrite the last character on the line. If scroll lock is off, moving down from the bottom line (including because of an auto wrap) will scroll the screen up one line. Otherwise moving down from the bottom line has no effect. Writing cannot fail.

Reading from the device ignores the length and always reads exactly 4 bytes, representing a single keystroke:

The autorepeat count indicates how many keystrokes have been combined into one return; it will only be greater than 1 if processing of the keystrokes is not keeping up with the autorepeat.

Function 7

Argument 1 = 0

This alters the text style as specified:

Unsupported styles and those requiring a different character width will be silently ignored. This function cannot fail.

Argument 1 = 1

This scrolls a rectangle (ignoring the scroll lock flag) by any amount according to the control block:

Offset Length Description
0 2 left edge of rectangle (inclusive)
2 2 top edge of rectangle (inclusive)
4 2 right edge of rectangle (exclusive)
6 2 bottom edge of rectangle (exclusive)
8 2 horizontal scroll distance (positive=right, negative=left)
10 2 vertical scroll distance (positive=down, negative=up)

The rectangle will be clipped to the text area. This function cannot fail.

Argument 1 = 2

This clears a rectangular area described by the control block:

Offset Length Description
0 2 left edge of rectangle (inclusive)
2 2 top edge of rectangle (inclusive)
4 2 right edge of rectangle (exclusive)
6 2 bottom edge of rectangle (exclusive)

The rectangle will be clipped to the text area. This function cannot fail.

Argument 1 = 3

The cursor moves to the specified location; if that is outside the text area, it moves to the closest point within. The control block has the format:

Offset Length Description
0 2 x coordinate
2 2 y coordinate

This function cannot fail.

Argument 1 = 4

The cursor moves the specified amount, or to the edge of the text area if that is closer. The control block has the format:

Offset Length Description
0 2 horizontal distance to move (positive=right, negative=left)
2 2 vertical distance to move (positive=down, negative=up)

This function cannot fail.

Argument 1 = 5

Sets the size of the text area according to the control block:

Offset Length Description
0 4 must be zero
4 2 new width
6 2 new height

Argument 1 = 6 or 7

Sets the scroll lock or auto wrap flag. This function cannot fail. The initial state is auto wrap on and scroll lock off.

Argument 1 = 8

Moves the cursor to the start of the next line, obeying the scroll lock flag. This function cannot fail.

Argument 1 = 9

Turns the cursor on or off; this has no effect other than altering the appearance of the cursor on the screen. This function cannot fail.

Argument 1 = 10

Enables or disables exiting via the PSION-ESC key sequence. This function cannot fail.

Argument 1 = 11

Enables or disables buffering of commands. When buffering is in effect, calls to the console are buffered up, and executed only when the buffer is full, a result is required, or on an explicit flush of the buffer. As a side effect, errors will be reported to the function causing the buffer contents to be executed, not the one making the call. This function cannot fail.

Argument 1 = 12

Sets the text area according to the control block:

Offset Length Description
0 2 left edge (inclusive) of the text area
2 2 top edge (inclusive) of the text area
4 2 right edge (exclusive) of the text area
6 2 bottom edge (exclusive) of the text area

Argument 1 = 13 or 14

Sets up or cancels capturing of a key or combination of keys by this process, whether or not it is in the foreground. The cancel must specify an identical control block to the set up. The control block has the format:

Offset Length Description
0 2 keycode
2 1 modifiers that must be pressed (if tested)
3 1 modifiers that are tested

Both modifier values use the bits:

Unused bits must be zero, and a bit must not be set in offset 2 while clear in offset 3.

Argument 1 = 15

Moves the indicated process to the foreground. This call cannot fail.

Argument 1 = 16

Sets the last line wrap flag. This function cannot fail. The initial state of the flag is off. When off, printing to the bottom right corner of the text area causes an immediate wrap and scroll. @???@ @Obeys other flags@

Argument 1 = 17

This sets the font type for the text area, resizing the latter as necessary to handle the new font, and clears the text area. The control word has the format:

Note that the console device uses a fixed character grid; if a proportional font is chosen, bit 4 of the style must be selected, and the characters will be printed on that grid, and not proportionally.

Window server font ids are 0x3FFF greater than the OPL font id @CHECK@. The current system font has id 0x4099 (widget server) or 0x9A (OPL).

Argument 1 = 18

Enables or disables reads from the console. The console may only be read (via functions 1, 14, or the equivalent OPL keywords) when enabled. This function cannot fail.

@@Subs: 19 SET_PRIORITY_CONTROL, 20 COMPATIBILITY, 21 GREY, 22 FONT_EXT ??

Function 8

The position of the text area and the current cursor position (as set by the AT keyword) are written into the buffer.

Offset Length Description
0 2 set to left edge (inclusive) of the text area
2 2 set to top edge (inclusive) of the text area
4 2 set to right edge (exclusive) of the text area
6 2 set to bottom edge (exclusive) of the text area
8 2 set to cursor x coordinate relative to offset 0
10 2 set to cursor y coordinate relative to offset 2

All coordinates are in character positions. 0,0 is the top left corner of the screen; note that the bottom and right edges are outside the text area. This function cannot fail.

Function 9

This function discards any waiting keypresses. It cannot fail.

Function 10

This function tests whether there are any keypresses waiting. It cannot fail.

Function 11

This function allows the user to edit a string on the screen. The control block has the following format:

Offset Length Description
0 1 unused
1 1 non-zero allows escape from editing
2 256 string buffer

The initial value of the string must be placed in the buffer; the resulting string will also be placed there (in both cases it is a cstr). The length of the string, excluding the terminating zero, is limited to the specified maximum. If ESC is pressed with the string currently non-empty, it is cleared. If ESC is pressed with the string empty and escaping is allowed, the function
will fail; otherwise ESC will be ignored in this circumstance.

Function 12

The buffer is filled with information about the text area:

Offset Length Description
0 2 window server id of the console window
2 2 window server id of the console font
4 2 height of a text line in pixels
6 2 width of a text character in pixels

This function cannot fail.

Function 13

If console buffering is in effect, any buffered commands are executed. Otherwise this function has no effect. It cannot fail.

Function 14

This function is equivalent to the GETEVENT keyword. It behaves the same as reading from the device, except that events other than keypresses can be returned; for example, foreground, background, and change file events. Unlike GETEVENT, this function can be called from OPL programs whether or not they are OPA applications.

Function 15

This function is equivalent to the TESTEVENT keyword. It behaves the same as function 10 except that events other than keypresses are also detected. It cannot fail.

Filesystem IO Interfaces

This document is based on FILEIO from The Psionics Files.

This document describes the use of the IO interface for accessing the filing system. For general discussion on IO, see Device Driver Interfaces.

The filing system is a special device driver, called FIL:. Whenever an open fails to locate a device, or if the name opened is not that of a device driver, the driver name FIL: is prefixed, and the open is retried. Thus the original name becomes the channel name. For file IO, the channel name is, or controls, the file name.

An addition filing system called TXT: also exists. This is identical to FIL:, and accesses the same files, except that all files are assumed to be text files (see below). There is no normal need to use TXT:; instead, use FIL: and open files with a format component of 2 (see below).

Filing system organisation

The filing system is divided into one or more nodes. A node has a name ending with a double colon. The nodes most commonly met are:

A node may be monolithic, or may be divided into devices. The devices available and the format of their names depends on the node. For example:

Unless explicitly stated otherwise, the term device includes monolithic nodes. A node may be flat or hierarchical. In the former case, each device is a single directory which contains files. In the latter, each device has a directory hierarchy  starting with a root directory; each directory can hold files and other directories.

The format of file and directory names depends on the node. Various system calls (such as FilChangeDirectory) can be used to manipulate file names. The LOC:: node uses \ as a directory name terminator (the root directory is just called "\") and allows both file and directory names to consist of up to 8 characters, a dot, and then up to 3 characters. The ROM:: node is flat, and uses the same rules for file names.

The full pathname of a file consists of the node, the device (if any), the path of directories (if any), and the filename, all joined with no intervening spaces. It is limited to 128 characters.

The system has the concept of a current path. When any filename does not include a node, device, or directory, that of the current path is used. For example, if the current path is LOC::A:\APP\, then the names XXX\YYY and M:ZZZ actually refer to LOC::A:\APP\XXX\YYY and LOC::M:\APP\ZZZ. However, the default path will only be used for names which are on the same node (either explicitly or because no node is specified).

Opening files

There are two kinds of open: open for scanning, and open for access. These are both done with the IOOPEN keyword, but once the file is open, it is used in totally different ways.

Opening for scanning

A file is opened for scanning by specifying one of the following modes to IOOPEN:

Mode Description
$0030 scan a directory
$0050 scan a node
$0060 scan all nodes
$0040 format a device
$8040 format a device in low density

In each case, once the file is opened, it is scanned or formatted by making several calls to function 1 until one fails with error -36 (end of file).

The IOREAD keyword should be equivalent to function 1. However, there have been reports of problems with using it.

Once a call fails, the handle should be closed. All these calls will ignore the length variable (argument 2).

Scanning generates a list of names. There are three different scans that can be done:

One member of the list is returned, as a cstr, by each call to function 1. The buffer (argument 1) should be at least 128 bytes long.

Formatting is used to prepare a device to contain files and to erase any previous contents. If a device supports multiple densities, it can be formatted at normal or low density. The node and device part of the name identifies the device to format; the remainder, if any, specifies a new volume name for the device (otherwise the previous one is reused).

The first call to function 1 will write a count into the first word of the buffer (argument 1); subsequent calls will ignore the buffer. This first call will not alter the device, and if the handle is closed immediately afterwards, nothing will happen. Otherwise, the count indicates the number of subsequent calls required to format the device. If the handle is closed before that number of calls has been made, the device will be left in an unusable state; it can be recovered by reformatting, but any information normally transferred to a reformatted device, such as the previous volume name or the unique serial number, will be lost.

As an example, when formatting a 2Mb flash SSD, the format count was 513. This consisted of:

Opening for access

A file is opened for access in order to read or write the file. To open a file for access, the mode parameter to IOOPEN has the following value:

Bit(s) Value Description

0-3

(Service Component)

0 open an existing file
1 create a new file
2 replace an existing file
3 open a file for appending only
4 open a new file with a new, arbitrary, name

4-7

(Format component)

0 open a binary file for binary access
1 open a text file for binary access
2 open a text file for text access
8 1 allow writing
9 1 allow random access
10 1 allow shared access

These individual components are now described.

Service component

The service component indicates what to do with the existing contents of the file. There are five possibilities:

Format component

There are two kinds of file: text and binary. A text file consists of a sequence of records, each ending with a newline character, while a binary file consists of arbitrary data, which is not broken into records.

Each node has its own way of storing text and binary files. On some nodes, the two types are completely distinct. On others, text files are merely a way of interpreting binary files. This is the case for the LOC:: and ROM:: nodes. In either case, a record in a text file is limited to 256 bytes, and may not contain $0A, $0D, or $1A.

In the LOC:: and ROM:: nodes, a text file obeys the following rules:

Access Modes

The three access modes are used to determine the way the file is processed.

Mode Description
0 opens a binary file for binary access
1 opens a text file for binary access
2 opens a text file for text access

The meaning of each of these is discussed below, under reading and writing. If a node does not distinguish binary and text files, the contents of the file are treated in the way described above. If it does distinguish them, the open will fail if the file has the wrong type.

Other opening flags

If the "writing" flag is not set on opening, all attempts to alter the file will fail. This includes files created by the open function.

If the "random access" flag is not set on opening, all attempts to set the current position (as opposed to altering it by reading and writing) will fail.

If the "shared" flag is not set on opening, the file is locked, and no other process may open it until this one closes it. If the flag is set, the file is open for sharing; other processes may also open it for sharing, but none of the processes may alter to the file.

Reading and writing

When reading or writing a binary file, the requested data is transferred directly without change. Up to 16k can be read or written with one call. On a read, the length argument is changed to the actual number of bytes read. The data is read from or written at the current position, which is moved to the end of that data.

When reading a text file as binary, the file is treated exactly as if each record were followed by $0D $0A; partial records can be read into the buffer, and the remaining portion will be retained until the next read.

When writing a text file as binary, the following sequences of bytes are taken to mark the end of a record:

Again, in each case the longest applicable sequence is used, and these bytes are not written as part of the record.

In all other respects access to a text file as binary behaves the same as access to a binary file.

When reading a text file as text, exactly one record is read from the file into the buffer; no explicit end-of-record marker is added. If the record is larger than the buffer, the trailing data is ignored and error -43 is returned. The length argument is changed to the number of bytes placed in the buffer. The record is read from the current position, which is moved to the start of the next record. Since text records are limited to 256 bytes, no more than that can ever be read.

When writing a text file as text, the contents of the buffer are written as a single record at the end of the file, no matter what the current position. The current position is moved to the end of the file. Records are limited to 256
bytes, and must not contain $0A, $0D, or $1A.

When writing to a flash SSD, there is one special case: if the write is a single byte, and if every bit of that byte is left unchanged or changes from 1 to 0 [equivalently, if (old AND new) = new], then the byte will be modified in situ. In all other cases, the old data will remain in place, but the file structure will be modified to skip it and point to the new data instead.

Seek

Seeking in a file is done using IOSEEK. It is reported that mode 4 returns the position of the current record (which is the record just read) within a text file (*not* the pointer after the read), and mode 5 allows you to seek to that position.

This has not been verified.

Other IO functions

Function: 9

Any buffered data is written to the file, and the file's modification date is updated if necessary. On the LOC:: node, the only buffering done for binary files is of the modification date of files on flash. Text files are buffered.

Function: 11

If the file is shorter than the specified length, random data is appended to bring it to that length; the current position is unaltered. If it is longer, the file is truncated to that length, and the current position is set to the new end of file.

Format of Flash and ROM SSD cards

Introduction

This document describes information about the structure of existing types of Flash and ROM SSDs. It does not apply to RAM cards as they use FAT16. It does, however, appear to apply to the ROM in the 3-Link pod and the SSD ROM used to ship the Spreadsheet.

The term "erased flash card" is one that was partially formatted, after which the format was stopped, and then reformatted. This causes the contents of the start of the flash card, which is normally preserved by the formatting process (see Psionics file FILEIO) to be lost.

All trip values are offsets from the start of the card. The term "NULL" means the value 0xFFFFFF.

Filesystem Header

Flash and ROM cards always begin with:

Offset Length Description
0 2 0xF1A5 ('Flas')
2 4 unique ID of SSD
6 2 unknown (only ever seen 1)
8 3 unknown (only ever seen 1)
11 3 pointer to the root directory entry
14 8 volume name
22 3 volume extension
25 4 count of times flash card has been formatted, or 0xFFFFFFFF for ROMs
29 (Flash only) 2 size of the card in 256 byte units (i.e. 0x1000 = 1MB)
31 (Flash only) 2 unknown (only ever seen 0xFFFF)
33 (Flash only) or 29 (ROM only) Until \0 Identity String

The unique ID is placed there when the SSD is first created, and is preserved even when the SSD is formatted. There is no obvious pattern to the IDs. Note that different 3-Link pods have different unique IDs.

If the first byte of the volume name is 00, the volume name is not in offsets 14 to 24, but is instead found in a special file record within the root directory.

The identity string is terminated by a zero byte or a 0xFF byte. The identity strings seen to date are:

The first two were seen on flash cards, the third on an erased flash card, and the last on both the 3-Link pod ROM and the spreadsheet SSD ROM.

The rest of the flash card is divided into records (unused portions of the card are full of 0xFF bytes).

The root directory entry is a filing system record. The directory name is ROOT.

File and folder entries

Filesystem records represent entries in directories: other directories, files, and volume names. A filing system record is 31 bytes if it represents a file, and 26 bytes otherwise:

Offset Length Description
0 3 Pointer to the next entry in same directory
3 8 Entry name
11 3 Entry extension
14 1 Flags
15 3 Pointer to first entry record
18 3 Pointer to alternate record
21 1 Entry properties
22 2 Time code
24 2 Date code
26 (File only) 3 Pointer to start of first data record
29 (File only) 2 Length of first data record

Flags and Properties

The flags are as follows:

Bit 0 1
0 entry deleted entry still valid
1   properties, time, and date valid
2 directory file or volume name
3   no entry record (so NULL at offset 15)
4   no alternate record (so NULL at offset 18)
5   no more entries in same directory (so NULL at offset 0)
6 all entries seen so far have this bit set to 1
7 all entries seen so far have this bit set to 1

The first entry record is:

If the alternate record exists, then most of the data in the record pointing to the alternate record should be ignored, and replaced by the corresponding data in the alternate record. The alternate record is:

The entry properties are:

Bit 1
0 Read-only
1 Hidden
2 System
3 Is a volume name
4 Is a directory
5 Modified

Time and Date Codes

The time code is: 0x800 * hour + 0x20 * minute + second / 2

The date code is: 0x200 * (year - 1980) + 0x20 * month + date

File Records

A file is represented by a linked list of records. The first record is the filing system record, or its alternate, and the remaining records are all continuation records. A continuation record is 17 bytes:

Offset Length Description
0 1 Flags (as above)
1 3 pointer to next continuation record
4 3 pointer to alternate continuation record
7 3 pointer to data record
10 2 length of data record, or 0xFFFF if it is unknown and the file is still open
12 1 entry properties
13 2 Time code
15 2 Date code

Note that bits 5, 2, and 0 of the flags will always be set, and that bits 4 and 3 refer to offsets 1 and 4 respectively. In addition, it is possible for bit 3 to be clear but for there to be no next continuation record.

To examine all the data in a file, start at the filing system record, and then proceed as follows for each record in turn:

If flag bit 4 is set, go to the alternate record and repeat this step. Otherwise the next part of the file is given by the data pointer and length within this record.

After using the data: if flag bit 3 is clear and the next continuation record pointer is not null, go to that record, starting by examining flag bit 4. Otherwise the end of file has been reached.

As files are modified, the records on the flash card become out of date. For example, data that has been overwritten will remain on the card. In particular, the properties, time, and date bytes of records will remain even when they are not valid (as indicated by flag bit 1). Also note that a change to a file may cause several continuation records to be written at the same time. In these circumstances, only one of these will have the correct properties, time, and date, and the others will be written without them, and with some other record overlapping these 5 bytes.

Reading flash cards

On later versions of EPOC16, flash cards can be read with FilLocReadPDD (see Psionics file SYSCALLS). If this is not available, the following code can be used to read flash cards. The left four columns give individual bytes; the right column is the bytes reorganised as long words.

EB 3A 55 E8 E8553AEB
95 00 83 EC EC830095
0E 8B F4 8D 8DF48B0E
7E 28 BA 21 21BA287E
DD 2B DB B4 B4DB2BDD
0A CD 85 83 8385CD0A
C4 0E 8B D8 D88B0EC4
B4 02 CD 85 85CD02B4
89 46 00 89 89004689
5E 02 CD 8F 8FCD025E
8C 46 32 B4 B432468C
00 CD 88 80 8088CD00
E4 0F 89 46 46890FE4
30 9C FA 1E 1EFA9C30
07 9D 5D CB CB5D9D07
83 FB 04 72 7204FB83
05 B8 FC FF FFFCB805
EB 51 8B F0 F08B51EB
55 E8 4F 00 004FE855
88 5E 20 FF FF205E88
36 12 00 8D 8D001236
46 04 A3 12 12A30446
00 FF 36 20 2036FF00
00 80 26 20 20268000
00 00 E4 14 14E40000
C4 7E 30 26 26307EC4
FE 45 0D 1E 1E0D45FE
07 8B FA B0 B0FA8B07
00 FF 5E 00 005EFF00
98 8B D8 C4 C4D88B98
7E 30 26 FE FE26307E
4D 0D 9C FA FA9C0D4D
1E 07 9D 8F 8F9D071E
06 20 00 80 80002006
3E 20 00 00 0000203E
74 02 E6 14 14E60274
8B C3 8F 06 068FC38B
12 00 5D CB CB5D0012
58 FF E0 E8 E8E0FF58
FA FF 05 06 0605FFFA
00 8B E8 C3 C3E88B00
00 00 00 00 00000000
00 00 00 00 00000000
00 00 00 00 00000000
00 00 00 00 00000000
00 00 00 00 00000000
00 00 00 00 00000000
00 00 00 00 00000000
00 00 00 00 00000000
00 00 00 00 00000000
00 00 00 00 00000000
4C 4F 43 2E 2E434F4C
54 59 31 00 00315954
00 00 00 00 00000000

If this code is placed at location bin%, then to initialise the code, call:

USR (bin% + 2, 0, 0, 0, 0)

Then, to copy date from the flash card:

rc% = USR (bin%, ADDR (loc&), drive%, length%, ADDR (buffer))

copies length% bytes into the buffer, starting from address loc& on card drive% (0 is A:, 1 is B:, 2 is C:, etc.). A returned value of 0 indicates success.

EPOC16 Kernel memory organisation

This document is incomplete. Questionable sections are marked with an at (@) symbol.

Kernel memory can be examined with the system call GenGetOsData, or in blocks of assembler with the system call GenDataSegment. Some useful information is available at known offsets. In addition, a handle is actually the offset, in kernel memory, of the start of a data structure, which can therefore also be examined.

Constant offsets

Offset Length Description
1036 2 number of seconds before auto power-off
1052 2 increments every 1/32 second, but is not synchronised to the real time clock (it drifts)
1056 2 delay in 1/32 seconds until current time next changes
1058 4 current abstime

Data structures

The bottom 12 bits of a process ID are actually the address of the process's control block. This has the following format:

Offset Length Description
0 2 pointer to next process in the same queue
2 2 pointer to previous process in the same queue
4 2 @@ queKey
6 2 @@ queData
8 1 @@ deltaType
9 1 @@ addressTrap
10 1 Process status
11 1 non-zero if the process is to be suspended
12 1 @@ priority
13 1 @@ priorityH
14 1 zero if executing ROM code, non-zero if executing RAM code
15 1 zero for processes, non-zero for sub-tasks
16 14 process name
29 1 zero if non-active, non-zero if active
30 2 handle of the semaphore of the process
32 2 @@ *semHead
34 2 address of the start of the heap
36 2 amount to grow heap by, in 16 byte units
38 2 address of the message control block (0 if none set up)
40 2 minimum heap size, in 16 byte units
42 2 file server's handle for the process (0 if not using files)
44 2 handle of the process's data segment (used for DS and SS)
46 2 handle of the process's code segment (used for CS)
48 2 @@ *saveSP
50 2 @@ *saveBP
52 1 0 = unattended, 1 = notify
53 1 non-zero if waiting for the sound semaphore
54 2 top 4 bits of the process ID @@ in which bits ?
56 2 checksum of code
58 2 ProcOnTerminate message type
Process Status (Offset 10)

One queue (offsets 0 and 2) is maintained for ready processes, in priority order, one for processes waiting for a timer, in timer order, and one for each semaphore.

The checksum (offset 56) is used to determine whether two programs of the same name are running the same code, which can then be shared between them.

The battery status data structure has an address returned by the system call HwGetBatData. It has the following format: @@@@

Offset Length Description
0 1 main battery level
1 1 main battery status
2 1 backup battery level
3 1 mains power status
4 2 warning flags
6 ???? insertion date
@ @ ticks in use battery
@ @ ticks in use mains power
@ @ milliamp-ticks

 

EPOC16 System Calls

Introduction

The Psion System 3 operating system offers a large number of system calls.

A system call is identified by either a "function number" or by a "function number and a "subfunction number". These are abbreviated to "Fn" and "Sub" in the descriptions of system calls.

Each call can take up to 5 word parameters, called BX, CX, DX, SI, and DI. In addition, there may be up to two byte parameters (AH and AL) or an additional word parameter (AX). The values returned from the call have the same structure; in addition, there is an error flag and three result flags (the latter are only used by a few system calls). Note that AX is equivalent to AH * 256 + AL; the description will use whichever is most convenient.

There are two OPL keywords for making system calls: CALL and OS. They access the same system calls, and differ only in the way in which the parameters are passed and the results returned.

The CALL keyword takes from 1 to 6 arguments. If an argument is omitted, the corresponding parameter is set to an undefined value. The first argument should be one of:

Fn
Fn + 256 * Sub
Fn + 256 * AH

according to the specific system call. The remaining arguments provide the word parameters:

The keyword returns a value, which is one of the results:

AX
AH * 256 + AL

(which are equivalent). The flags and the other 5 results are not available.

OS takes two or three arguments; if there is no third, it is taken to be identical to the second. The first argument is Fn, while the second and third are each the address of a 12 byte buffer, holding the parameters and results
respectively:

Offset 0 (word): one of:
Sub * 256 + AL (parameters only)
AX (parameters and results)
AH * 256 + AL (parameters and results)
Offset 2 (word): BX
Offset 4 (word): CX
Offset 6 (word): DX
Offset 8 (word): SI
Offset 10 (word): DI

The keyword returns a value which represents the error or result flags. Each flag is held in a specific bit of the value; the remaining bits are unspecified:

Bit 0: UL flag or error flag (depending on context)
Bit 6: EQ flag
Bit 7: SL flag

Thus, if the call can fail, it has failed if the returned value is odd.

When a parameter or result is described as a cstr, a qstr, a buffer, or any other construct requiring more than 2 bytes, the actual parameter or result is the address of the construct.

When a register holds an address (for the above reason or otherwise), it is relative to some segment register. If programming entirely in OPL, all the relevant segment registers (DS, SS, and ES) are the same. However, if assembler is being used, it is sometimes useful to have ES different from the others (see the Psionics file PROCESS for more details). A prefix of "e" to a register name (such as "eBX") means that the address is relative to ES. Unprefixed names are relative to DS or SS (which should be the same). A prefix of "u" means that the segment register is unknown.

The system calls are described in a standard form. The first line gives the following information:

The second line gives the following:

This is then followed by a list of the parameters and results used by the call; any parameter not listed is ignored. For the 5 main word results, the result (if the call does not fail) is the same as the corresponding parameter (including when the former is ignored) unless a different meaning is shown following an arrow (->). For the results AH, AL, and AX, and also the result flags, the result is unspecified if no such description is given.

For example, consider the following (non-existent) system call:

Fn $12 Sub $34
GetMagicCookie fails
AX: -> magic cookie table entry zero
BX: table entry number
CX: -> magic cookie entry
SI: addend -> CX out + SI in
Returns entries from the magic cookie table.

This system call could be used either by:

entry0% = CALL ($3412, entry%, 0, 0, addend%)

which only returns magic cookie table entry zero, or by:

LOCAL regs%(6)
regs%(1)=$3400
regs%(2)=entryno%
regs%(5)=addend%
failed%=1 AND OS ($12, ADDR(regs%()))
REM regs%(2,4,6) have not changed
IF NOT failed
	entry0%=regs%(1)
	entry%=regs%(3)
	REM regs%(5) will equal entry%+addend%
ELSE
	REM regs%(1,3,5) are undefined
	error%=regs%(1) and $FF00
ENDIF

which returns much more information.

System calls

Note that some system calls are deliberately not described.

Function 0x80

Sub-function 0x00: SegFreeMemory

AX: -> free memory

Returns the amount of free system memory, in units of 16 bytes.

Sub-function 0x01: SegCreate fails

AL: segment type: ordinary processes should use 1.
AX: -> segment handle
eBX: (cstr) name of the segment
CX: segment size in units of 16 bytes

Creates an additional memory segment. Each segment must be given a name, of the form "8.3" (i.e. up to 8 characters, optionally followed by a dot and up to 3 more characters). If the name is already in use, the call will fail. Once created, the segment may be used by the process as additional memory, either via SegCopyFrom and SegCopyTo, or in assembler code (see the Psionics file KERNEL).

Sub-function 0x02: SegDelete fails

eBX: segment handle

Deletes an additional memory segment. If any other process has opened the segment, the call will fail.

Sub-function 0x03: SegOpen fails

AX: -> segment handle
eBX: (cstr) name of the segment

Opens the additional memory segment with the given name (if no such segment exists, the call will fail). The call will fail if the process has the segment open already. Except where stated, all calls using additional memory segments must be given handles from SegCreate or SegOpen calls.

Sub-function 0x04: SegClose fails

BX: segment handle
Closes an additional memory segment which the process has open. If this was the only process with the segment open, it is deleted. Open segments are closed when a process terminates.

Sub-function 0x05: SegSize

AX: -> segment size
BX: segment handle

Returns the size of an additional memory segment in units of 16 bytes.

Sub-function 0x06: SegAdjustSize fails

BX: segment handle
CX: new size in units of 6 bytes

Changes the size of an additional memory segment. The memory will be added to or removed from the end of the segment.

Sub-function 0x07: SegFind fails

AX: -> segment handle
BX: last segment handle
SI: address of 14 byte buffer used by the call
eDI: (cstr) pattern to search for

Finds the additional memory segments with names matching the search pattern (use ? and * as wild cards). The first call should be made with the last segment handle set to 0, and subsequent calls should set it to the handle returned by the previous call. The call fails when there are no more segments to return. It is not necessary to keep calling SegFind until this happens.

Sub-function 0x08: SegCopyTo

BX: segment handle
CX: number of bytes to copy
DX: high half of start address in segment
SI: address in process of first byte to copy
DI: low half of start address in segment

Copies data from the current process to an additional memory segment.

Sub-function 0x09: SegCopyFrom

BX: segment handle
CX: number of bytes to copy
DX: high half of start address in segment
SI: address in process to copy first byte to
DI: low half of start address in segment

Copies data from an additional memory segment to the current process.

Sub-function 0x0A: SegLock

BX: segment handle

Locks an additional memory segment; a locked segment will not be deleted even if no processes have it open.

Sub-function 0x0B: SegUnLock

BX: segment handle

Unlocks an additional memory segment. The number of unlock calls should equal the number of lock calls; additional unlocks may cause the segment to be deleted while still open.

Sub-function 0x0C: SegRamDiskUsed

AX: -> size of the ram disc in units of 16 bytes

Returns the size of the ram disc; this should be treated carefully, as it can change without warning.

Sub-function 0x0D: SegCloseLockedOrDevice

BX: segment handle

Unlocks an additional memory segment where the handle may be that for a different process. See SegUnLock for more details.

Function 0x81

Sub-function 0x00: HeapAllocateCell fails

AX: -> allocated block
CX: number of bytes to allocate

Allocates a block of memory from the heap. The returned block may be larger than requested. Heap memory is part of the process's normal memory segment.

Sub-function 0x01: HeapReAllocateCell fails

AX: -> new address of block
BX: block to be reallocated, or zero
CX: new size of block in bytes

Changes the size of a heap block; the block may have to be moved to do this. The memory will be added or deleted to the end of the block. If the call fails, the block is unaffected. If BX is zero, then a new cell is allocated. The new block may be larger than requested.

Sub-function 0x02: HeapAdjustCellSize fails

AX: -> new address of block
BX: block to be adjusted (must not be zero)
CX: number of bytes to add or remove
DX: location within block of the change

Changes the size of a heap block; the block may have to be moved to do this. If the call fails, the block is unaffected. The memory will be added or removed at the offset given by DX. For example, if the block was 10 bytes long, CX is 3, and DX is 6, the new block will be 13 bytes, and consist of the first 6 bytes of the old block, then 3 random bytes, then the last 4 bytes of the old block. The new block may be larger than requested.

Sub-function 0x03: HeapFreeCell

BX: block to free

Frees a previously allocated heap block.

Fn $81 Sub $04: HeapCellSize

AX: -> cell size in bytes
BX: address of block

Returns the actual size of a heap block (which may be larger than requested when the block was created or last resized).

Sub-function 0x05: HeapSetGranularity

BX: new granularity in units of 16 bytes

When the application data space is not large enough to satisfy a heap request, it is grown by the granularity. The default is 2kb (128 units), and the maximum is 16k (1024 units).

Sub-function 0x06: HeapFreeMemory

AX: -> maximum possible free space on heap
BX: -> address of start of heap

Returns the amount of heap space which can be allocated (by using freed blocks or by growing the data space, or both), plus the address of the base of the heap.

Function 0x82

Sub-function 0x00: SemCreate fails

AX: -> semaphore handle
BX: initial value of semaphore

Creates a new semaphore for process interlocking. Each semaphore has a list of processes associated with it (this list is initially empty) and a value, which must initially be zero or positive.

Sub-function 0x01: SemDelete

BX: semaphore handle

Deletes a semaphore. Any processes on the semaphore's list will be restarted. When a process terminates, any semaphore it created will be deleted.

Sub-function 0x02: SemWait

BX: semaphore handle

If the value of the semaphore is positive or zero, one is subtracted from it. If the value is now or initially -1, the current process is then blocked and added to the end of the list for that semaphore.

Sub-function 0x03: SemSignalOnce

BX: semaphore handle

If the list for the semaphore is not empty, the first process on the list is removed and restarted. If the list is empty (either initially or after the only process is removed), one is added to the value of the semaphore. If the restarted process has a higher priority than the current one, a reschedule will take place and the other process will start running (see the description of priorities in the Psionics file PROCESS).

Sub-function 0x04: SemSignalMany

BX: semaphore handle
CX: number of calls to make (must be positive)

This is equivalent to making several calls to SemSignalOnce.

Sub-function 0x05: SemSignalOnceNoReSched

BX: semaphore handle

This is identical to SemSignalOnce except that a reschedule never takes place because of the call (though one may take place due to the current process using up its time slot).

Function 0x83

Sub-function 0x00: MessInit fails

BX: number of message slots + 256 * maximum data length

Initialize the message system so that the current process can receive inter-process messages. The call reserves the indicated number of message slots, with each slot having room for the indicated amount of data. The slots are allocated on the heap.

Sub-function 0x01: MessReceiveAsynchronous async

BX: address of message slot pointer
DI: address of the status word

When a message arrives, the message slot pointer is set to the address of the message, the status word is set to zero, and the call completes. The message has the format:

Offset 0 to 3: used by the message system
Offset 4 (word): message type
Offset 6 (word): process sending the message
Offset 8 onward: data in message

Sub-function 0x02: MessReceiveWithWait

BX: address of message slot pointer

When a message arrives (this may have happened before the call; otherwise the call waits until a message arrives), the message slot pointer is set to the address of the message. The message format is as for MessReceiveAsynchronous.

Sub-function 0x03: MessReceiveCancel

Cancel any pending MessReceiveAsynchronous.

Sub-function 0x04: MessSend fails

BX: process to receive the message
CX: message type
SI: address of first byte of message data

Send a message to a process. The call will block until there is a free message slot in the receiving process. The receiving process determines the amount of data sent. The reply is ignored.

If the sender has priority 128 or above, the message is placed at the front of the queue of messages waiting for the recipient (if it is not already waiting for a message). Otherwise it is placed at the back of the queue.


Sub-function 0x05: MessSendReceiveAsynchronous fails async

BX: process to receive the message
CX: message type
SI: address of first byte of message data
DI: address of the status word

Send a message to a process; when the recipient replies, the status word is set to the reply and the process is sent an IOSIGNAL. The call will block until there is a free message slot in the receiving process.

Sub-function 0x06: MessSendReceiveWithWait fails

AX: -> reply
BX: process to receive the message
CX: message type
SI: address of first byte of message data

Send a message to a process, and blocks until the recipient replies.

Sub-function 0x07: MessFree

BX: address of received message
CX: reply

The reply is sent to the recipient of the message, and the message slot is freed and can be used for another incoming message.


Sub-function 0x08: MessSignal fails

BX: process to watch
CX: message type

Requests that, when the specified process terminates, the kernel sends a message of the indicated type to the current process. The data in the message has the format:

Offset 0 (word): process id of terminating process
Offset 2 (byte): reason code (see ProcKill) or panic code
Offset 3 (byte):

0 = process terminated or was killed
1 = process caused a panic
2 = a subtask of the process caused a panic in the process

If the message slots do not have room for 4 bytes of data, not all this information is available.

Sub-function 0x09: MessSignalCancel fails
Sub-function 0x0A: MessSignalCancelX fails

BX: process to watch
CX: message type (MessSignalCancelX only)

Cancels a call to MessSignal for the indicated process. MessSignalCancel ignores the message type and should not be used if more than one MessSignal call has been made for the process.

Function 0x84

Used to control dynamic libraries and is not described here.

Function 0x85


Fn $85 Sub $00
IoOpen fails
AX: -> handle of opened device
eBX: (cstr) name of device driver
CX: mode
DX: handle of device being attached to
Opens a channel to a device driver. If the driver is a base driver, then
DX is ignored (and this call is equivalent to the IOOPEN keyword). If it is
a stacked driver (see the Psionics file DEVICES), then the handle to be
stacked on must be specified. The meaning of the mode is determined by the
device. A driver can support several channels at once, and each has its own
handle. The driver must be a logical device driver.


Fn $85 Sub $01 and $02 involve physical device drivers and should only be
called from within logical device drivers.


Fn $85 Sub $03 to $05 should only be used by the operating system.


Fn $85 Sub $06
DevLoadLDD fails
Fn $85 Sub $07
DevLoadPDD fails
eBX: (cstr) name of file holding the driver
Loads a device driver into the system. A driver cannot be opened until it is
loaded. The correct call for the driver type must be used.


Fn $85 Sub $08
DevDelete fails
eBX: (cstr) name of the device driver
DX: $DD01 for logical device drivers, or $DD21 for physical device drivers
Unloads a device driver from the system. Open drivers and those in the ROM
cannot be unloaded.


Fn $85 Sub $09
DevQueryUnits fails
AX: -> number of channels supported
eBX: (cstr) name of the device driver, without a trailing colon
Returns the number of simultaneous open channels supported by a driver (which
must be a logical one); $FFFF indicates no limit.


Fn $85 Sub $0A
DevFind fails
AX: -> find code
BX: last find code
DX: $DD01 for logical device drivers, or $DD21 for physical device drivers
SI: address of 14 byte buffer
eDI: (cstr) pattern to search for
Finds all devices with names matching the search pattern (use ? and * as wild
cards). The first call should be made with the last find code set to 0, and
subsequent calls should set it to the code returned by the previous call. The
call fails when there are no more drivers to return. It is not necessary to
keep calling DevFind until this happens. The names do not have a trailing
colon.


Fn $85 Sub $0B should only be used by the operating system.


Fn $85 Sub $0C is used for special operations on device drivers.

Function 0x86

Fn $86 Sub $00
IoAsynchronous fails async
Fn $86 Sub $01
IoAsynchronousNoError async
Fn $86 Sub $02
IoWithWait fails
AL: service number
AX: -> result from driver
BX: handle of driver
CX: address of first argument
DX: address of second argument
DI: address of the status word (ignored by IoWithWait)
These calls are equivalent to the IOA, IOC, and IOW keywords respectively
[For those without documentation of IOC, this is the same as IOA, except that
errors are handled by setting the status word and calling IOSIGNAL, so that
IOC always succeeds, unlike IOA.]


Fn $86 Sub $03 and $04 should only be used by device drivers.


Fn $86 Sub $05
IoWaitForSignal
This call is equivalent to the IOWAIT keyword.


Fn $86 Sub $06
IoWaitForStatus
DI: address of the status word
This call is equivalent to the IOWAIT keyword.


Fn $86 Sub $07
IoYield
DI: address of the status word
This call is equivalent to the IOYIELD keyword.


Fn $86 Sub $08
IoSignal
Sends an IOSIGNAL to the current process. This call is equivalent to the
IOSIGNAL keyword.


Fn $86 Sub $09
IoSignalByPid fails
Fn $86 Sub $0A
IoSignalByPidNoReSched fails
BX: process ID
Sends an IOSIGNAL to a process. With the latter call a reschedule never takes
place because of the call (though one may take place due to the current
process using up its time slot).


Fn $86 Sub $0B to $0F should only be used by device drivers.


Fn $86 Sub $10
IoClose fails
AX: -> result from driver
BX: handle
This call is equivalent to the IOCLOSE keyword.


Fn $86 Sub $11
IoRead fails
Fn $86 Sub $12
IoWrite fails
AX: -> amount actually read or result from driver
BX: handle
CX: address of buffer
DX: number of bytes read or written
These calls are equivalent to the IOREAD and IOWRITE keywords.


Fn $86 Sub $13
IoSeek fails
AX: -> result from driver
BX: handle
CX: mode
DX: address of long holding seek position
This call is equivalent to the IOSEEK keyword.


Fn $86 Sub $14 should only be used by the window manager.


Fn $86 Sub $15 to $17 should only by used from assembler.


Fn $86 Sub $18
IoShiftStates
AL: modifiers
This call makes available the state of the various modifier keys:
Bit 1: shift
Bit 2: control
Bit 3: psion


Fn $86 Sub $19
IoWaitForSignalNoHandler
This call should be used instead of IOSEEK by tasks (subsidiary processes of
a process).


Fn $86 Sub $1A
IoSignalKillAsynchronous fails async
BX: process to watch
DI: address of the status word
This call completes, and the status word is set to 0, when the specified
process terminates.


Fn $86 Sub $1B
IoSignalKillCancel fails
BX: process to watch
Cancel any pending IoSignalKillAsynchronous.


Fn $86 Sub $1C and $1D should only be used by the window manager.


Fn $86 Sub $1E
IoPlaySoundW v3
AL: -> failure code
BX: (cstr) sound file name
CX: duration to play (in 1/32 second)
DX: volume: 0 (loudest) to 5 (softest)
Plays a sound file. A duration of 0 means the file header specifies the
duration; otherwise, the sound is clipped or padded with space as needed.
The name may be either an ordinary filename, or a string of the form "*ABCD",
meaning the first found of the files:
ROM::ABCD.WVE
LOC::M:\WVE\ABCD.WVE
LOC::A:\WVE\ABCD.WVE
LOC::B:\WVE\ABCD.WVE
Note that this call does not fail in the usual way, but just returns a failure
code.


Fn $86 Sub $1F
IoPlaySoundA v3 async
BX: (cstr) sound file name
CX: duration to play (in 1/32 second)
DX: volume: 0 (loudest) to 5 (softest)
DI: address of the status word
Plays a sound file asynchronously; the call completes when the sound has
finished. The other arguments are as for IoPlaySoundW.


Fn $86 Sub $20
IoPlaySoundCancel v3
Cancel any pending IoPlaySoundA.


Fn $86 Sub $21
IoRecordSoundW v3
AL: -> failure code
BX: (cstr) sound file name
CX: number of samples to record, in units of 2048 samples
Records a sound file. Note that 2048 samples are slightly more than a quarter
of a second. The file will be created before recording, and must not be on
a flash device. Note that this call does not fail in the usual way, but just
returns a failure code.


Fn $86 Sub $22
IoRecordSoundA v3 async
BX: (cstr) sound file name
CX: number of samples to record, in units of 2048 samples
DI: address of the status word
Records a sound file asynchronously; the call completes when the recording has
finished. The other arguments are as for IoRecordSoundW.


Fn $86 Sub $23
IoRecordSoundCancel v3
Cancel any pending IoRecordSoundA.


Fn $86 Sub $24
IoPlaySoundAO v3.9 async
BX: (cstr) sound file name
CX: duration to play (in 1/32 second)
DX: volume: 0 (loudest) to 5 (softest)
DI: address of the status word
SI: duration to skip (in 1/32 second)
Plays part of a sound file asynchronously, skipping some initial portion of
the sound; the call completes when the sound has finished. The other
arguments are as for IoPlaySoundA.

Function 0x87

Fn $87 Sub $00 is carried out automatically for OPL programs.

Fn $87 Sub $01
FilExecute fails vsync
eBX: (cstr) program file name
CX: (qstr) program information
DX: address of the status word
DI: address of word to be filled with process ID of new process
Starts a new process and places it in "suspended" state. The program file name will have the extension ".IMG" added if one is not specified. The program information is a qstr whose interpretation depends on the program; it is available from location 36 of the new process's data segment (see Psionics file PROCESS). The process name will be set to the name part of the file (excluding any extension). If another process of this name is already running, both must execute the same code, or the call will fail.

More in S3/S3a manual chapters 1 and 2.

Program information often consists of the following catenated together (note that all these elements except the first are cstrs):

(1) the character 'C' (create new file) or 'O' (open existing file);
(2) (cstr) the application name, with the first character uppercased and the
rest lowercased;
(3) (cstr) one of:
(a) the normal extension for filenames, including the leading dot;
(b) the normal extension with dot, followed by a space and aliasing
information;
(c) an empty string
(4) (cstr) the data file path passed as the initial argument;
(5) (cstr) the application path (may be omitted if not required).

A binary application may be used to operate on a standard file type. Examples include:

Program Application Extension
[item 2] [item 3]
"ROM::DATA.APP" "Data" ".DBF"
"ROM::WORD.APP" "Word" ".WRD"
"ROM::WORD.APP" "Program" ".OPL"
"LOC::C:\APP\COMMS.APP" "Comms" ".SCO"

In each of these cases there is no aliasing information or application path. An example program information qstr is "OData~.DBF~LOC::M:\DBF\MYDATA.DBF~" (tilde indicates a zero byte).

@This section needs rewriting@

The word processor may also be used as a program editor, by making item 2 its name ("Program") and item 3 an extension (usually ".OPL") followed by the necessary aliasing information: this is empty for normal Word, or:

* "O" for OPL editor, "S" for SCR editor, "$" for plain text editor (3a only), "/" for custom template (3a only); any letter uses translator SYS$PRG<letter>.IMG to translate, then
* then "R" indicates that the translator can execute resulting code, anything else means it can't, then
* extension and directory ("OPO" or "SCO" for example) of translated files,
* then on 3a only optional "*" to indicate compatibility mode exists.

An example program information qstr is

"Program~.OPL OROPO~LOC::M:\OPL\MYPROG.OPL~"

template mode for Word means there must be a \WDR\<template>.WRT file on the current drive; template name is that if the application name. For example, alias file of:

Letter.LET
\LET\
1083
Word
/

uses template LETTER. Note mode 80 in application type in alias file.

Finally, a translator may be used to execute a translated file: in the case of the translator "ROM::SYS$PRGO", it can execute either OPO or OPA files. The application name is given in the APP ... ENDA clause for OPA files, and is "RunOpl" for OPO files; there is no extension or aliasing information. For OPA files, the data file is passed to the application, and the application path shows which application is actually run. For OPO files, the data file should name the OPO file itself, and there is no application path. Examples are "RunOpl~~M:\OPO\MYPROG.OPO~" and "MyApp~~M:\DAT\MYDATA~M:\APP\MYAPP.OPA~".

Fn $87 Sub $02
FilParse fails vsync
BX: (cstr) file name to be parsed
CX: (cstr) file specification to be used
DX: address of the status word
SI: address of a 6 byte buffer to be filled in
DI: address of 128 byte buffer to be filled with the parsed filename

This call is equivalent to the PARSE$ keyword. The buffer is filled as follows:

Offset 0 (byte): length of node name
Offset 1 (byte): length of device name
Offset 2 (byte): length of path name
Offset 3 (byte): length of base name
Offset 4 (byte): length of extension
Offset 5 (byte): flags
Bit 0: the base name or extension contains a wildcard ("*" or "?")
Bit 1: the base name contains a wildcard
Bit 2: the extension contains a wildcard


Fn $87 Sub $03
FilPathGet fails vsync
BX: 128 byte buffer
DX: address of the status word
The buffer is filled with the current filing system default path (a cstr).


Fn $87 Sub $04
FilPathSet fails vsync
BX: (cstr) new path
DX: address of the status word
Sets the default path (equivalent to the SETPATH keyword).


Fn $87 Sub $05
FilPathTest fails vsync
BX: (cstr) pathname to be tested
DX: address of the status word
Equivalent to the EXIST keyword; the call succeeds if the file with that
pathname exists.


Fn $87 Sub $06
FilDelete fails vsync
BX: (cstr) pathname to be deleted
DX: address of the status word
Equivalent to the DELETE keyword; non-empty directories cannot be deleted.


Fn $87 Sub $07
FilRename fails vsync
BX: (cstr) old pathname
CX: (cstr) new pathname
DX: address of the status word
Equivalent to the RENAME keyword.


Fn $87 Sub $08
FilStatusGet fails async
BX: (cstr) filename
CX: 16 byte buffer
DX: address of the status word
The buffer is filled in with information about the file:
Offset 0 (word): buffer format version: always 2
Offset 2 (word): attributes
Offset 4 (long): file size in bytes
Offset 8 (long): time last modified

The attribute bits have the following meanings (question marks indicate that
the bit name was specified but the meaning is unknown; equals signs mean that
the bit can be set by FilStatusSet):
= Bit 0: file is not ReadOnly
= Bit 1: file is Hidden
= Bit 2: file is a System file
Bit 3: file is a Volume name
Bit 4: file is a Directory
= Bit 5: file is Modified
? Bit 8: file is a readable file
? Bit 9: file is an executable file
? Bit 10: file is a byte stream file
Bit 11: file is a text file
The LOC:: node (see Psionics file FILEIO) does not distinguish text and binary
files, and always leaves bit 11 clear. Other nodes may distinguish the types of
files and set the bit where appropriate.


Fn $87 Sub $09
FilStatusSet fails vsync
BX: (cstr) filename
CX: mask of attributes to be changed (only specify settable bits)
DX: address of the status word
DI: new values for attributes to be altered
The attributes indicated in the mask of the specified file are altered to
the new values; all other attributes are left unchanged.


Fn $87 Sub $0A AL sync
FilStatusDevice fails vsync
BX: (cstr) device name (such as "A:" or "LOC::A:")
CX: 64 byte buffer
DX: address of the status word
The buffer is filled in with information about the device:
Offset 0 (word): buffer format version
Offset 2 (byte): device type
0 = unknown
1 = floppy
2 = hard disc
3 = flash
4 = ram
5 = rom
6 = write-protected
Offset 3 (byte): device properties:
Bit 3: formattable device
Bit 4: dual density device
Bit 5: internal device
Bit 6: dynamically sizeable device
Bit 7: compressible (worth compressing database files)
Offset 4 (word): non-zero if the device contains removable media
Offset 6 (long): total space on the device in bytes
Offset 10 (long): free space on the device in bytes
Offset 14 (cstr): volume name
Offset 46 (word): device battery status
0 = low battery
1 = battery OK
-4 = status not available for this device type
This field is not valid if the format version (offset 0) is less than 3.


Fn $87 Sub $0B
FilStatusSystem fails vsync
BX: (cstr) node name (such as "LOC::" or "REM::")
CX: 32 byte buffer
DX: address of the status word
The buffer is filled in with information about the node:
Offset 0 (word): buffer format version (currently 2)
Offset 2 (word): 0 = flat, 1 = hierarchical
Offset 4 (word): non-zero if devices are formattable, and zero otherwise


Fn $87 Sub $0C
FilMakeDirectory fails vsync
BX: (cstr) pathname
DX: address of the status word
This is equivalent to the MKDIR keyword.


Fn $87 Sub $0D AL sync
FilOpenUnique fails vsync
eBX: (cstr) pathname
CX: open mode (format and access parts only)
DX: address of the status word
Open a file with a unique name. This is equivalent to the IOOPEN keyword with
a mode of 4. The pathname is used to determine the directory to create
the file in, and will be modified to give the actual name (thus the pathname
should have room for 128 characters).


Fn $87 Sub $0E
FilSystemAttach fails vsync
BX: (cstr) name of a file system PDD
DX: address of the status word
The specified physical device driver will be attached to the filing system,
possible adding new nodes.


Fn $87 Sub $0F
FilSystemDetach fails vsync
BX: (cstr) name of a filing system
DX: address of the status word
Detaches a filing system. Built-in filing systems cannot be detached.


Fn $87 Sub $10
FilPathGetById fails vsync
BX: process to examine
CX: 128 byte buffer
DX: address of the status word
The buffer is set to the current path of the specified process (a cstr).


Fn $87 Sub $11
FilChangeDirectory fails vsync
BX: (cstr) pathname
CX: 128 byte buffer
DX: address of the status word
SI: (cstr) name of subdirectory
DI: 0 = get root directory, 1 = get parent directory, 2 = get subdirectory
The path name is modified in the requested way. This call should be used
instead of manipulating the directory part of a name directly, as it works on
all nodes, irrespective of the format that the node uses for path names.


Fn $87 Sub $12 has no effect on OPL processes.


Fn $87 Sub $13
FilSetFileDate fails vsync
BX: (cstr) pathname
CX: low word of new time
DX: address of the status word
DI: high word of new time
Sets the modification time of the specified file.


Fn $87 Sub $14
FilLocChanged fails vsync
AX: -> channel change flags
BX: channel to check
DX: address of the status word
Specifies whether any directory in the LOC:: node has changed (i.e. a file
or directory has been created, destroyed, or renamed, but not changes to file
contents) since the last use of this system call with this channel. BX should
have exactly one bit set, corresponding to the channel to use; bits 8 to 15
are reserved by Psion. The corresponding bit in AX will be set if the node
has changed, and will be clear otherwise; the other 15 bits are unspecified.
This call can be used to determine whether to update a directory display.


Fn $87 Sub $15
FilLocDevice v3 fails vsync
BX: local device indicator (%A to %H, or %I or %M)
CX: address of word set to the media type
DX: address of the status word
Provides the media type of a device on the LOC:: node (I and M both refer to
the internal ramdisc). The device type consists of:
Bits 0 to 3:
0 = unknown
1 = floppy
2 = hard disc
3 = flash
4 = ram
5 = rom
6 = write-protected
Bits 7 to 8:
0 = device battery measurement not supported
1 = device battery measurement not supported
2 = device battery voltage low
3 = device battery voltage good


Fn $87 Sub $16
FilLocReadPDD v3 fails vsync
BX: local device indicator (%A to %H, or %I or %M)
CX: (long) location on the device
DX: address of the status word
SI: number of bytes to read
DI: address in process to copy first byte to
Copies data from a device on the LOC:: node to the current process. This
call is very efficient, and accesses the raw device.

PSIONICS FILE - SYSCALLS.2
==========================
System calls (part 2)
Last modified 1998-11-07
========================

See part 1 for general notes and explanations.

Function 0x88

Fn $88 Sub $00
ProcId
AX: -> process ID of the current process
Gets the process ID of the current process.


Fn $88 Sub $01
ProcIdByName fails
AX: -> process ID
eBX: (cstr) pattern
Gets the process ID of a process whose name matches the pattern (usual
wildcards apply, and case is ignored).


Fn $88 Sub $02
ProcGetPriority fails
AL: -> priority
BX: process ID
Gets the priority of the specified process.


Fn $88 Sub $03
ProcSetPriority fails
AL: new priority
BX: process ID
Sets the priority of the specified process.


Fn $88 Sub $04 should only be called by the operating system.


Fn $88 Sub $05
ProcCreateTask
Tasks are processes which share the data segment of another process. They
cannot be conveniently handled in OPL.


Fn $88 Sub $06
ProcResume fails
BX: process ID
Take a process out of the suspended state and start it executing.


Fn $88 Sub $07
ProcSuspend fails
BX: process ID
Place a process in the suspended state. If the process is waiting for a system
service (e.g. a semaphore), then it will be suspended when the service has
been carried out.


Fn $88 Sub $08
ProcKill fails
AL: reason code
BX: process ID
Kills the specified process, without allowing it to execute any cleanup code.
Only use this on the current process or in emergencies.


Fn $88 Sub $09
ProcPanicById fails
AL: panic code
BX: process ID
Simulate the specified panic on the specified process.


Fn $88 Sub $0A
ProcNameById fails
BX: process ID
eDI: 13 byte buffer
Places the name (a cstr) of the specified process in the buffer.


Fn $88 Sub $0B
ProcFind fails
AX: -> process ID
BX: 0 or process ID
SI: 14 byte buffer
eDI: (cstr) pattern
Obtains process IDs for processes whose name matches the pattern ("?" and "*"
wildcards have their Unix meaning, and case is ignored). BX should be zero to
return the first matching process, or the process ID returned by a previous
call to return subsequent matching processes. Process are returned in *task*
ID order. The buffer is filled with a cstr giving the process name.


Fn $88 Sub $0C
ProcRename fails
BX: process ID
eDI: (cstr) new name
Rename the specified process; the new name must be between 1 and 8 characters.


Fn $88 Sub $0D
ProcTerminate fails
BX: process ID
Terminates the indicated process. The process will be sent a termination
message if it has so requested, and will be killed otherwise.


Fn $88 Sub $0E
ProcOnTerminate
BX: message type
When the current process is terminated, it will be sent a message of the
specified type; type 0 cancels the request. After receiving the message and
executing any clean-up code, the process should use ProcKill to kill itself.


Fn $88 Sub $0F is reserved for the Shell process.


Fn $88 Sub $10
ProcGetOwner fails
AX: -> owning process ID
BX: process ID
Gets the ID of the process owning the specified process (normally the
creator of that process).

Function 0x89


Fn $89 Sub $00
TimSleepForTenths fails
CX: high half of delay
DX: low half of delay
Sleep for the specified delay (in units of 0.1 seconds). Changing the system
clock does not affect the call. Only time when the machine is switched on is
measured; any time when the machine is switched off will be in addition to
the requested delay.


Fn $89 Sub $01
TimSleepForTicks fails
CX: high half of delay
DX: low half of delay
Sleep for the specified delay (in system ticks; there are 32 ticks per second
on the Series 3 and 18.2 on the PC emulation). Changing the system clock does
not affect the call. Only time when the machine is switched on is measured;
any time when the machine is switched off will be in addition to the requested
delay.


Fn $89 Sub $02
TimGetSystemTime
AX: -> high half of system clock
BX: -> low half of system clock
Reads the system clock (an abstime).


Fn $89 Sub $03
TimSetSystemTime
CX: high half of new system clock
DX: low half of new system clock
Sets the system clock to the given abstime.


Fn $89 Sub $04
TimSystemTimeToDaySeconds
CX: high half of abstime
DX: low half of abstime
DI: 8 byte buffer
Splits an abstime into a day number and an interval, placed in the buffer as
follows:
Offset 0 (long): day number
Offset 4 (long): interval


Fn $89 Sub $05
TimDaySecondsToSystemTime fails
AX: -> high half of abstime
BX: -> low half of abstime
SI: 8 byte buffer
Converts a day number and an interval to an abstime. The former are in the
buffer, in the same format as TimSystemTimeToDaySeconds.


Fn $89 Sub $06
TimDaySecondsToDate fails
SI: 8 byte buffer (day number and interval)
DI: 8 byte buffer (broken down time)
Converts a day number and an interval to broken-down time information. The
former is in the same format as TimSystemTimeToDaySeconds. The latter is in
the format:
Offset 0 (byte): year - 1900
Offset 1 (byte): month (0 = January, 11 = December)
Offset 2 (byte): day - 1
Offset 3 (byte): hours
Offset 4 (byte): minutes
Offset 5 (byte): seconds
Offset 6 (word): day number in year (0 to 364 or to 365)


Fn $89 Sub $07
TimDateToDaySeconds fails
SI: 8 byte buffer (broken down time)
DI: 8 byte buffer (day number and interval)
Converts broken-down time to a day number and an interval. The day number in
year (offset 6) is ignored.


Fn $89 Sub $08
TimDaysInMonth fails
AX: -> number of days in month
CX: month * 256 + year - 1900
Gets the number of days in the specified month (0 = January, 11 = December).


Fn $89 Sub $09
TimDayOfWeek
AX: -> day of week (0 = Monday, 6 = Sunday)
CX: high half of day number
DX: low half of day number
Gets the day of the week of the given date.


Fn $89 Sub $0A
TimNameOfDay fails
AL: day of week (0 = Monday, 6 = Sunday)
BX: 33 byte buffer
The buffer is filled with a cstr giving the name of that day of the week.


Fn $89 Sub $0B
TimNameOfMonth fails
AL: month (0 = January, 11 = December)
BX: 33 byte buffer
The buffer is filled with a cstr giving the name of that month.


Fn $89 Sub $0C
TimWaitAbsolute fails
CX: high half of abstime
DX: low half of abstime
Sleep this process until the specified abstime. If the machine is turned off
at that time, it will turn back on. Changing the system clock will affect
when the call returns.


Fn $89 Sub $0D
TimWeekNumber fails
AX: -> week number (1 to 53)
CX: high half of day number
DX: low half of day number
Gets the week number of the specified day.


Fn $89 Sub $0E
TimNameOfDayAbb v3 fails
AL: day of week (0 = Monday, 6 = Sunday)
BX: 4 byte buffer
The buffer is filled with a cstr giving the abbreviated name of that day of
the week. The length of the abbreviated name varies between languages, but
is the same for all days in a given language.


Fn $89 Sub $0F
TimNameOfMonthAbb v3 fails
AL: month (0 = January, 11 = December)
BX: 4 byte buffer
The buffer is filled with a cstr giving the abbreviated name of that month.
The length of the abbreviated name varies between languages, but is the same
for all months in a given language.


Fn $8A Sub $00
ConvUnsignedIntToBuffer
AX: -> length of converted value
BX: value to be converted
CX: radix
eDI: buffer to hold converted value
The value is converted to a string in the specified radix and written to the
buffer. No trailing zero byte is written; instead, the length of the string
is returned. The radix can be any value from 2 to 200. If the radix is 11 or
greater, digits greater than 9 are written as "A", "B", etc; characters other
than digits and uppercase letters are used when the radix is 37 or more.


Fn $8A Sub $01
ConvUnsignedLongIntToBuffer
AX: -> length of converted value
BX: low half of value to be converted
CX: radix
DX: high half of value to be converted
eDI: buffer to hold converted value
The value is converted to a string, in the same way as ConvUnsignedIntToBuffer.


Fn $8A Sub $02
ConvIntToBuffer
AX: -> length of converted value
BX: value to be converted
eDI: buffer to hold converted value
The value is converted to a string in radix 10 and written to the buffer. If
the value is negative, a leading "-" will be included. No trailing zero byte
is written; instead, the length of the string is returned.


Fn $8A Sub $03
ConvLongIntToBuffer
AX: -> length of converted value
BX: low half of value to be converted
DX: high half of value to be converted
eDI: buffer to hold converted value
The value is converted to a string in radix 10, as for ConvIntToBuffer.


Fn $8A Sub $04
ConvArgumentsToBuffer
AX: -> length of converted format
BX: buffer holding the format arguments
SI: (cstr) format
eDI: buffer to hold converted format
The format is written to the buffer, with certain sequences of characters -
"conversion specifiers" - being replaced by the values of arguments converted
to strings. No trailing zero byte is written; instead, the length of the string
is returned.

All conversion specifiers begin with a percent sign (to include a literal
percent in the output, use "%%"), followed by:
- an optional alignment code
- an optional width code (required if there is an alignment code)
- an optional length code
- a conversion code.

The alignment code consists of two characters. The first is:
- "-": left align (fill on the right)
- "=": centre align (fill at both ends)
- "+": right align (fill on the left).
The second is either the character to fill with, or "*". In the latter case,
the next word is taken from the arguments and used as the fill character.
The default alignment is to right align filling with spaces ("+ "). Also, the
alignment "+0" may be abbreviated to "0".

The width code gives the number of characters generated by the conversion. If
the output would be longer, it is truncated. The code is either an unsigned
decimal number (not beginning with a zero), or "*". In the latter case, the
next word is taken from the arguments and gives the (unsigned) width.

The length code can be "l" or "L" (equivalent); it is equivalent to making the
conversion code uppercase.

Each conversion code (apart from "f") takes an argument of the type stated,
and then converts it as described.

Code Type Conversion

"b" word convert to unsigned binary representation
"B" long convert to unsigned binary representation
"c" word output the character with that code
"C" long output the character with that code
"d" word convert to signed decimal representation
"D" long convert to signed decimal representation
"f" ---- output an empty string filled with the fill character.
"F" ---- output an empty string filled with the fill character.
"o" word convert to unsigned octal representation
"O" long convert to unsigned octal representation
"m" word output the value as 2 bytes, least significant first
"M" long output the value as 4 bytes, least significant first
"s" cstr output the cstr
"S" cstr output the cstr
"u" word convert to unsigned decimal representation
"U" long convert to unsigned decimal representation
"w" word output the value as 2 bytes, most significant first
"W" long output the value as 4 bytes, most significant first
"x" word convert to unsigned hexadecimal representation
"X" long convert to unsigned hexadecimal representation
Codes "m", "M", "w", and "W" are available in EPOC v2.17 and later only.


Fn $8A Sub $05
ConvStringToUnsignedInt fails
AX: -> converted value
CX: radix
SI: (cstr) string to convert -> pointer to first unused character
The string is converted to an unsigned integer in the specified radix. The
conversion ends at the first character which is not a valid digit for the
radix, which may be the terminating zero byte; if the first character of the
string is not valid, the call fails. The letters A to F, in either case, are
used for digits 10 to 15 if the radix is 11 or more. The radix may be greater
than 16, but the valid digits remain restricted to the range 0 to 15.


Fn $8A Sub $06
ConvStringToUnsignedLongInt fails
AX: -> high half of converted value
BX: -> low half of converted value
CX: radix
SI: (cstr) string to convert -> pointer to first unused character
The string is converted, in the same manner as ConvStringToUnsignedInt.


Fn $8A Sub $07
ConvStringToInt fails
AX: -> converted value
SI: (cstr) string to convert -> pointer to first unused character
The string is converted to an signed integer in radix 10. The conversion ends
at the first character which is not a valid digit or leading sign; this may
be the terminating zero byte. If the first character of the string is not a
digit or sign, the call fails.


Fn $8A Sub $08
ConvStringToLongInt
AX: -> high half of converted value
BX: -> low half of converted value
SI: (cstr) string to convert -> pointer to first unused character
The string is converted, in the same manner as ConvStringToInt.


Fn $8A Sub $09
ConvFloatToBuffer fails
AX: -> length of converted value
DX: pointer to 6 byte conversion information block
SI: address of real value to be converted
DI: buffer to hold converted value
The real value is converted to a cstr and placed in the buffer. The exact
format of the string depends on the contents of the conversion information
block:
Offset 0 (byte): 0 = fixed format, 1 = exponent format, 2 = variable format
Offset 1 (byte): maximum length of converted value
Offset 2 (byte): number of decimal digits (fixed and exponent formats only)
Offset 3 (byte): radix character
Offset 4 (byte): triad character (fixed format only)
Offset 5 (byte): triad threshold (fixed format only)
If the converted value would be greater than the maximum length, or the real
to be converted has an exponent less than -99 or greater than 99, the call
fails and the contents of the buffer are undefined (note that the length
of the buffer need only be the maximum specified plus an extra byte for the
terminating zero).

For fixed format, the resulting string will take the form:
* minus sign if the value is negative; nothing if it is positive
* the integer part of the number, with no leading zeros (one zero if the
integer part is zero); if the triad threshold is non-zero and there are
more than that number of digits in the integer part, then the triad
character is inserted between groups of 3 digits
* if the number of decimal digits is non-zero:
- the radix character
- the specified number of digits
For example, the number 1234321.4731 is converted as follows (assuming that
the radix character is "." and the triad character is ","):
0 decimal digits, triad threshold 0: "1234321"
0 decimal digits, triad threshold 5: "1,234,321"
0 decimal digits, triad threshold 7: "1234321"
2 decimal digits, triad threshold 5: "1,234,321.47"
6 decimal digits, triad threshold 1: "1,234,321.473100"

For floating format, the resulting string will take the form:
* minus sign if the value is negative; nothing if it is positive
* one non-zero digit
* if the number of decimal digits is non-zero:
- the radix character
- the specified number of digits
* the letter "E"
* a plus or minus sign
* two digits (using leading zeros if necessary)
For example, the number 1234321.4731 is converted as follows:
0 decimal digits: "1E+06"
2 decimal digits: "1.23E+06"
7 decimal digits: "1.234321E+06"
12 decimal digits: "1.234321473100E+06"
Zero (with either sign) is always converted as "0E+00" or "0.000E+00" etc.

For general format the resulting string will take a form depending on its
value. If the maximum width is W and the real value is R, then:
R <= -1E+(W-1) as for exponent format with W-7 decimal digits
-1E+(W-1) < R <= -1E+(W-2) a string containing a minus sign and W-1 digits
-1E+(W-2) < E <= -1E+(W-1) a string containing a minus sign and W-2 digits
-1E+(W-3) < R <= -1E-4 a string containing a minus sign and then W-2
significant digits with the radix character in
the appropriate position
-1E-4 < R < 0 as for exponent format with W-7 decimal digits
0 = R the string "0"
0 < R < 1E-4 as for exponent format with W-6 decimal digits
1E-4 <= R < 1E+(W-2) a string containing W-1 significant digits with
the radix character in the appropriate position
1E+(W-2) <= E < 1E+(W-1) a string containing W-1 digits
1E+(W-1) <= E < 1E+(W) a string containing W digits
1E+(W) <= R as for exponent format with W-7 decimal digits


Fn $8A Sub $0A
ConvStringToFloat fails
DX: radix character
SI: address of a word pointing to the start of the cstr to convert
DI: address of real variable to be set
Converts a string representing a floating-point value and places it in the
variable. The string must have the form:
* an optional sign
* a mantissa containing at least one digit and an optional radix character
* an optional exponent consisting of:
- the letter "E" or "e"
- an optional sign
- an integer
The resulting value must have an exponent in the range -99 to 99 inclusive.
If it is outside this range, the call fails; for underflow the value 0 is
stored, while for overflow an undefined value is stored.

If the call succeeds, the pointer to the string is altered to point to the
first character beyond the converted number.


Fn $8B Sub $00
GenVersion
AX: -> kernel version
Gets the version of the operating system. Version 1.23 is reported as:
$123A for alpha release
$123B for beta release
$123F for final release


Fn $8B Sub $01
GenLcdType
AL: -> display type
Gets the display type:
0 = 640x400 LCD (MC)
1 = 640x200 LCD small version (MC)
2 = 640x200 LCD large version or CGA (PC emulation)
3 = 720x348 LCD or Hercules graphics
4 = 160x80 LCD (HC)
5 = 240x80 LCD (Series 3t)
6 = MDA (PC emulation)
7 = EGA monochrome (PC emulation)
8 = EGA colour (PC emulation)
9 = VGA monochrome (PC emulation)
10 = VGA colour (PC emulation)
11 = 480x160 LCD (Series 3a and Series 3c)
12 = 240x100 LCD (Workabout)
14 = 240x160 LCD (Siena)
255 = unknown


Fn $8B Sub $02
GenStartReason
AL: -> reason code
Gets the reason for the last cold start:
0 = system RAM invalid
1 = forced power down
2 = user reset (using reset button)
3 = kernel fault
4 = new operating system installed
The environment variables and the internal disc are valid after reasons 1 and
3, and are valid after reason 2 unless ESC was also pressed.

Reason 1 only happens if a faulty device driver delayed a normal battery-low
powerdown for too long.


Fn $8B Sub $03
GenParse fails
BX: 18 byte buffer
Parse filenames according to certain basic rules. Unlike FilParse, this does
not invoke any device drivers. The buffer has the format:
Offset 0 (word): address of file name 1 (a cstr)
Offset 2 (word): address of file name 2 (a cstr)
Offset 4 (word): address of file name 3 (a cstr)
Offset 6 (word): address of buffer to be filled with final name (a cstr)
Offset 8 (word): address of 6 byte buffer
Offset 10 (byte): device separator
Offset 11 (byte): path separator
Offset 12 (byte): extension separator
Offset 13 (byte): maximum length of device including separators
Offset 14 (byte): maximum length of path including separators
Offset 15 (byte): maximum length of name
Offset 16 (byte): maximum length of extension including separator
The three filenames are split into 5 components, any of which may be missing.
* node (ends with "::")
* device (ends with device separator)
* path (ends with last path separator)
* name
* extension (starts with extension separator)
The final name is constructed by taking, for each component, the value from
file name 1 if present, otherwise the value from file name 2 if present,
and otherwise the value from file name 3. The 6 byte buffer is then filled in
with the same data as for FilParse. File names 2 and 3 should be in different
places in memory.


Fn $8B Sub $04
LongUnsignedIntRandom
AX: -> high half of random number
BX: address of seed -> low half of random number
Generates a 32 bit unsigned random number from a seed; the number also replaces
the seed, so that the sequential calls with the same seed address will generate
a random sequence based on the initial seed.


Fn $8B Sub $05
GenGetCountryData
BX: 40 byte buffer
Fills the buffer with country-specific data:
Offset 0 (word): country code (e.g. UK is 44) of locale
Offset 2 (word): current offset from GMT in minutes (+ is ahead)
Offset 4 (byte): date format (0 = MDY, 1 = DMY, 2 = YMD)
Offset 5 (byte): time format (0 = am-pm, 1 = 24 hour)
Offset 6 (byte): currency symbol position (0 = before, 1 = after)
Offset 7 (byte): currency symbol separated with space (0 = yes, 1 = no)
Offset 8 (byte): currency decimal places
Offset 9 (byte): currency negative format (0 = minus, 1 = brackets)
Offset 10 (byte): currency triad threshold
Offset 11 (byte): triad separator
Offset 12 (byte): decimal separator
Offset 13 (byte): date separator
Offset 14 (byte): time separator
Offset 15 to 23: currency symbol (cstr)
Offset 24 (byte): start of week (0 = Mon, 1 = Tue, ... 6 = Sun)
Offset 25 (byte): currently active summer times:
Bit 0: home
Bit 1: European
Bit 2: Northern
Bit 3: Southern
Bits 4 to 7: unused, always zero
Offset 26 (byte): clock type (0 = analogue, 1 = digital)
Offset 27 (byte): number of letters in day abbreviation (0 to 6)
Offset 28 (byte): number of letters in month abbreviation (0 to 255)
Offset 29 (byte): workdays (the set bits indicate the workdays)
Bit 0: Monday
Bit 1: Tuesday
Bit 2: Wednesday
Bit 3: Thursday
Bit 4: Friday
Bit 5: Saturday
Bit 6: Sunday
Bit 7: always zero
Offset 30 (byte): units (0 = inches, 1 = centimetres)

If the triad threshold is non-zero and there are more than that number of
digits in the integer part of an amount of money, then the triad character
should be inserted between groups of 3 digits. See ConvFloatToBuffer for a
way to do this.


Fn $8B Sub $06
GenGetErrorText
AL: error number
BX: 64 byte buffer
The buffer will be filled with a cstr giving an error message corresponding to
the error number (a generic message including the number is used when there is
no stored message in the current locale).


Fn $8B Sub $07
GenGetOsData
CX: number of bytes to fetch
SI: offset of first byte in kernel workspace
DI: buffer to be filled in
Copy a number of bytes from the kernel workspace to the current process.
Within assembler code, this can also be done via GenDataSegment (see Psionics
file KERNEL).


Fn $8B Sub $08 only applies to MC systems.


Fn $8B Sub $09
GenNotify fails
AL: -> option chosen (0 = first, 1 = second, 2 = third)
BX: first message (cstr, up to 63 characters plus the terminating zero)
CX: second message (cstr, up to 63 characters plus the terminating zero)
DX: first option (cstr, up to 15 characters plus the terminating zero)
SI: second option (cstr, up to 15 characters plus the terminating zero)
DI: third option (cstr, up to 15 characters plus the terminating zero)
Sends a message to the notifier process and waits for a reply. The call fails
if there is no notifier process running. The two messages are displayed, and
the user is offered the three options. The chosen option is returned.

Any of the arguments except BX may be zero instead; for CX this means that
only one message is displayed, while for DX, SI, and DI it means that less
options are offered (if all are zero, the option "CONTINUE" is offered).


Fn $8B Sub $0A
GenNotifyError fails
AL: error number -> option chosen (0 = first, 1 = second, 2 = third)
BX: first message
DX: first option
SI: second option
DI: third option
This call is equivalent to GenNotify with the second message derived from the
error number via GenGetErrorText.


Fn $8B Sub $0B and $0C are used by the notifier process.


Fn $8B Sub $0D
GenGetRamSizeInParas
AX: -> system RAM size
Gets the amount of system RAM fitted, in units of 16 bytes. Note that this
is an unsigned value - $8000 represents 512 kb, not some negative amount.


Fn $8B Sub $0E
GenGetCommandLine
AX: -> zero or command line
Gets a pointer to the command line if the program was started with program
information (see FilExecute). If so, the command line consists of a cstr giving
the program executed, immediately followed by the program information (a qstr).


Fn $8B Sub $0F
GenGetSoundFlags
AX: -> sound flags
Gets the sound flags:
Bit 0: keyboard clicks enabled
Bit 1: sound via piezo buzzer enabled
Bit 2: sound via SND: device driver enabled
Bit 3: keyboard clicks: set=loud, clear=soft
Bit 4: piezo buzzer: set=loud, clear=soft
Bit 15: set=disable all sound, clear=obey individual flags


Fn $8B Sub $10
GenSetSoundFlags
BX: sound flags
Sets the sound flags to new values (see GenGetSoundFlags).


Fn $8B Sub $11
GenSound
BX: duration in ticks
CX: pitch code (frequency=512kHz/code)
Makes a simple single-frequency note. Access to this call is sequenced; it
will wait until the piezo buzzer is not in use, and will return when the sound
has started to play. On the Series 3a, the piezo buzzer is emulated by the
SND: device, but the emulation is complete (for example, this call works
even when SND: is disabled by GenSetSoundFlags).


Fn $8B Sub $12
GenMarkActive
Fn $8B Sub $13
GenMarkNonActive

These two calls alter the state of the current process to "active" (the default
when the process starts) or "non-active". Whenever an active process restarts
execution after being idle (basically when keywords such as IOWAIT, IOW, GET
and so on return), the auto-off timer is reset; the machine switches off when
the timer reaches the appropriate value.


Fn $8B Sub $14
GenGetText fails
AL: message number
eBX: 64 byte buffer
Copies a message (a cstr) from the kernel message table to the buffer.


Fn $8B Sub $15
GenGetNotifyState
AL: -> notify state (0=unattended, 1=notify)
Gets the notify state for the process. If this is "unattended", then the file
server will not call the notifier process when a correctable error occurs (such
as an SSD with open file being removed), but will simply return an error. If
it is "notify" (the initial state), then it will use GenNotify to request the
user to fix the problem.


Fn $8B Sub $16
GenSetNotifyState
AL: notify state
Sets the notify state for the process. See GenGetNotifyState for details.


Fn $8B Sub $17
GenGetAutoSwitchOffValue
AX: -> auto-off time in seconds, or $FFFF if disabled
Gets the auto-off time.


Fn $8B Sub $18
GenSetAutoSwitchOffValue
BX: auto-off time in seconds, or $FFFF to disable
Sets the auto-off time. Times of less than 15 are adjusted to 15.


Fn $8B Sub $19 and $1A are for device drivers only.


Fn $8B Sub $1B
GenGetLanguageCode
AX: -> current locale code
Gets the current locale code. Locale codes are listed in the Psionics file
LOCALES.


Fn $8B Sub $1C
GenGetSuffixes
eBX: 93 byte buffer
The buffer is filled with 31 cstrs giving the correct suffix for each of the
31 days of the month. The suffix for day N is at offset (3*N-3).


Fn $8B Sub $1D
GenGetAmPmText
AL: 0=AM, 1=PM
eBX: 3 byte buffer
The buffer is filled with a cstr giving the correct suffix for "a.m." or
"p.m." times.


Fn $8B Sub $1E
GenSetCountryData
eBX: 40 byte buffer
Sets the country-specific data to that in the buffer. See GenGetCountryData
for the format of the buffer.


Fn $8B Sub $1F
GenGetBatteryType
AL: -> battery type
Gets the battery type from the following list:
0 = Unknown
1 = Alkaline
2 = NiCaD (600 mAh)
3 = NiCaD (1000 mAh)
4 = NiCaD (500 mAh)
The battery type is used to control the warning thresholds.


Fn $8B Sub $20
GenSetBatteryType
AL: battery type
Sets the battery type (see GenGetBatteryType).


Fn $8B Sub $21
GenEnvBufferGet fails
AX: -> size of value
DX: length of pattern
eSI: buffer filled with value
eDI: pattern to search for
Searches for an environment variable whose name matches the pattern (if there
is more than one, which one is chosen is unspecified). The buffer is filled
with the variable's value.


Fn $8B Sub $22
GenEnvBufferSet fails
CX: size of value (0 to 255)
DX: length of name (1 to 16)
eSI: buffer holding value
eDI: name of variable
Changes the value of the specified enviromment variable, creating it first if
necessary. The name may not contain wildcards.


Fn $8B Sub $23
GenEnvBufferDelete fails
DX: length of name
eDI: pattern to delete
Searches for an environment variable whose name matches the pattern and deletes
it (if there is more than one, which one is deleted is unspecified).


Fn $8B Sub $24
GenEnvBufferFind fails
AX: -> new handle
BX: previous handle (0 for first call)
DX: length of pattern
eSI: 273 byte buffer
eDI: pattern to search for
Searches for each environment variable whose name matches the pattern. The
call is made multiple times until it fails; the same pattern must be used
each time. If the call succeeds, the buffer is filled with two qstrs, the
first being the name and the second the value of the variable found.


Fn $8B Sub $25
GenEnvStringGet fails
eSI: 256 byte buffer
eDI: pattern (cstr)
Searches for an environment variable whose name matches the pattern (if there
is more than one, which one is chosen is unspecified). The buffer is filled
with the variable's value followed by a zero byte (thus a cstr).


Fn $8B Sub $26
GenEnvStringSet fails
eSI: value (cstr)
eDI: name (cstr)
Changes the value of the specified enviromment variable, creating it first if
necessary. The name may not contain wildcards and is limited to 16 characters;
the value is limited to 255 characters.


Fn $8B Sub $27
GenEnvStringDelete fails
eDI: pattern (cstr)
Searches for an environment variable whose name matches the pattern and deletes
it (if there is more than one, which one is deleted is unspecified).


Fn $8B Sub $28
GenEnvStringFind fails
AX: -> new handle
BX: previous handle (0 for first call)
eCX: 256 byte buffer
eSI: 17 byte buffer
eDI: pattern to search for
Searches for each environment variable whose name matches the pattern. The
call is made multiple times until it fails; the same pattern must be used
each time. If the call succeeds, the 17 byte buffer is filled with the name
of the variable, as a cstr, and the 256 byte buffer is filled with the value
followed by a zero byte (thus also a cstr).


Fn $8B Sub $29
GenCrc
AX: -> CRC
CX: buffer length
DX: previous CRC
SI: buffer
Calculates the CCITT Cyclic Redundancy Checksum using the X^16+X^12+X^5+1
polynomial (e.g. the CRC of a single byte with value 1 is $1021). If the
buffer is to be checked standalone, use zero as the previous checksum. If
several blocks are to be checksummed as if they were one long block, use 0
as the previous CRC for the first block, and the previous result for the
remainder.


Fn $8B Sub $2A
GenRomVersion
AX: -> rom version number
Gets the version of the system ROM (which includes both the operating system
and many files). Version 1.23 is reported as:
$123A for alpha release
$123B for beta release
$123F for final release


Fn $8B Sub $2B and $2C are used by the alarm server process.


Fn $8B Sub $2D
GenAlarmId
AX: -> alarm server pid
Gets the process ID of the alarm server process, or 0 if none is running.


Fn $8B Sub $2E
GenPasswordSet fails
uSI: (qstr) current password
uDI: (qstr) new password
Sets a new system password. The call will fail and take no action if the
current password is incorrect.


Fn $8B Sub $2F
GenPasswordTest fails
uSI: (qstr) password to test
Succeeds if the system password is that provided.


Fn $8B Sub $30
GenPasswordControl fails
AL: new state (0 = off, 1 = on)
uSI: (qstr) current password
Turns the system password on and off. The call will fail and take no action
if the current password is not provided.


Fn $8B Sub $31
GenPasswordQuery
AX: -> new state (0 = off, 1 = on)
Get the status of the system password.


Fn $8B Sub $32
GenTickle

Resets the auto-off timer. A non-active process (see GenMarkNonActive) can
use this to prevent auto-off.


Fn $8B Sub $33
GenSetConfig
@No documentation available at present@


Fn $8B Sub $34
GenMaskInit fails
SI: (qstr) password
DI: 18 byte encryption control block
Initializes an encryption control block according to the password given.

The contents of the control block for the current algorithm are:
Offset 0 to 8: encryption key, generated from the password
Offset 9 to 15: copy of offset 0 to 7
Offset 16 (word): current location within the key (initially zero)
@The algorithm for generating the key from the password is unknown.

It is possible that future versions of this call may implement multiple
encryption algorithms, so AL, BX, CX, and DX - unused at present - should
be set to zero.


Fn $8B Sub $35
GenMaskEncrypt fails
CX: length of buffer
SI: encryption control block
DI: buffer holding data to be encrypted
Encrypts a block of data according to the encryption control block, which
will be updated. The value of the encrypted data depend only on the original
data and on the contents of the control block, which should normally be
initialized by GenMaskInit. Provided that the control block is not modified
in any other way, encrypting a block of data in two or more parts yields the
same result as encrypting it all at once.

The current encryption algorithm operates on a byte by byte basis as follows.
For each data byte in turn, take the value of offset 16 in the control block
(which will be from 0 to 15) and use it to select one of the first 16 bytes
in the control block (that is, offset 16 = 0 selects offset 0, offset 16 = 1
selects offset 1, and so on). Add the selected byte to the data byte modulo
$100. Finally, add 1, modulo 16, to offset 16 of the control block.

An example of this algorithm in use can be found in the file WORD.FMT.

It is possible that future versions of this call may implement multiple
encryption algorithms, so AL, BX, and DX - unused at present - should be set
to zero.


Fn $8B Sub $36
GenMaskDecrypt fails
CX: length of buffer
SI: encryption control block
DI: buffer holding data to be decrypted
Decrypts a block of data according to the encryption control block, which
will be updated. The data should have been encrypted with GenMaskEncrypt
with the same initial control block. All comments applying to the latter call
apply here.


Fn $8B Sub $37
GenSetOnEvents v2.28
AL: 0=disable 1=enable
Enables or disables reporting of power-on events. By default this is enabled
on the Series 3 and disabled on other systems. Disabling may affect other
applications.


Fn $8B Sub $38
GenGetAutoMains v3
AX: -> setting
Gets the setting of the external power auto-off flag. Zero means that auto-off
will take place even if external power is present, while non-zero means that
auto-off is suspended while external power is present.


Fn $8B Sub $39
GenSetAutoMains v3
AL: new setting
Sets the external power auto-off flag. Zero means that auto-off will take
place even if external power is present (unless it has been disabled by
setting the auto-off time to $FFFF), while non-zero means that auto-off is
suspended while external power is present.


Fn $8C Sub $00
FloatSin fails [sine]
Fn $8C Sub $01
FloatCos fails [cosine]
Fn $8C Sub $02
FloatTan fails [tangent]
Fn $8C Sub $03
FloatASin fails [arc sine]
Fn $8C Sub $04
FloatACos fails [arc cosine]
Fn $8C Sub $05
FloatATan fails [arc tangent]
Fn $8C Sub $06
FloatExp fails [exponentiation (base e)]
Fn $8C Sub $07
FloatLn fails [natural logarithm (base e)]
Fn $8C Sub $08
FloatLog fails [decimal logarithm (base 10)]
Fn $8C Sub $09
FloatSqrt fails [square root]
SI: argument (real)
DI: result (real)
Calculates the specified function of the argument. The argument and result
may be stored in the same place; if not, the argument is not altered. The
trignometric functions operate in radians.


Fn $8C Sub $0A
FloatPow fails
DX: power (real)
SI: base (real)
DI: result (real)
Calculates the result of raising the base to the indicated power. The result
may be stored in the same place as either argument; if not, neither argument
is altered.


Fn $8C Sub $0B
FloatRand
SI: seed (long)
DI: result (real)
Generates a random real number based on the unsigned long integer seed, which
is unaltered; the memory used for the two should not overlap.


Fn $8C Sub $0C
FloatMod fails
DX: divisor (real)
SI: dividend (real)
DI: result (real)
Calculates the dividend modulo the divisor, using the formula:
result = dividend - divisor * FloatInt (dividend/divisor)
The result may be stored in the same place as either argument; if not, neither
argument is altered.


Fn $8C Sub $0D
FloatInt fails
SI: argument (real)
DI: result (real)
Rounds the argument to the closest integer towards zero (i.e. zeros the
fractional part of the argument). The argument and result may be stored in the
same place; if not, the argument is not altered.

PSIONICS FILE - SYSCALLS.3
==========================
System calls (part 3)
Last modified 1998-07-22
========================

See part 1 for general notes and explanations.

 

Fn $8D is used for the Window Server, and is described in the Psionics file
WSERVER.


Fn $8E Sub $00 to $10 control various parts of the hardware, and should not
be used by OPL programs.


Fn $8E Sub $11
HwGetSupplyStatus
BX: 6 byte buffer
Gets information about the power supply. The buffer is filled with the
following data:
Offset 0 (word): main battery voltage in mV
Offset 2 (word): backup battery voltage in mV
Offset 4 (word): positive if external power is available, zero if not
available, and negative if the detector is disabled
because an SSD door is open.
The returned voltages should be taken with a grain of salt: I have observed
the following values:
1800: no main batteries
1800: low main batteries
2056: new main batteries
2300: no lithium battery
2556: lithium battery fitted


Fn $8E Sub $12
HwLcdContrastDelta
AL: step direction
Alters the LCD contrast by one step, upwards if AL is between 0 and 127, and
downwards if it is between 128 and 255 (all inclusive).


Fn $8E Sub $13
HwReadLcdContrast
AL: -> setting
Gets the current LCD contrast setting. On a Series 3, only the bottom 4 bits
are significant.


Fn $8E Sub $14
HwSwitchOff
CX: delay in quarter seconds
Switches the machine off for the specified time, then back on again ($FFFF
means never turn back on). The machine will also be turned on by external
events, alarms, and timers. The delay must be at least 9 (2.25 seconds).


Fn $8E Sub $15 should only be used by device drivers.


Fn $8E Sub $16
HwExit

Exits the emulation on PC systems; has no effect on actual Psion machines.


Fn $8E Sub $17 to $1A should only be used by device drivers.


Fn $8E Sub $1B
HwGetPsuType
AL: -> PSU type
Gets the PSU type: 0 = old MC, 1 = MC "Maxim", 2 = Series 3t, 3 = Series 3a


Fn $8E Sub $1C
HwSupplyWarnings
BX: 8 byte buffer
Gets information about the power supply. The buffer is filled with the
following data:
Offset 0 (word): main battery good voltage threshold in mV
Offset 2 (word): backup battery good voltage threshold in mV
Offset 4 (word): main battery nominal maximum voltage in mV
Offset 6 (word): backup battery nominal maximum voltage in mV
The values will depend on the battery type set by GenSetBatteryType.


Fn $8E Sub $1D
HwForceSupplyReading
@No documentation available at present@


Fn $8E Sub $1E
HwGetBackLight
AX: -> current value
On systems fitted with a backlight, this value indicates control of the
backlight function. If the top bit is set, the operating system will ignore
the backlight toggle key. The remaining bits give the auto-light-off time in
ticks (1/32 second); zero means that auto-light-off is disabled.


Fn $8E Sub $1F
HwSetBackLight
BX: new value
Sets the backlight control value (see HwGetBackLight).


Fn $8E Sub $20
HwBackLight fails
AL: action -> status before call
This call fails if no backlight is fitted. Otherwise, the actions are:
0 = switch backlight off
1 = switch backlight on
2 = toggle backlight
3 = no action
The status returned is that of the backlight before the call: 0 = off, 1 = on.


Fn $8E Sub $21 controls various parts of the hardware, and should not be used
by OPL programs.


Fn $8E Sub $22
HwSupplyInfo v3
BX: 22 byte buffer
Fills the buffer with additional information about the power supply:
Offset 0 (byte): main battery status:
0 = not present
1 = very low voltage
2 = low voltage
3 = good voltage
Offset 1 (byte): worst main battery status since batteries last inserted
Offset 2 (byte): non-zero if backup battery voltage is good
Offset 3 (byte): non-zero if external supply is present
Offset 4 (word): warning flags
Bit 0: set if power supply too low for sound
Bit 1: set if power supply too low to use flash
Bit 2: set if offset 6 changed because system clock changed
clear if offset 6 changed because the batteries were changed
Offset 6 (long): abstime when batteries inserted
Offset 10 (long): ticks running on battery
Offset 14 (long): ticks running on external supply
Offset 18 (long): mA-ticks (i.e. mAhours * 60 * 60 * 32)


Fn $8E Sub $28
HwGetScanCodes v3
BX: 20 byte buffer
The buffer is filled with information describing the state of each key on
the keyboard. For the Series 3a, the offset and bit for each key are given
in the following table ("2:4" means offset 2, bit 4).
System 9:1 Esc 15:0 Delete 4:0 1 14:1 A 12:2 N 0:6
Data 7:1 Tab 0:2 Enter 0:0 2 14:2 B 8:6 O 4:5
Word 11:1 Control 4:7 ShiftR 6:7 3 10:6 C 10:3 P 2:5
Agenda 3:1 ShiftL 2:7 Up 14:5 4 8:2 D 10:4 Q 12:1
Time 1:1 Psion 0:7 Left 0:4 5 8:3 E 10:5 R 8:1
World 5:1 Menu 10:7 Down 0:5 6 14:3 F 10:1 S 12:4
Calc 3:0 Diamond 8:7 Right 0:1 7 6:6 G 8:5 T 8:4
Sheet 1:0 Space 8:0 Help 6:2 8 4:3 H 14:6 U 6:5
+ and = 2:3 - and _ 2:2 9 4:4 I 4:2 V 10:2
* and : 2:6 / and ; 2:1 0 2:4 J 6:4 W 12:5
, and < 6:1 . and > 14:4 K 4:1 X 12:6
L 4:6 Y 0:3
M 6:3 Z 12:3


Fn $8E Sub $29
HwGetSsdData

Nothing is known about this call except its name. @@@@@@


Fn $8E Sub $2A
HwResetBatteryStatus v3.9

The battery status is reset, exactly as if the main batteries had been
removed and then replaced.


Fn $8E Sub $2B
HwEnableAutoBatReset v3.9
AX: -> (if querying) 1 = enabled, 0 = disabled
BX: 1 = enable, 0 = disable, -1 = query
Enables, disables, or queries the current setting of the automatic reset
of the battery status. This is intended for use on the Workabout, where
the batteries can be recharged in situ.


Fn $8E Sub $2C
HwGetBatData v3.9
AX: -> address of a data structure in kernel data space
The data is described in the KERNEL file.


Fn $8E Sub $2E
HwReLogPacks v3.9 fails

This has the same effect as opening and then closing the SSD doors.


Fn $8E Sub $2F
HwSetIRPowerLevel v3.9
AX: -> previous level (0 = low, 1 = high)
BX: new level (0 = low, 1 = high)
Sets the IR power level, returning the previous level.


Fn $8E Sub $30
HwReturnTickCount v3.9
AX: tick count
Returns a tick count that is incremented 32 times per second.


Fn $8E Sub $31
HwReturnExpansionPortState v3.9
AX: -> port type and state
BX: -> zero
Returns the type and state of the expansion port:
Bits 0 to 7: non-zero if SSD doors are open, or something has just been
plugged into or removed from the Honda expansion connector
Bits 8 to 14: connector type: 0 = Series 3t/3a, 1 = Workabout LIF,
2 = Siena Honda, 3 = Series 3c Honda, 4 = HC
Bit 15: 1 = contains Condor chip, 0 = no Condor chip


Fn $8F
GenDataSegment

This call is only useful in assembler code; it sets ES to point to the start
of the kernel data space (accessible in OPL using GenGetOsData).


Fn $90
ProcPanic
AL: reason
Panic the current process; this call never returns.


Fn $91
ProcCopyFromById fails
BX: process ID
CX: number of bytes to copy
SI: remote address of first byte to copy
eDI: local address of first byte to copy
Copy a number of bytes from the indicated process to the current process.


Fn $92
ProcCopyToById fails
BX: process ID
CX: number of bytes to copy
SI: local address of first byte to copy
DI: remote address of first byte to copy
Copies a number of bytes from the current process to the indicated process.


Fn $93
CharIsDigit
Fn $94
CharIsHexDigit
Fn $95
CharIsPrintable
Fn $96
CharIsAlphabetic
Fn $97
CharIsAlphaNumeric
Fn $98
CharIsUpperCase
Fn $99
CharIsLowerCase
Fn $9A
CharIsSpace
Fn $9B
CharIsPunctuation
Fn $9C
CharIsGraphic
Fn $9D
CharIsControl
AL: character to test
EQ: -> set if test fails, clear if test succeeds
Tests to see whether the character has the indicated property. These functions
are language dependent.


Fn $9E
CharToUpperChar
Fn $9F
CharToLowerChar
Fn $A0
CharToFoldedChar
AL: character 1 -> converted character 1
AH: character 2 -> converted character 2
Converts two characters to uppercase, lowercase, or folded (uppercase with no
accents). These functions are language dependent.


Fn $A1
BufferCopy
CX: length to be copied
SI: address of "from" buffer
eDI: address of "to" buffer
Copies a number of bytes from one buffer to another. The case of the buffers
overlapping is handled correctly.


Fn $A2
BufferSwap
CX: length to be swapped
SI: address of buffer 1
eDI: address of buffer 2
Swaps the contents of two buffers. The case of the buffers overlapping is
handled correctly.


Fn $A3
BufferCompare
Fn $A4
BufferCompareFolded
BX: length of buffer 2
CX: length of buffer 1
SI: address of buffer 1
eDI: address of buffer 2
UL: -> set if buffer 1 less than buffer 2
EQ: -> set if buffers are identical
The contents of the two buffers are compared byte-for-byte, using unsigned
comparisons, and the result flags set accordingly. BufferCompareFolded acts
as if each character had been passed to CharToFoldedChar before comparison.


Fn $A5
BufferMatch fails
Fn $A6
BufferMatchFolded fails
CX: length of buffer
DX: length of pattern
SI: address of buffer
eDI: address of pattern
The buffer is examined to determine whether it matches the pattern (using
the usual wildcards); the call fails if it does not. BufferMatchFolded acts
as if each character had been passed to CharToFoldedChar before comparison.


Fn $A7
BufferLocate fails
Fn $A8
BufferLocateFolded fails
AH: character -> [undefined]
AX: -> offset of character
CX: length of buffer
SI: address of buffer
The buffer is searched to determine if the character occurs within it; the
call fails if it does not. If it does, the offset from the start of the buffer
of the first occurence is returned. BufferLocateFolded acts as if each
character had been passed to CharToFoldedChar before comparison.


Fn $A9
BufferSubBuffer fails
Fn $AA
BufferSubBufferFolded fails
AX: -> offset
BX: length of buffer 2
CX: length of buffer 1
SI: address of buffer 1
eDI: address of buffer 2
Buffer 1 is searched to determine if buffer 2 occurs within it; the call fails
if it does not. If it does, the offset from the start of buffer 1 of the first
occurence of buffer 2 is returned. BufferSubBufferFolded acts as if each
character had been passed to CharToFoldedChar before comparison.


Fn $AB
BufferJustify
AX: -> address of first uncopied character
BX: length of buffer 2
CX: length of buffer 1
DX: fill character * 256 + control code
SI: address of buffer 1
eDI: address of buffer 2
Buffer 1 is copied into buffer 2, and the remaining space filled with the fill
character according to the control code (0 = fill at end, 1 = fill at start,
2 = centre the copied data). If buffer 1 is longer than buffer 2, then the
contents will be truncated to fit. If the length of buffer 2 is negative, then
it is assumed to be the same as that of buffer 1 (and the data is just copied).


Fn $AC
StringCopy
Fn $AD
StringCopyFolded
SI: cstr
eDI: large enough buffer
The cstr is copied into the buffer. StringCopyFolded passes each character
through CharToFoldedChar during the copy.


Fn $AE
StringConvertToFolded
SI: cstr
Each character of the cstr is passed through CharToFoldedChar.


Fn $AF
StringCompare
Fn $B0
StringCompareFolded
SI: cstr 1
eDI: cstr 2
UL: -> set if cstr 1 less than cstr 2
EQ: -> set if cstrs are identical
The contents of the two cstrs are compared byte-for-byte, using unsigned
comparisons, and the result flags set accordingly. StringCompareFolded acts
as if each character had been passed to CharToFoldedChar before comparison.


Fn $B1
StringMatch fails
Fn $B2
StringMatchFolded fails
SI: cstr to be searched
eDI: pattern (cstr)
The cstr is searched to determine if the pattern occurs within it (using
the usual wildcards); the call fails if it does not. StringMatchFolded acts
as if each character had been passed to CharToFoldedChar before comparison.


Fn $B3
StringLocate fails
Fn $B4
StringLocateFolded fails
Fn $B5
StringLocateInReverse fails
Fn $B6
StringLocateInReverseFolded fails
AH: character -> [undefined]
AX: -> offset of character
SI: cstr
The cstr is searched to determine if the character occurs within it; the
call fails if it does not. If it does, the offset from the start of the cstr
of the first (for StringLocate and StringLocateFolded) or last (for the two
Reverse calls) occurence is returned. The two Folded calls act as if each
character had been passed to CharToFoldedChar before comparison.


Fn $B7
StringSubString fails
Fn $B8
StringSubStringFolded fails
AX: -> offset
SI: cstr 1
eDI: cstr 2
Cstr 1 is searched to determine if cstr 2 occurs within it; the call fails
if it does not. If it does, the offset from the start of cstr 1 of the first
occurence of cstr 2 is returned. StringSubStringFolded acts as if each
character had been passed to CharToFoldedChar before comparison.


Fn $B9
StringLength
AX: -> length of the cstr
eDI: cstr
Returns the length of a cstr, excluding the terminating zero byte.


Fn $BA
StringValidateName fails
AL: maximum number of characters permitted
AH: non-zero if an extension is permitted
eDI: cstr
The cstr is checked to see if it a valid name, and the call fails if it is
not. A name is valid if it:
* begins with a letter;
* contains only letters, digits, dollar signs ($), underscores (_), and at
most one dot;
* if AH is zero, does not contain a dot;
* contains no more than the specified number of characters before the dot
(if any); and
* contains no more than 4 characters after the dot, if any.
@The manual says 3 characters, but my tests accept 4.@


Fn $BB
LongIntCompare
AX: high half of P
BX: low half of P
CX: high half of Q
DX: low half of Q
SL: -> set if P less than Q
EQ: -> set if P equals Q
Compares P and Q (both signed longs) and sets the result flags accordingly.


Fn $BC
LongIntMultiply fails
AX: high half of P -> high half of product
BX: low half of P -> low half of product
CX: high half of Q
DX: low half of Q
Multiples P and Q (both signed longs); the call fails if the result cannot
be represented as a signed long.


Fn $BD
LongIntDivide fails
AX: high half of P -> high half of quotient
BX: low half of P -> low half of quotient
CX: high half of Q -> high half of remainder
DX: low half of Q -> low half of remainder
Divides P by Q (both signed longs); the call fails if Q is zero. The remainder
will have the same sign as P.


Fn $BE
LongUnsignedIntCompare
AX: high half of P
BX: low half of P
CX: high half of Q
DX: low half of Q
UL: -> set if P less than Q
EQ: -> set if P equals Q
Compares P and Q (both unsigned longs) and sets the result flags accordingly.


Fn $BF
LongUnsignedIntMultiply fails
AX: high half of P -> high half of product
BX: low half of P -> low half of product
CX: high half of Q
DX: low half of Q
Multiples P and Q (both unsigned longs); the call fails if the result cannot
be represented as a unsigned long.


Fn $C0
LongUnsignedIntDivide fails
AX: high half of P -> high half of quotient
BX: low half of P -> low half of quotient
CX: high half of Q -> high half of remainder
DX: low half of Q -> low half of remainder
Divides P by Q (both unsigned longs); the call fails if Q is zero.


Fn $C1
FloatAdd fails
Fn $C2
FloatSubtract fails
Fn $C3
FloatMultiply fails
Fn $C4
FloatDivide fails
SI: address of Q
DI: address of P
Calculates the specified one of P+Q, P-Q, P*Q, or P/Q, and places the result
in P. Both P and Q are reals.


Fn $C5
FloatCompare
SI: address of Q
DI: address of P
SL: -> set if P is less than Q
EQ: -> set if P equals Q
Compares two reals and sets the result flags appropriately.


Fn $C6
FloatNegate
DI: address of P
Negates a real in-situ.


Fn $C7
FloatToInt fails
Fn $C8
FloatToUnsignedInt fails
AX: -> result
SI: address of real
Converts a real to a signed or unsigned int; the call fails if the result is
out of range. FloatToUnsignedInt ignores the sign of the real.


Fn $C9
FloatToLong fails
Fn $CA
FloatToUnsignedLong fails
AX: -> high half of result
BX: -> low half of result
SI: address of real
Converts a real to a signed or unsigned long; the call fails if the result is
out of range. FloatToUnsignedLong ignores the sign of the real.


Fn $CB
IntToFloat
Fn $CC
UnsignedIntToFloat
AX: value
DI: address of real
Converts a signed or unsigned int to a real.


Fn $CD
LongToFloat
Fn $CE
UnsignedLongToFloat
AX: high half of value
BX: low half of value
DI: address of real
Converts a signed or unsigned long to a real.


Fn $CF
LibSend
Fn $D0
LibSendSuper
AX: -> method result
BX: handle of object to receive the message
CX: message number
DX: argument 1
SI: argument 2
DI: argument 3
These functions send a message to an object and invoke a method on that object.
LibSend starts searching for the method in the class of the object, and
LibSendSuper in the superclass.


Fn $D1 to $D3 can only be used from assembler.


Fn $D4
Dummy

This function has no effect.


Fn $D5
GenIntByNumber
AL: Fn -> error and result flags
SI: argument block
DI: result block
This call is equivalent to the OS keyword; it calls another system call with
the arguments and results stored in 12 byte blocks.


Fn $D6 is used for the Window Server, and is described in the Psionics file
WSERVER.


Fn $D7 is normally only used by the C library.


Fn $D8 is used for accessing DBF files. See the Psionics file DBF.FMT.


Fn $D9
LibEnterSend
AX: -> method result
BX: handle of object to receive the message
CX: message number
DX: argument 1
SI: argument 2
DI: argument 3
This is identical to LibSend, except that it also starts a new "entry-exit
region". The method description will state when this is needed.


Fn $DA
IoKeyAndMouseStatus
@No documentation available at present@


Fn $DB
StringCapitalise
SI: cstr
The first character of the cstr is passed through CharToUpperChar, and the
remaining characters through CharToLowerChar.


Fn $DC
ProcIndStringCopyFromById fails
BX: process ID
CX: maximum length to copy
SI: address of location holding address of cstr
eDI: buffer
This copies a cstr from the indicated process to the current process. The
cstr is found via a pointer also in the memory of the indicated process, and
the address of this pointer is specified. This call is equivalent to making
two calls to ProcCopyFromById, the first to find the location of the cstr, and
the second to fetch it, except that the contents of the buffer beyond the
terminating zero are unspecified.


Fn $DD is reserved for the window server.


Fn $DE
IoSerManager
@No documentation available at present@

EPOC16 Window Server Calls

This file wouldn't have appeared for much longer if it weren't for Dan Ramage, who sent Clive enough material to convince him to restart after many months of neglect.

Dan, if you're still about, we would really like the source code for your Damage graphics engine!

This page is dedicated to the memory of Felicia Hatunen. Most of Clive's original version of the document this was based on was written while he was travelling to and from a memorial service for her (in California). It seems fitting that such a memorial should remain.

There is a lot of missing and incomplete material in this file. By his own admission, there are a number of gaps in what Clive had (and we currently have), particularly the mapping of registers to C function arguments. Therefore this file contains more than the usual number of @ signs indicating missing material. Assistance in filling these gaps would be greatly appreciated.

Introduction

Processes in EPOC16 do not have direct access to the screen and keyboard. Instead, they send messages to a special process called the Window Server. This process then handles the screen and keyboard, arbitrating between the various requests - for example, it ensures that only the current foreground process gets keystrokes, and handles the case of different application windows overlapping.

Many calls to the Window Server are buffered; the individual commands are stored in a buffer, and then sent to the server in a batch. This is done whenever the buffer is full, by any command requiring a response from the server, whenever waiting for an event, and by the wFlush call. The calls that return a value but do not flush the command buffer are:
gTextCount, gFontInfo, and wCheckBitmapid.

If an error occurs when a buffered command is executed, all further commands are ignored until one that requires a response. This command is also ignored, and the error is returned instead.

Clients of the window server can be in the foreground or background. On machines with a small screen, only one client can be in the foreground, and it occupies the whole screen. On machines with a large screen, more than one client can be in the foreground or be visible at a time.

See the file SYSCALLS.1 for the notation used in this file. In the case of function 0x8D, bit 7 of the sub-function number is set to indicate that the function obtains a response from the server; this bit is ignored in ordering the functions in the following list of descriptions. Furthermore, in the case of Fn 0x8D Sub 0x7E and Sub 0xFF, there are several different functions depending on the value of AL.

If a call is marked "fails" then:

A common data structure is the "standard rectangle structure". This is defined here:

Offset Length Description
0 2 x coordinate of left edge of the rectangle
2 2 y coordinate of top edge of the rectangle
4 2 x coordinate of left edge plus width
6 2 y coordinate of top edge plus height

Graphics Contexts

Many window server calls are described as using a "graphics context". This is a data structure associated with a specific window or bitmap and stored in the window server itself. It determines various features about the call, such as the font used in text operations. At any time there is a "current GC"; calls labelled "cgc" use that to determine appropriate properties.

A graphics context is specified using a GC description block. This is a block of memory in the client laid out as follows:

Offset Length Description
0 1 Graphics mode (0=set, 1=clear, 2=invert)
1 1 Text mode (0=set, 1=clear, 2=invert, 4=copy with background)
2 1 Text style
3 1 Additional graphics options (v4 only)
4 2 Font or font group

Offset 2: Text styles

Bit Description
0 bold
1 underline
2 inverse
3 double height
4 monospaced
5 italic
6 subscript (v4 only, and only with appropriate font groups)
7 superscript (v4 only, and only with appropriate font groups)

Offset 3: Additional graphics options (v4 only)

Bit Description
0-1 0 = black plane, 1 = grey plane, 2 = both planes
2 double pixel mode, clear = normal

Wherever a font is required, one of the ROM-based fonts beginning at 0x4000 can be used. The value 0x4099 always means the system font.

GC description blocks are normally provided in association with a GC selector mask. This is a word which is used to determine which values are taken from the description block, as follows:

Bit Description
1 graphics mode
2 text mode
3 text style
4 font
5 bits 0 and 1 of additional graphics options (v4 only)
6 bit 2 of additional graphics options (v4 only)

When creating a new GC, values not taken from the description block are set to zero, except the font which is set to the system font.

Events

An event is a message sent from the window server to a client to inform it that something has happened that is not directly related to a function call; for example, that a key has been pressed when the client is the foreground client. The event is between 2 and @@ bytes long depending on its type. Offset 0 is always a word giving the event type.

In many types of event the words at offsets 2 and 4 have a standard meaning.

Type 1: WM_KEY

Offset Length Description
0 2 type, set to 1
2 2 connection handle
4 2 tick count
6 2 keycode
8 1 keyboard modifiers and mouse state
9 1 unused
10 1 repeat count

Sent when a key is pressed and the client is the one connected to the keyboard (usually because it owns the frontmost foreground window). The keycode is defined by the key and modifiers. For example, the 'A' key will generate:

The window server will handle control-plus-number combinations and generate a single event. @@@@ special cases

The modifiers are:

Bit Description
1 shift key pressed
2 control key pressed
3 Psion or alt key pressed
4 caps lock is on
5 num lock is on
6 Not used.
7 mouse button down

The repeat count is 1 for a single key press. If a key is held down and is auto-repeating faster than the client accepts new events, the repeat count will be set to the number of repeats since the last key event.

Type 2: WM_MOUSE

Offset Length Description
0 2 type, set to 2
2 2 window handle
4 2 tick count
6 1 1=release, 2=press, 3=motion
7 1 keyboard modifiers and mouse state
8 2 mouse position x coordinate
10 1 mouse position y coordinate

Sent when the mouse button is pressed or released, or the mouse moves and the appropriate window has requested motion events. The modifiers are as for WM_KEY, plus Bit 6:

Bit Description
1 shift key pressed
2 control key pressed
3 Psion or alt key pressed
4 caps lock is on
5 num lock is on
6 mouse position is outside the visible portion of the window
7 mouse button down

This can happen through grabs and mouse capture.

Type 3: WM_REDRAW

Offset Length Description
0 2 type, set to 3
2 2 window handle
4 2 tick count
6 2 left edge
8 2 top edge
10 2 @@@ right edge or width or what ?
12 2 @@@ bottom edge or height or what ?

Sent when no other events (except WM_USER_MSG) are pending and a window has an area that needs redrawing (an "update region"). The rectangle describes some portion (possibly all) of the update region.

Type 5: WM_BACKGROUND

Offset Length Description
0 2 type, set to 5

Sent to a client in the foreground when it moves to the background.

Type 6: WM_FOREGROUND

Offset Length Description
0 2 type, set to 6

Sent to a client in the background when it moves to the foreground.

Type 7: WM_RUBBER

Offset Length Description
0 2 type, set to 7
2 2 window handle
4 2 tick count
6 2 final status
8 8 standard rectangle structure giving the final size

Offset 6: Final Status

The final status can be:

Bit Description
0 the final rectangle is the same as the initial one
1 the rubber band moved but was not resized
2 the rubber band was resized
3 the rubber band was cancelled; the rectangle is undefined
4 the rubber band was not displayed because the parameters were wrong

Type 8: WM_USER_MSG

Offset Length Description
0 2 type, set to 8

Sent to a client following a call to wUserMsg if no other events are pending (and so can be used to check that condition).

Type 9: WM_ACTIVE

Offset Length Description
0 2 type, set to 9

More information needed.

Type 11: WM_CANCELLED

Offset Length Description
0 2 type, set to 11

Sent to a client following a call to wCancelGetEvent.

Type 12: WM_KEYBOARD_STATE_CHANGE

Sent to the system shell only.

Type 13: WM_RUBBER_BAND_INIT

Offset Length Description
0 2 type, set to 13
2 2 window handle
4 2 tick count
6 1 set to 2
7 1 keyboard modifiers and mouse state
8 2 mouse position x coordinate
10 2 mouse position y coordinate

Sent to a client on a button press when the window is configured so that pressing a mouse button starts rubber banding. The window server will suspend all mouse and keyboard processing for all clients until this client calls wRubberBand. If rubber banding is not desired, the cancel flag can be used in the call.

Type 14: WM_DEICONISE

Offset Length Description
0 2 type, set to 14

Sent to an iconised client when it moves to the foreground.

Type 15: WM_ATTACHED

Offset Length Description
0 2 type, set to 15
2 2 Unknown
4 2 tick count
6 2 attached client

Sent to a client when another client has attached itself on top. Note that the notifier process attaches itself to a client when that client uses the p_notify system call.

Type 16: WM_DETACHED

Offset Length Description
0 2 type, set to 16

Sent to a client when a previously attached client detaches itself.

Type 17: WM_COMMAND v3.5

Offset Length Description
0 2 type, set to 17

Sent to a client that is the target of a wSendCommand call, and indicates that wGetCommand should be called.

Type 18: WM_TASK_KEY

Series 3 only.

Offset Length Description
0 2 type, set to 18
2 2 connection handle
4 2 tick count
6 2 application key code @@@
8 2 modifiers ? @@@
10 2 repeat count ? @@@

@@@@

Type 19: WM_TASK_UPDATE v3.5

Offset Length Description
0 2 type, set to 19

Sent to the shell process if any process terminates, whether or not a client of the window server.

Type 20: WM_ON v3.5

Offset Length Description
0 2 type, set to 20

Sent to a client when the machine is switched on and the client has either called wInformOnAll, or has called wInformOn and is in the foreground.

Type 21: WM_ESCAPE

Offset Length Description
0 2 type, set to 21

@@@@

Sent on if key events are not selected using wGetEventSpecial. The event is sent when the ESC key is pressed; all pending keystrokes are thrown away.

Type 22: WM_DATE_CHANGED v4

Offset Length Description
0 2 type, set to 22

Sent to any client which is not in Series 3t compatibility mode and is in the foreground, whenever either the date changes, or the machine is switched on on a different date to when it was switched off.

System calls

Function 0x8D

Sub-function 0x00: wEndRedraw

Ends redrawing, as started by wBeginRedrawWin or related calls.

Sub-function 0x01: wEraseTextCursor

Makes the text cursor invisible.

Sub-function 0x02: wReleaseMouse

Cancels any call to wCaptureMouse.

Sub-function 0x03: gFreeTempGC

Destroys the temporary graphics context, and makes the remembered current graphics context be current again.

Sub-function 0x04: wCancel

@@@

Sub-function 0x85: wDisconnect

@@@

Sub-function 0x06: wDetachClient

Detaches the client from any process it is attached to (see wAttachToClient) and moves it to the back.

Sub-function 0x07: wCleanUp

Returns the window server to a standard state. This frees any temporary graphics context, ends any redraws taking place, and invalidates any window that has an attached graphics context.

Sub-function 0x08: wAttachToForegroundClient

Attaches the client to the current foreground client, if different. See wAttachToClient for details.

Sub-function 0x09: wUserMsg

Instructs the window server to send the client a WM_USER_MSG event when there are no other events to deliver. Only one such event can be pending for a client.

Sub-function 0x8A: wStartCompute

Inform the window server that the client is about to start intensive computation, and its priority should be set to 112 (background) even if it is in the foreground. Ignored if the client has not selected server-controlled priority handling (see wSetPriorityControl).

Sub-function 0x8B: wEndCompute

Cancel the effect of wStartCompute; if the client is in the foreground,  sets its priority back to 128 (foreground). Ignored if the client has not selected server-controlled priority handling.

Sub-function 0x8C: wClientInfo fails

Register Description
BX ID of process to be checked

Output: AX: -> information about the process

Returns information about a process:

Bit 0: set if the process is connected the window server
Bit 1: returns the setting specified at connection time
Bit 2: the client is system modal
Bit 7: server-controlled priority handing is active

If the process is not a client of the window server, the call may return zero or may fail.

Sub-function 0x0D: wCloseWindowTree

Register Description
BX Window ID

Destroys the window and all its descendants.

Sub-function 0x8E: wInquireWindow

Register Description
BX Window ID
SI Address of 14 byte information block (see wCreateWindow)

The first 10 bytes of the block are set to the flags, position, and size of the specified window. The last 4 bytes of the block are set to unspecified values.

Sub-function 0x0F: wCaptureMouse

Register Description
BX Window ID

Captures the mouse within the window and its descendants. It will cancel any active capture in another window.

Sub-function 0x10:wBeginRedrawWin

Register Description
BX Window ID

Validate the window for redrawing. Validation causes all pixels to be set or cleared if the background mode is 1 or 2 (this applies to black and grey separately), and all future drawing is clipped to the update region (which is set to the entire window in this case). Normal drawing resumes when wEndRedraw is called.

Sub-function 0x11: wFree

Register Description
BX Identifier

Destroy an object and free all the related resources. The identifier can be any of:

Sub-function 0x12: wMakeInvisible

Register Description
BX Window ID

The window is marked as invisible; a window will not appear on the screen if it or any of its ancestors is invisible.

Sub-function 0x93: wAttachtoClient fails

Register Description
BX ID of process to attach to

Attaches the current process to the specified one. This will cause its windows to stay just in front of those of the client it is attached to. Applies only on large screen servers.

Sub-function 0x14: wInitialiseWindowTree

Register Description
BX Window ID

The specified window and its descendants are initialized. This may only be done once for any given window, and must be done before it is first drawn on.

Sub-function 0x15: wInvalidateWin

Register Description
BX Window ID

Add the entire window to its own update region. This will cause a redraw event, which can be used to trigger redrawing of the window.

Sub-function 0x16: wValidateWin

Register Description
BX Window ID

Validate the window (causing all pixels to be set or cleared if the background mode is 1 or 2 - this applies to black and grey separately), and the update region is deleted.

Sub-function 0x17: wMakeVisible

Register Description
BX Window ID

Cancels wMakeInvisible on the window.

Sub-function 0x18: wClientIconised

Register Description
BX action (0 = deiconise, 1 = iconise)

Iconises or deiconises the current process. Iconisation only works on large screen systems.

Sub-function 0x19: wClientPosition

Register Description
BX Position
CX Process ID

Move the specified process (zero means the current process) to the given position in the window server task list. Position 0 is the front of the list; any position greater than or equal to the number of processes attached to the window server puts the process at the very back of the list.

Sub-function 0x9A: wInquireWindowOffset fails

Register Description
BX ID of window A (0 = screen)
CX ID of window B
SI address of a 4 byte buffer

The buffer is filled in with the position of window B relative to window A:

Offset 0 (word): x offset

Offset 2 (word): y offset

Sub-function 0x1B: wWindowPosition

Register Description
BX Window ID
CX position (0 = front)

Moves the window to the specified position within the sibling list (the list of windows with the same parent).

Sub-function 0x1C: wScrollRect

Register Description
BX Window ID
CX address of a standard rectangle structure
DX address of offset structure

The pixels defined by the rectangle are copied to a new rectangle offset by the indicated distance. The offset structure is:

Offset 0 (word): x offset of new rectangle
Offset 2 (word): y offset of new rectangle

Copying does not go outside the window, and does not appear in areas obscured by other windows or in "invalid" areas waiting for update.

Sub-function 0x1D: wRubberBand

Register Description
BX ID of window to be sent the WM_RUBBER event
CX ID of window limiting the rubber band (0 = whole screen)
DX address of an information block

Starts rubber banding, with the rubber band limited to the specified window or allowed to roam over the screen. When the user completes the rubber banding, a WM_RUBBER event is sent to the window given. The information block is:

Offset 0 to 7: standard rectangle structure giving the initial rectangle
Offset 8 to 15: standard rectangle structure giving the inner bounds
Offset 16 to 23: standard rectangle structure giving the outer bounds
Offset 24 (word): flags
Offset 26 (word): minimum width
Offset 28 (word): minimum height
Offset 30 (word): maximum width
Offset 32 (word): maximum height
Offset 34 (word): x grid snap value
Offset 36 (word): y grid snap value

@@@@@@@@

A window can be set so that pressing a mouse button starts rubber banding. In this case, the press event is sent as a WM_RUBBER_BAND_INIT event instead. The client must call wRubberBand (use the @@@@@@ flag to cancel rubber banding if necessary).

Sub-function 0x1E: gCopyRect cgc

Register Description
BX Standard rectangle structure
CX address of point definition block
DX mode (see gFillPattern)

Copies a rectangular block from one part of a bitmap to another (the current graphics context should refer to a bitmap). The top left corner of the rectangle is copied to the point given by the definition block:

Offset 0 (word): x
Offset 2 (word): y

Sub-function 0x9F: gPeekBit

Register Description
BX Window ID
CX address of point definition block
DX number of pixels
SI address of buffer

Copies a horizontal row of pixels into the buffer. The point definition block gives the first pixel to be copied:

Offset 0 (word): x

Offset 2 (word): y

The pixels are packed 8 per byte of the buffer, in LSB-first order ?@@@@@@
In version 4, the grey plane can be used by setting bit 15 of BX.

Sub-function 0x20: gDrawPolyLine cgc

Register Description
BX x coordinate of start point
CX y coordinate of start point
DX address of poly-line control block

Draws a sequence of lines according to the control block, which has the format:

Offset 0 (word): number of line segments (N)
Offsets 2 to 5: line segment 1 control block
Offsets 6 to 9: line segment 2 control block
...
where the block is 4N+2 bytes long. The control block for segment M has the format:


Offset 4M-2 (word): 2 times x offset, plus 0 for draw or 1 for don't draw
Offset 4M (word): y offset

Each control block causes a line to be drawn, or not drawn, from the previous end point (or the start point, for the first control block) to a new point specified as a relative offset. In version 2 of the window server there is a limit of 61 control blocks.

Sub-function 0x21: gFillPattern cgc

Register Description
BX standard rectangle structure
CX bitmap (0x4000 = chequered 1 and 0 pixels)
DX mode

Fills the specified rectangle with copies of the bitmap. The mode can be:

0 = set each pixel where the bitmap has a 1 pixel
1 = clear each pixel where the bitmap has a 1 pixel
2 = invert each pixel where the bitmap has a 1 pixel
4 = copy the bitmap to the rectangle

In version 3 and above, CX can also be a window with black plane redraw method 3, indicating that the backup bitmap of that window is to be used. In version 4, if both planes have redraw method 3, the appropriate plane is used for each selected plane in the target window or bitmap.

Sub-function 0x22: gCreateTempGC

Register Description
BX Window or bitmap
CX GC selector mask
DX GC description block

Creates a new temporary graphics context associated with the window or bitmap, and makes it the current GC. The previous current GC is remembered. While a temporary graphics context exists, the following calls are forbidden:

gCreateGC
gCreateTempGC
gSetGC (unless modifying the temporary graphics context)
wBeginRedrawGC
wBeginRedrawWinGC
wFree for any graphics context

Sub-function 0xA3: gCreateGC fails

Register Description
BX Window ID or bitmap
CX GC selector mask
DX GC description block

Output: AX: -> graphics context identifier

Creates a new graphics context associated with the window or bitmap, and makes it the current GC.

Sub-function 0x24: gSetGC

Register Description
BX graphics context (for v3 and above, 0=current GC)
CX GC selector mask
DX GC description block

Makes the specified graphics context current, and modifies those properties specified in the selector mask.

Sub-function 0x25: wSetWindow

Register Description
BX window to change
CX flags
DX address of a block of information about the window

Changes various properties of a window. The flags are as follows:

Bits 2 to 6, 8, and 10: set the indicated property to the corresponding bit of the flags within the information block
Bit 12: if set, move and resize the window
Bit 13: if set, change the pointer symbol
Bit 14: if set, change the background method

New values are taken from the information block, which is as for wCreateWindow.

Sub-function 0x26: wBeginRedrawWinGC

Register Description
BX Window ID
CX Unknown
DX GC selector mask
DI address of a GC description block

Validate the window for redrawing (see wBeginRedrawWin) but using a temporary graphics context which will be destroyed by wEndRedraw.

Sub-function 0x27: gDrawLine cgc

Register Description
BX x coordinate of first end
CX y coordinate of first end
DX x coordinate of second end
DI y coordinate of second end

Draws a line between the two locations. If horizontal or vertical, the line includes the end with the lower coordinates. If diagonal, the line includes all pixels intersected by the diagonal of a rectangle including the top and left edges but not the bottom and right edges. Note that, in all cases, the order of the two ends does not affect the line drawn.

Sub-function 0x28: gPrintText cgc

Register Description
BX x coordinate of starting point
CX y coordinate of baseline
DX (text) string
DI length of string (maximum 246)

Prints the string at the indicated location. Characters not found in the font will be treated as if they were the highest character code.

Sub-function 0x29: gCopyBit cgc

Register Description
BX address of point definition block
CX bitmap identifier or window identifier
DX standard rectangle structure
DI mode (see gFillPattern)

Copies a rectangular block from a bitmap or a backed-up window (see gSaveBit). The top left corner of the rectangle is copied to the point given by the definition block:

Offset 0 (word): x
Offset 2 (word): y

The function cannot copy from a bitmap to itself. If the destination is in grey plane mode, the grey plane of the source is used if there is one. If the destination is in both planes mode, a single plane source is copied to both planes, and a double plane source has each plane copied to the corresponding plane.

Sub-function 0xAA: wCreateWindow fails

Register Description
BX parent window (0 = parent is the entire screen)
CX flags
DX address of a block of information about the window
DI handle for the new window (must not be zero)

Output: AX: -> new window identifier

Creates a new window which is a child of the specified window, and gives it the indicated id and handle (note that the two are not the same, and the former is used in other calls except where explicitly stated otherwise). The window cannot be drawn to until wInitialiseWindowTree has initialised it. The flags are:

Bits 0 to 11: if set, use the corresponding bit from the flags word of the information block; if clear, bits 1, 2, 7, 8, and 9 are
cleared, the remainder are inherited from the parent window.

Bit 12: set = use coordinates and size, clear = covers entire parent
Bit 13: set = use pointer symbol in information block, clear = use parent's
Bit 14: set = new background method, clear = same method as parent

The information block contains the following:

Offset 0 (word): flags
Bit 0: this window is input-only (and therefore invisible)
Bit 1: pressing a mouse button starts rubber-banding (see wRubberBand)
Bit 2: ignore the mouse when it is within this window
Bit 3: send mouse events when the mouse button is up
Bit 4: send mouse events when the mouse button is down
Bit 5: grab the mouse when its button is pressed
Bit 6: draw in double pixel mode (v4 only)
Bit 7: visible only when client is in foreground (large screen only)
Bit 8: send redraw events to windows with this bit set bfore those with it clear
Bit 9: do not send redraw events
Bit 10: activate the window if it receives a mouse click
Bit 11: rubber banding will terminate when the mouse button is released

Offset 2 (word): x coordinate within parent
Offset 4 (word): y coordinate within parent
Offset 6 (word): width
Offset 8 (word): height
Offset 10 (word): identifier of the pointer symbol, where relevant
Offset 12 (byte): background redraw method

Bits 0 and 1: black plane method (0 = do nothing, 1 = set pixels,
2 = clear pixels, 3 = keep an off-screen bitmap)
Bit 3: if set, attempts to draw on the black plane are ignored (v4 only)
Bits 4 and 5: grey plane method (0 = do nothing, 1 = set pixels,
2 = clear pixels, 3 = keep an off-screen bitmap)
Bit 7: if clear, attempts to draw on the grey plane are ignored

The choice of keeping an off-screen bitmap cannot be changed after the window has been created, while the other options can be changed using wSetWindow.

Sub-function 0x2B: wBeginRedrawGC

Register Description
BX window
CX address of a standard rectangle structure
DX graphics context fields to be set
DI address of a graphics context information block

Validate the window for redrawing (see wBeginRedrawWin) with the update region set to the indicated rectangle and using a temporary graphics context which will be destroyed by wEndRedraw (see wBeginRedrawWinGC).

Sub-function 0xAC: gPrintClipText cgc

Register Description
BX x coordinate of starting point
CX y coordinate of baseline
DX (text) string
DI length of string (maximum 244)
SI maximum number of pixels

Output: AX: -> number of characters printed

Prints the string at the indicated location as gPrintText, but only enough characters are printed to fit within the specified number of pixels.

Sub-function 0x2D: gPrintBoxText cgc

Register Description
BX address of a standard rectangle structure
SI distance from top of rectangle to baseline
AX alignment (1=right, 2=left, 4=centre)
CX margin
DX (text) string
DI length of string (maximum 236)

Clears the specified rectangle, then prints the string within it using text mode 0 (set pixels). The text is clipped to fit within the rectangle. The string is printed in the part of the rectangle excluding a margin area, whose position depends on the alignment:
left or right: CX must be >= 0, margin is on the same side, width is CX centre and CX >= 0: margin is on the left, width is CX centre and CX < 0: margin is on the right, width is -CX

Sub-function 0xAE: gOpenBit fails

Register Description
BX (cstr) filename
CX bitmap number (0 = first or only)
DX flags
SI address of an information block

Output: AX: -> bitmap identifier

Loads a specified bitmap from a file. The flags are:

Bit 0: set for a writeable bitmap, clear for a shared read-only bitmap
Bit 1: place the bitmap in a separate memory segment
Bit 2: write the segment name in the information block
Bit 3: must be clear

The information block is written to as follows:

Offset 0 (word): set to the width of the bitmap
Offset 2 (word): set to the height of the bitmap
Offset 4 to 17: set to the segment name (cstr), only if flag bit 2 is set

Sub-function 0xAF: gOpenMouseIcon fails

Register Description
BX (cstr) file name
CX number of icon within file

Output: AX: -> mouse icon identifier

Loads a specified mouse icon from a file.

Sub-function 0xB0: gOpenFont fails

Register Description
BX (cstr) filename

Output: AX: -> font identifier

Opens the specified font file.

Sub-function 0x31: gDrawBox cgc

Register Description
BX address of a standard rectangle structure

Draws a box of the appropriate size. Note that a box with width and height of 3 will have exactly one empty pixel inside it.

Sub-function 0xB2: wLoadDYL fails

Register Description
BX (cstr) DYL segment name

Output: AX: -> DYL identifier

Load a DYL into the window server. The DYL must already have been loaded into memory with @@@@@@@

More information needed.

Sub-function 0xB3: gCreateBit fails

Register Description
@@ flags
@@ address of an information block

Output: AX: -> bitmap identifier

Creates an uninitialized writeable bitmap. The flags are:

Bit 0: must be clear
Bit 1: place the bitmap in a separate memory segment
Bit 2: write the segment name in the information block
Bit 3: make the bitmap zero-sized

If the bitmap is zero-sized, nothing can be written to it; the size can be increased later. The information block is:

Offset 0 (word): width
Offset 2 (word): height
Offset 4 to 17: set to the segment name (cstr), only if flag bit 2 is set

Sub-function 0x34: wScrollWin

Register Description
BX window or bitmap
CX address of offset structure

Identical to wScrollRect with the rectangle structure set to (0, 0, width, height).

Sub-function 0x35: wDrawTextCursor

Register Description
BX window
CX address of text cursor information

As wTextCursor, but the properties byte is ignored and treated as zero.

Sub-function 0x36: wInvalidateRect

Register Description
BX window
CX address of a standard rectangle structure

Add the rectangle to the update region of the window. This will generate a redraw event if necessary.

Sub-function 0x37: wBeginRedraw

Register Description
BX window
CX address of a standard rectangle structure

Validate the window for redrawing (see wBeginRedrawWin) with the update region set to the rectangle.

Sub-function 0x38: wValidateRect

Register Description
BX window
CX address of a standard rectangle structure

Validate the indicated rectangle of the window (causing all pixels to be set or cleared if the background mode is 1 or 2 - this applies to black and grey separately), and remove that rectangle from the update region of the window.

Sub-function 0xB9: gSaveBit fails

Register Description
BX (cstr) filename
CX bitmap identifier, window identifier, or zero

Writes a bitmap to the named file. A window identifier must be for a window with a background redraw method of 3, in which case its off-screen bitmap is used. Zero for the bitmap causes the entire screen to be saved. If the window off-screen bitmap, or the screen, has a grey plane then a double-plane bitmap is written.

Sub-function 0x3A: gClrRect cgc

Register Description
BX standard rectangle structure
CX 0=set, 1=clear, 2=invert

Sets, clears, or inverts all pixels in the specified rectangle.

Sub-function 0x3B: wCallDYL

Register Description
BX DYL identifier
CX function number
DX number of bytes of data to be passed
DI address of data to be passed

Call a function in a DYL loaded into the window server that has no result.

Sub-function 0xBC: wCallDYLreply fails

Register Description
BX dyl identifier
CX function number
DX number of bytes of data to be passed
DI address of data to be passed
SI address of area to store a result in

Output: AX: -> result

Call a function in a DYL loaded into the window server that has a result. The main result is returned in AX (a negative value is a failure), and other data (depending on the function) may be written into the area pointed to by SI.

Sub-function 0xBD: wSetWinBitmap fails

Register Description
BX window
CX number of bitmaps (1 to 12)
DX address of a sequence of information blocks

Output: AX: -> sequence identifier

Attaches an animated sequence of bitmaps to the background of a window. Each time the background changes the client will be sent a redraw event unless an appropriate background mode has been selected. There must be an information block for each bitmap in the sequence; the blocks are immediately adjacent in memory. Each block has the form:

Offset 0 (word): bitmap identifier
Offset 2 (word): x coordinate of location in the window to display bitmap
Offset 4 (word): y coordinate of location in the window to display bitmap
Offsets 6 to 13: standard rectangle structure giving the part of the bitmap to be displayed
Offset 14 (byte): graphics mode used to copy bitmap (0=set, 1=clear, 2=invert, 4=copy with background)
Offset 15 (byte): plane to write to (0=white, 128=grey) (v4 only)
Offset 16 (long): delay in 0.1 seconds before next bitmap is shown

Sub-function 0x3E: wChangeWinBitmap

Register Description
BX bitmap sequence identifier
CX position of bitmap (0 to 11)
DX address of an information block

Replace the appropriate bitmap in a sequence (see wSetWinBitmap) with the new information in the block.

Sub-function 0xBF: wEscapeon

More information needed.

Sub-function 0x40

More information needed.

@@@ RConnect

Sub-function 0xC1: wEscapeoff

More information needed.

Sub-function 0xC2: wGetWindowPosition v3

@@@@ ???? [ was = GetPosition] fails

Register Description
BX window

Output: AX: -> position

Returns the position of the window in its sibling list (the windows with the same parent). Has the side effects of wCheckPoint.

Sub-function 0xC3: gSaveRect fails

Register Description
BX (cstr) filename
CX bitmap identifier, window identifier, or zero
DX standard rectangle structure

Saves a rectangle from a bitmap, backed-up window, or the screen (see gSaveBit for details).

Sub-function 0x44: wReassignRootWindow v3

Register Description
BX window (0 = screen)

All future calls within this client will treat the specified window as it it were the whole screen (e.g. this window will be the parent for those whose parent is specified as 0).

Sub-function 0xC5: wCaptureKey v3 fails

Register Description
BX keycode
CX modifier state
DX modifier mask

Captures certain key combinations; from now on, these key presses will be sent to this client whether or not it is in the foreground. The key combinations captured are those that will generate the specified keycode, and for which those modifiers given in DX have the value given in CX (all other bits in CX must be clear). For example, to only depend on the settings of shift and control:

Shift Control CX DX
Up Up 0 6
Up Down 4 6
Up Either 0 2
Down Up 2 6
Down Down 6 6
Down Either 2 2
Either Up 0 4
Either Down 4 4
Either Either 0 0

(if CX is not 0, nothing is captured)

However, it should be borne in mind that most modifier combinations affect the keycode as well. The call fails if the same combination is already captured; if two different combinations capture the same key, the client that made the earlier request receives the event.

Sub-function 0xC6: wCancelCaptureKey v3 fails

Register Description
BX keycode
CX modifier state
DX modifier mask

Cancels a call to wCaptureKey with identical arguments. The call fails if the client has not captured this combination.

Sub-function 0x47: wSystemModal v3

Register Description
BX position in task list (0 = front)

Makes the current client system modal and sets its position in the task list. Task switching only applies to clients that are in front of the frontmost system modal task.

Sub-function 0x48: wCancelSystemModal v3

Register Description
BX position in task list (0 = front)

Cancels a call to wSystemModal and re-positions the client.

Sub-function 0x49: gBorder v3 cgc

Register Description
BX border type

Draws a border just inside the window or bitmap of the current graphics context. The border type is:

Bit 0: if set, draw the border 1 pixel from the edge
Bit 1: set for 4 pixel corner, clear for 1 or 2 pixel corner
Bits 2 to 4: allowance for shadow

0 = no shadow
1 = remove (but leave space for) single width shadow
2 = remove (but leave space for) double width shadow
5 = draw single width shadow
6 = draw double width shadow

Bit 5: set for special top-of-menu border
Bit 6: set for 1 pixel corner, clear for 2 or 4 pixel corner
Bit 7: remove any arrow at top right, and repair the border
Bit 8: remove any arrow at bottom right, and repair the border
Bit 9: include an arrow at top right
Bit 10: include an arrow at bottom right

Sub-function 0x4A: gBorderRect v3 cgc

Register Description
BX standard rectangle structure
CX border type

Draws a border just inside the indicated rectangle. The border type is as for gBorder.

Sub-function 0x4B: gXPrintText v3 cgc

BX: x coordinate of starting point
CX: y coordinate of baseline
DX: (text) string
DI: length of string (maximum 244)
SI: embellishments

Prints the text, as gPrintText in mode 4 (copy with background), but with embellishments:

0 = none
1 = inverted
2 = inverted except the four corners
4 = underlined
8 = inverted and no descenders
9 = inverted except the four corners, and no descenders
12 = underlined and no descenders

Embellishments with "no descenders" stop on the row below the baseline, on the assumption that no characters in the string descend below that point.

Sub-function 0x4C: gInvObloid v3 cgc

BX: address of information block

Inverts all the pixels, except the four corner pixels, of the rectangle specified by the block:

Offset 0 (word): left edge
Offset 2 (word): top edge
Offset 4 (word): width
Offset 6 (word): height

Sub-function 0x4D: wEnablePauseKey v3

Allows the program to be paused by the user by pressing CTRL-S; this is initially turned on. When paused, the window server will not process any requests from the client (they will be held until the pause is released by pressing any key).

Sub-function 0xCE: wDisablePauseKey v3

Disallow the program from being paused by the use of CTRL-S.

Sub-function 0x4F: wsEnable

Turns on the permanent status window. This lies behind any other windows of this client and so, to be seen, all overlaying windows must be resized or moved.

Sub-function 0x50: wsDisable

Turns off the permanent status window.

Sub-function 0x51: wInformOn v3.5

Instructs the window server to send WM_ON events when the client is in the foreground.

Sub-function 0x52: wsUpdate

BX: reason (1 = name, 2 = time)

Updates the contents of the status window to reflect a change elsewhere. A reason of "name" means that the process name has changed; a reason of "time" indicates that the clock format has changed.

Sub-function 0xD3: wsCreateClock fails

AX: -> clock identifier
BX: window
CX: flags
DX: x coordinate
SI: difference in minutes between clock and system time @@@
DI: y coordinate

Creates a clock. See wsCreateClock2, which includes all the functionality of this call together with additional features.

Sub-function 0x54: wsSetClock

BX: clock identifier
CX: difference in minutes between clock and system time

Changes the difference between clock and system time for a clock.

Sub-function 0xD5: wSetBusyMsg

eBX: (cstr) text to be displayed
CX: location and delay:

Bits 0-5: delay in half seconds before displaying
Bit 6: 0 = top, 1 = bottom
Bit 7: 0 = left, 1 = right

Waits for the required time (during which another call can cancel the previous request) and then displays the text, flashing, in the indicated corner; the text remains until replaced or cancelled (by an empty string). Equivalent to the BUSY keyword. The text is limited to 20 characters.

Sub-function 0x56: wsDisableTemp

Disable the display of a temporary status window via the PSION-MENU keypress. This is a system-wide setting and is initially on.

Sub-function 0x57: wsEnableTemp

Enable the display of a temporary status window via the PSION-MENU keypress. This is a system-wide setting and is initially on.

Sub-function 0xD8: wSystem

BX: settings to be changed
CX: new values for settings

Changes settings within the window server (thus affecting all clients). For each bit that is set in BX, the property is set to the corresponding bit in CX. The meanings of the bits are:

Bit @: do not restart the shell (SYS$SHLL) when the window server terminates
Bit @: do not restart the notifier (SYS$NTFY) when the window server terminates (v4 only)
Bit @: attempt to become the notifier process [H4]
Bit @: if the window server is also the notifier, do not report processes which terminate abnormally
Bit @: send task update events to the shell when any process terminates [H4]
Bit @: test battery and display low battery warnings if necessary each time the machine is switched on [H4]
Bit @: report clients that are failing to respond to events [H4]
Bit @: disable low battery indicator in the status window [v4]
Bit @: disable SSD indicators in the status window [v4]
Bit @: disable link indicator in the status window [v4]
Bit @: disable caps lock indicator in the status window [v4]

Those bits marked [H4] apply only to HC machines and version 4 of the server; Series 3t machines will act as if the bit is always set.

Those marked [v4] apply only in version 4. The initial values of all settings are taken from the $WS_FL environment variable.

Sub-function 0xD9: wGetProcessList v3.5

SI: address of a 44 byte buffer

The buffer is filled with a list of all the processes connected to the window server; the list is in front-to-back order, and is terminated by a zero word.

Sub-function 0xDA: wSendCommand v3.5 fails

BX: process
CX: address of the first byte of the data
DX: number of bytes of data (1 to 127)

Sends command data to the specified process. The process will receive a WM_COMMAND event, and should then call wGetCommand.

Sub-function 0xDB: wGetCommand v3.5 fails

SI: address of a 127 byte buffer

Reads the last command data sent by wSendCommand into the buffer. Only one pending command is held.

Sub-function 0x5C: wTextCursor

BX: window
CX: address of text cursor information

Make the text cursor visible if it is not, and move it to the window and location given. The information is:

Offset 0 (word): x coordinate of baseline
Offset 2 (word): y coordinate of left edge
Offset 4 (byte): height of cursor
Offset 5 (byte): distance from baseline to top of cursor
Offset 6 (byte): width
Offset 7 (byte): properties (v4 only)

Bit 0: clear=rectangle, set=rounded
Bit 1: clear=flashing, set=steady
Bit 2: clear=black, set=grey

The distance from baseline to cursor top is 2's complement signed. That is, 0 means the top is the baseline, 1 means it is the pixel above, 255 means the pixel below, and so on.

Sub-function 0xDD: wAppKeyHandler

@@@

Sub-function 0xDE: wInfoMsgCorner

eBX: (cstr) text to be displayed
CX: location:

Bit 6: 0 = top, 1 = bottom
Bit 7: 0 = left, 1 = right

Displays the text in the indicated corner for 2 to 2.5 seconds; an empty string clears any existing text. Equivalent to the GIPRINT keyword. The text is limited to 64 characters.

Sub-function 0x5F:gSetOpenAddress

BX: 0=cancel, 1=direct, 2=indirect long, 3=indirect word
CX: file offset low word ??? it's declared as ULONG
DX: file offset high word ??? it's declared as ULONG

Modifies the next call to any of:

gInitBit
gOpenBit
gOpenFont
gOpenFontIndex
gOpenMouseIcon

to change the place within the file that reading starts; this is used where the font, bitmap, or icon file is embedded in another file. The meaning of BX is:

0: equivalent to BX=1, CX=0, DX=0
1: DX/CX is the starting position within the file
2: DX/CX is the position within the file of a long giving the start point
3: DX/CX is the position within the file of a word giving the start point

Sub-function 0x60: wDrawButton cgc

BX: standard rectangle structure
CX: (cstr) string in button (maximum length 240)
DX: button state (0 = normal, 1 = pressed)
Draws a button containing a string.

Sub-function 0xE1: wSetTaskKey v3.5 fails

BX: keycode
CX: modifier state
DX: modifier mask

Causes the relevant keypresses (see wCaptureKey) to be treated as the "task key". The task key causes the current foreground task to be moved to the back of the list. There can be any number of task keys. On the HC and MC, the TASK key is preassigned as a task key; on the Series 3 SHIFT-SYSTEM is assigned by the shell process.

Sub-function 0xE2: wSetBackTaskKey v3.5 fails

BX: keycode
CX: modifiers
DX: modifier mask

Identical to wSetTaskKey, except that it sets a "reverse task key" which brings the rearmost process to the foreground. On the Series 3 SHIFT-PSION-SYSTEM is preassigned as the reverse task key.

Sub-function 0xE3: wCancelTaskKey v3.5 fails

BX: keycode
CX: modifiers
DX: modifier mask

Cancels a previous call to wSetTaskKey with the same arguments.

Sub-function 0xE4: wCancelBackTaskKey v3.5 fails

BX: keycode
CX: modifiers
DX: modifier mask

Cancels a previous call to wSetBackTaskKey with the same arguments.

Sub-function 0xE5

@@@ SwExt

Sub-function 0xE6: gOpenFontIndex v4 fails

AX: -> font identifier
@@: (cstr) filename
@@: font number within file (0 = first or only font)

Opens the specified font from a multiple-font file.

Sub-function 0xE7: gInitBit v4 fails

AX: -> bitmap file handle
@@: (cstr) filename
@@: address of a word

Opens a file containing one or more bitmaps, ready for gGetBit and gDrawBit. The word pointed to by @@ is set to the number of bitmaps in the file. Using this facility is more efficient than using gOpenBit several times.

Sub-function 0xE8: gGetBit v4 fails

@@: bitmap file handle
@@: bitmap number (0 = first or only)
@@: flags
@@: address of an information block

Loads a bitmap from the file given by the handle (which must have been returned by gInitBit). The other parameters are as for gOpenBit.

@@@@ Manual says returns 0. gOpenBit returns a bitmap identifier!


Sub-function 0xE9: gDrawBit v4 fails cgc

@@: address of point definition block
@@: bitmap file handle
@@: standard rectangle structure
@@: mode (see gFillPattern)
@@: bitmap number (0 = first or only)

Copies a rectangle from a bitmap in a file to the window or bitmap given by the current graphics context. Effectively does gGetBit, gCopyBit, and then wFree on the bitmap, only much more efficiently.


Sub-function 0xEA: gQueryBit v4 fails

@@: bitmap file handle
@@: bitmap number (0 = first or only)
@@: address of 4 byte buffer

The buffer is filled with the size of the specified bitmap:

Offset 0: width
Offset 2: height

Sub-function 0x6B: wsStatusWindow v4

BX: window format (0 = off, 1 = small, 2 = large, 3 = Series 3t)

Sets the format of the status window.

Sub-function 0x6C: wInformOnAll v4

@@: new state (0 = don't send, 1 = send)

Instructs the window server to send or not send WM_ON events.

Sub-function 0xED: wsCreateClock2 v4 fails

AX: -> clock identifier
BX: address of clock information
CX: (cstr) clock format for type 5 clocks, must be 0 for all others

Creates a clock, which will then tick automatically. The clock information has the following form:

Offset 0 (word): window
Offset 2 (word): clock type

0 = Series 3t small digital
1 = Series 3t medium variable (36 x 32 pixels)
2 = Series 3t large analogue (66 x 60 pixels)
3 = Series 3a medium variable (58 x 51 pixels)
4 = Series 3a large analogue (99 x 99 pixels)
5 = Formatted digital (v4 only)
6 = Series 3c/Siena medium variable
7 = Series 3c large analogue

Offset 4 (word): x coordinate of position
Offset 6 (word): y coordinate of position
Offset 8 (word): difference in minutes between clock and system time
Offset 10 (word): flags [apply only to the types in brackets]

Bit 4: display the date [0, 1, 3]
Bit 5: display seconds [0, 2, 3 (analogue), 4]
Bit 6: force analogue [1, 3]
Bit 7: force digital [1, 3]
Bit 8: add AM/PM indicator if system is in 12 hour mode [0, 1]
Bit 9: centre text within space added when bit 8 set [0]
Bit 10: add AM/PM indicator if system is in 12 hour mode [0, 1 (digital)]
Bit 10: @@@ CLOCK_WITH_DATE_EXTRA
Bit 11: use grey plane [0, 1, 2, 5?]
Bit 12: @@@ DBL_PLANE
Bit 13: right align [@@@]
Bit 14: @@@ SUMMER_TIME
Bit 15: enclose in a box [5]

Offset 12 (word): font (type 5 only)
Offset 14 (word): style (type 5 only)

Bit 0: bold
Bit 1: underline
Bit 2: inverse
Bit 3: double height
Bit 4: monospaced

Clock types described as "variable" can be either digital or analogue according to the system settings or additional bits. For type 5 clocks, the format string @@@

Sub-function 0xEE: wSetPriorityControl v4

BX: new state (0 = off, 1 = on)

Sets server-controlled priority handling. When on, the server will change the
priority of a process to 112 when it is in the background or has called
wStartCompute, and 128 when in the foreground. The client must not set its
own priority when this is on.

Sub-function 0xEF: gConfigureFonts v4 fails

AX: -> font group identifier
@@: number of fonts
@@: address of a sequence of information blocks

Creates a font group, which is a set of fonts intended for use in various styles (for example, roman, bold, italic, and bold-italic versions of a basic font would be combined to form a font group). There must be an information block for each font in the group; the blocks are immediately adjacent in memory. Each block has the form:

Offset 0 (word): font
Offset 2 (word): style of this font
Offset 4 (word): style to be applied to this font
Offset 6 (word): vertical adjustment

When using a font group and a style for output, the following process is used. The "best" block is set to the first block. The list of blocks is then scanned in order; whenever a block is found where all the styles in offset 2 are part of the required style and include all the styles in offset 2 of the best block, that block becomes the best block. When all blocks have been scanned, the font in offset 0 of the best block is selected, the styles in offset 2 are removed from those to be used, and then the styles in offset 4 are added. The resulting styles are applied to the font, and the text is moved vertically by the distance given in offset 6.

Sub-function 0xF0: wInquireStatusWindow v4

AX: -> current format (0 = off, 1 = small, 2 = large, 3 = Series 3t)
BX: format of interest (as for AX, or -1 for current format)
SI: address of 8 byte buffer

The buffer is filled in with the coordinates the status window would have if it had the indicated format; the current format is also returned.

The contents of the buffer are:

Offset 0 (word): x coordinate of left edge
Offset 2 (word): y coordinate of top edge
Offset 4 (word): width
Offset 6 (word): height

(When the window is off, it has zero width but full height, at the right hand edge of the screen.)

Sub-function 0xF1: wInquireCompatibility

AX: -> compatibility flag

Returns the state of the Compatibility mode. See wCompatibilityMode for details.


Sub-function 0xF2: gReadFontHeader v4 fails

AX: -> length of header actually read (up to 128)

@@: (cstr) filename
@@: font number within file (0 = first or only font)
@@: address of 128 byte buffer

The font header of the specified font is read into the buffer.

Sub-function 0xF3: gReadFontGroupHeader v4 fails

AX: -> length of header actually read (up to 126)

@@: (cstr) filename
@@: address of 128 byte buffer

The file must be a multiple font file. The number of fonts is placed in the word at offset 0 of the buffer, and the font group header is read into the rest of the buffer.

Sub-function 0xF4: wSetSystemFont v4 fails

@@: system font to be set
@@: font, font group, or internal font identifier
@@: text style (internal fonts only)

Changes the font in use for one of the four standard system fonts.

0 = Series 3a system font
1 = Series 3t compatibility system font
2 = Series 3a internal font
3 = Series 3t compatibility internal font

Sub-function 0xF5: wSetSprite v4 fails

@@: sprite identifier
@@: address of a position structure, or 0 to leave it in the same place
@@: number of bitmap set to change (0 = first set in the sequence)
@@: address of an information block, or 0 if all sets remain unchanged

Moves the sprite, or change a bitmap set, or both. The position structure and information block, if provided, have the same format as for wCreateSprite.


Sub-function 0xF6: wCreateSprite v4 fails

AX: -> sprite identifier

@@: window
@@: address of a position structure
@@: child window behaviour (0=sprite over windows, 1=sprite under windows)
@@: number of bitmap sets in the sprite
@@: address of a sequence of information blocks

Attaches an animated sequence of bitmap sets to a window as a sprite; the sprite will appear in front of everything else in the window. Only one window of a client may have a sprite at any time. The position structure gives the initial position of the sprite:

Offset 0 (word): x coordinate
Offset 2 (word): y coordinate

There must be an information block for each bitmap set in the sequence; the blocks are immediately adjacent in memory. Each block has the form:

Offset 0 (word): bitmap for black pixels to be set
Offset 2 (word): bitmap for black pixels to be cleared
Offset 4 (word): bitmap for black pixels to be inverted
Offset 6 (word): bitmap for grey pixels to be set
Offset 8 (word): bitmap for grey pixels to be cleared
Offset 10 (word): bitmap for grey pixels to be inverted
Offset 12 (word): x coordinate of bitmap position relative to the sprite
Offset 14 (word): y coordinate of bitmap position relative to the sprite
Offset 16 (long): delay in 0.1 seconds before next bitmap set is shown

Any of the bitmaps can be 0 to indicate that there is no such bitmap. All non-zero bitmaps must be the same size.

Sub-function 0xF7: wsSetList v4 fails

BX: number of strings in the new list (or -1 to show an icon)
eCX: an array of cstrs
DX: position in list to be selected (0 = first string, -1 = none)

Sets the "mode", or "diamond" list in the status window. CX should hold the address of an array of words, each of which holds the address of the start of a cstr. If BX is -1, the list is replaced by the application icon; in this case CX and DX are ignored.

Sub-function 0xF8: wsSelectList v4

BX: position in list to be selected (0 = first string, -1 = none)

Sets the position of the diamond in the status window.

Sub-function 0x79: gShadowText v4 cgc

@@: x coordinate of starting point
@@: y coordinate of baseline
@@: address of information block
@@: (text) string
@@: length of string (maximum 234)

Prints the text, ignoring the text mode, but applying shadow and lighting effects according to the information block:

Offset 0 (byte): body colour ) 0 = black, 1 = white
Offset 1 (byte): shadow colour ) 2 = grey, 3 = none
Offset 2 (byte): light colour ) 4 = dark grey, 5 = light grey
Offset 4 (word): link to shadow (0 = disconnected, 1 = connected)
Offset 6 (word): shadow effect width
Offset 8 (word): shadow effect height
Offset 10 (word): lighting effect width
Offset 12 (word): lighting effect height
Offset 14 (word): additional horizontal gap between characters

Sub-function 0x7A: gDrawObject v4 cgc

@@: object type
@@: standard rectangle structure
@@: flags

Draws a special object just inside the specified rectangle. Available object types are:

0 = 3-dimensional box

and the available flags are:

Bit 1: set for 4 pixel corner, clear for 1 or 2 pixel corner
Bit 3: double thickness
Bit 6: set for 1 pixel corner, clear for 2 or 4 pixel corner

Sub-function 0x7B: gBorder2 v4 cgc

@@: 0 = as gBorder, 1 = black/white/grey 3-D effect
@@: border type

Draws a border as gBorder, except that it can also generate a 3-D effect on screens with grey available. @@@ arrows are not documented as available

Sub-function 0x7C: gBorder2Rect v4 cgc

@@: 0 = as gBorderRect, 1 = black/white/grey 3-D effect
@@: standard rectangle structure
@@: border type

Draws a border as gBorderRect, except that it can also generate a 3-D effect on screens with grey available. @@@ arrows are not documented as available

Sub-function 0xFD: wCompatibilityMode

BX: new state (0 = off, 1 = on)
SI: *the same* pointer to a WSERV_SPEC structure as for wConnect @@@@

Changes the compatibility mode state. When the mode is off, drawing is done in the usual way. When it is on, drawing is done in double pixel mode on those machines that support it. The initial state is off.

Sub-function 0x7E AL 0x00: wDrawButton2 v4 cgc

@@: standard rectangle structure
@@: (cstr) string in button (maximum length 240)
@@: button type (0 = Series 3t, 1 = Series 3a)
@@: button state (0 = normal, 1 = pressed, 2 = deeply pressed)
Draws a button containing a string. Series 3a buttons require the window to have a grey plane. Series 3t buttons must not be deeply pressed.

Sub-function 0x7E AL 0x01

@@@ InformInactivity

Sub-function 0x7E AL 0x02: wDisableKeyClick v4

BX: 0 = enable, 1 = disable

Enables or disables key clicks for the current process.

Sub-function 0xFF AL 0x00: gInitMultiSave v4 fails

AX: -> multisave file handle

@@: (cstr) filename
@@: number of bitmaps

Creates a file capable of holding the specified number of bitmaps, for use with gSaveMultiBit and gSaveMultiRect.

Sub-function 0xFF AL 0x01: gSaveMultiBit v4 fails

@@: multisave file handle
@@: bitmap identifier, or zero for the whole screen

Saves the specified bitmap as the next bitmap in the multisave file created by gInitMultiSave. If the save fails, all further saves to the file will also fail (but the file must still be closed with gEndMultiSave).

Sub-function 0xFF AL 0x02: gSaveMultiRect v4 fails

@@: multisave file handle
@@: bitmap identifier, or zero for the whole screen
@@: address of a standard rectangle structure

Saves a rectangle from the specified bitmap as the next bitmap in the multisave file, as for gSaveMultiBit.

Sub-function 0xFF AL 0x03: gEndMultiSave v4 fails

@@: multisave file handle

Closes the multisave file, making it unavailable for further saves.

Sub-function 0xFF AL 0x04: gInquireChecksum v4

@@: bitmap identifier, window identifier, or zero
@@: address of a word

Checksums the specified bitmap and writes the checksum to the word pointed to by @@. A window identifier must be for a window with a background redraw method of 3, in which case its off-screen bitmap is used. Zero for the bitmap causes the entire screen to be checksumed.

Sub-function 0xFF AL 0x05: gCreateFontHeader

@@@@

Sub-function 0xFF AL 0x06: wSupportInfo v4

@@: address of a 32 byte buffer

The buffer is filled in with information about supported features:

Offset 0 (word): flags

Bit 0: set if grey is available
Bit 1: set if Series 3t compatibility mode is available

The remaining flag bits, and the rest of the buffer, is currently set to 0.

@@@@@@@@@

Sub-function 0x@@: wsScreenExt

@@: address of 8 byte buffer

The buffer is filled in with the size of the screen *excluding* the current status window. The format of the buffer is as for wInquireStatusWindow, which should be used for preference.

Function 0xD6

Sub-function 0x00: wConnect

Used to connect to the window server. All OPL programs, and all programs using the console device CON: are connected automatically and must not use this call.

Sub-function 0x01: gPlayback

@@: @@@@
@@@

Sub-function 0x02: gCloseMetafile

@@: @@@@
@@@

Sub-function 0x03: gRecordToMetafile

@@: @@@@
@@: @@@@
@@: @@@@
@@@

Sub-function 0x04: wFlush

Sends any buffered commands to the server.

Sub-function 0x05: wCloseDown

@@@

Sub-function 0x06: wSelect

@@: @@@@
@@@

Sub-function 0x07: wPanic

@@: @@@@
@@@

Sub-function 0x08: wGetEvent

@@: address of a 16 byte buffer
@@@@ This is async. How does the sync version work ? Is it vsync ?

This call may be made synchronously or asynchronously. If made synchronously, it waits until the window server sends an event to the process, and then copies the event into the buffer. If called asynchronously, it writes the value -46 into the word at offset 0 of the buffer and returns; when an event is sent from the window server, it is written to the buffer and the I/O semaphore is signalled. Further information about events is given below.

Sub-function 0x09: wDisconnect

Disconnects from the window server and frees all associated resources. All programs are automatically disconnected upon exit, so this call is generally not used by the programmer.

Sub-function 0x0A: wCheckPoint fails

Sends any buffered commands to the server (as wFlush) and reports any errors immediately (see wDisableLeaves).

Sub-function 0x0B: gTextWidth fails

AX: -> width in pixels
DX: font or font group
SI: style adjustments
DI: (text) string
CX: length of string

Returns the width in pixels of the specified string when displayed in the specified font and style adjustments. The latter are:

Bit 0: bold
Bit 1: underline
Bit 2: inverse
Bit 3: double height
Bit 4: monospaced
Bit 5: italic
Bit 8: subscript
Bit 9: superscript

Sub-function 0x0C: gFontInfo fails

DX: font or font group
CX: style adjustments (see gTextWidth)
DI: address of 32 byte buffer

Fills the buffer with information about the font modified by the style:

Offset 0 (word): minimum character code
Offset 2 (word): maximum character code
Offset 4 (word): height (affected by style)
Offset 6 (word): ascent (affected by style)
Offset 8 (word): descent (affected by style)
Offset 10 (word): width of a digit (affected by style)
Offset 12 (word): width of widest common character (affected by style)
Offset 14 (word): flags:

Bit 0: contains standard ASCII
Bit 1: contains IBM code page 850
Bit 2: looks bold
Bit 3: looks italic
Bit 4: has serifs
Bit 5: monospaced
Bit 6: has a "hang table" @@@@

Offset 16 to 31: name

The widest common character is usually an M or W, and is not necessarily the widest character in the font.

Sub-function 0x0D: wDisableLeaves

AX: -> previous value of the flag
@@: error handling flag

Sets the error handling mechanism used by the window server calls. If the flag is zero, then an error in a command calls the "leave" operation. If it is non-zero, calls that can fail return an error number in AX. The initial setting is zero; OPL programs should always make it non-zero.

Sub-function 0x0E: gCheckBitmapID v3 fails

@@: bitmap identifier

Succeeds (returning 0) if the bitmap identifier is valid. Fails otherwise.

Sub-function 0x0F

@@@ Alert

Sub-function 0x10

@@@ AlertCancel

Sub-function 0x11: gTextCount fails

AX: -> number of characters
DX: font or font group
SI: style adjustments (see gTextWidth)
DI: (text) string
CX: length of string
@@: address of a word holding the available width

AX is set to the length of the longest initial substring that will fit in the number of pixels stored in the word pointed to by @@ when displayed in the specified font and style adjustments (see gTextWidth). The word is altered to hold the number of pixels that would be left over.

Sub-function 0x12: gGetWidthTable fails

DX: font or font group
SI: style adjustments (see gTextWidth)
DI: address of a buffer

Fills the buffer with the widths of each character in the font as adjusted. The first byte of the buffer corresponds to the minimum character code, and the last byte to the maximum character code (see gFontInfo).

Sub-function 0x13: wGetEventSpecial v4

@@: address of a 16 byte buffer
@@: event type mask

Starts looking asynchronously for an event as wGetEvent, but only accepts events of specific types. @@@ what happens to the rest ? @@@ based on the event type mask:

Bit 0: key and task key events
Bit 1: redraw events
Bit 2: foreground, background, and power on events
Bit 3: mouse and rubber band events
Bit 4: all other events
Bit 15: escape events

Calling wGetEvent is equivalent to calling this function with a mask of 0x1F. Escape events are sent only if key events are not selected; in this case, if the ESC key is pressed, all pending keystrokes are thrown away and the client is sent an escape event.

Sub-function 0x14: wGetEventUpdate v4

@@: event type mask

If there is an asynchronous call to wGetEvent or wGetEventSpecial outstanding, it changes the mask specifying the events being looked for. If no call is outstanding, it has no effect.

EPOC16 Environment Variables

EPOC16 always places a dollar sign ($) in the names of the environment variable it uses. Other applications should use names without a dollar sign in them.

Psion issues environment variable name prefixes to registered developers; these prefixes will contain dollar signs, but names based on them should have no further dollar signs.

The following environment variables are known.

$WS_FL

initial value of the window server settings (changeable using the wSystem call). Only applies to window server version 4.

Offset Length Description
0 2 Initial settings

$WS_FNTS

fonts used by the window server (version 4):

Offset Length Description
0 2 general system purposes
2 2 notifer and alerts
4 2 status window
6 2 special font holding the diamond symbol
8 2 medium digital clock
10 2 medium date
12 2 notifier/alert buttons
14 2 small status window clock

$WS_PW

Owner information: up to 218 bytes:

Offset Length Description
3 1 length of first line
4 1 offset of start of first line (always 18)
7 1 length of second line
8 1 offset of start of second line
11 1 length of third line
12 1 offset of start of third line
15 1 length of fourth line
16 1 offset of start of fourth line
18   Text of the information

The remaining bytes appear to be zero, except 2,6,10,14, which are 0x6. Why?

C$P#

parameters used by Link. [Workabout only]

C$P$

Offset Length Description
0 1 setting (0 = standard, 1 = special)

current keyboard setting. [Workabout only]

C$P@

current drive last time the command processor was exited. [Workabout only]

Offset Length Description
0 1 drive letter (e.g. $4D or %M for the internal drive)

C$PA

current path on drive A last time the command processor was exited. [Workabout only]

Offset Length Description
0 cstr Current path

If the variable is unset, then the path is the root directory. Variables C$PB to C$PZ can also exist.

D$X

Alleged to be something to do with dialling settings

EM$

Full pathname of the 8087 emulator software.

Offset Length Description
0 cstr Path name

P$D

Printer device.

Offset Length Description
0 1 48 = print device is a parallel port
49 = print device is a serial port
50 = print device is a file

P$F

Print to file name: up to 128 bytes:

Offset Length Description
0 cstr Last file used for printing to file

P$M

Printer driver: up to 129 bytes.

Offset Length Description
0 1 printer driver model number
1 cstr Printer driver library

A printer driver library can support several similar printers; the model number specifies which is selected.

P$S

Serial port setup: 12 bytes.

Unknown, but includes fields called tbaud, rbaud, frame, parity, hand, xoff, xon, flags, tmask, something called P_SRCHAR format

S$SVER

System screen version number. [Workabout only]

Offset Length Description
0 cstr Version number as text

WP$SPEL

Used by the word processor (in some way when constructing its menus, probably to indicate that the spell checker is available.)

WP$THES

Used by the word processor (in some way when constructing its menus, probably to indicate that the thesaurus is available.)

SIBO ASICs

ASIC stands for Application Specific Integrated Circuit. These devices are widely used within Psion hardware. Some are well documented, others barely mentioned in anything but internal documentation. This is a list of ASICs specific to the SIBO range.

ASIC1

ASIC1 is the main system controller chip for the SIBO architecture. It connects directly to the 8086-based processor (i.e. the V30H) controlling all bus cycles to and from the processor. This configuration effectively forms a micro-controller like device that executes 8086 instruction codes. ASIC1 is made up of a number of functional blocks including a bus controller, a programmable timer, an eight input interrupt controller, an LCD controller and the memory decoding circuitry.

ASIC2

ASIC2 is the peripheral controller chip for the SIBO architecture. It contains the system clock oscillator and controls switching between the standby and operating states. ASIC2 provides an interface to the power supply, keyboard, buzzer and SSDs. ASIC2 includes the eight-channel SIBO Serial Protocol controller and provides interface circuitry to both the reduced external and extended internal peripheral expansion ports.

ASIC3

Power IC, specific to the MC range. Used for charging NiCd power packs.

ASIC4

ASIC4 is a serial protocol slave IC for addressing memory and general memory-mapped peripherals. It is used in SSDs to convert SIBO serial protocol signals into addresses within the memory range of the memory pack. ASIC4 was designed to be a cut-down version of ASIC5 which was the original SIBO serial protocol slave chip.

ASIC5

ASIC5 is a general purpose I/O chip with a built-in UART that can be set to run in a number of different modes thereby simplifying the task of peripheral design. For example, it is possible to set up ASIC5 to run as a Centronics parallel port interface, an 8-bit parallel I/O port, a serial bar code controller or a serial RS232 converter.

ASIC6

The first of the three publicly-undocumented ASICs.

Known internally as 'the voice ASIC,' ASIC6 is the support chip for use with the TMS320C10 DSP. It is primarily controlled via an MC serial channel with minor control from the DSP. The ASIC contains an extremely limited version of an ASIC5 in Pack mode, allowing access to the on board ROM and RAM by the MC. The DSP is unable to access the ROM, the RAM is the main system memory. Access to the RAM by the MC is non-standard as it is arranged in words of two bytes. There is a second serial interface for talking to the combo, the SLD bus.

ASIC7

The second publicly-undocumented ASIC. Additional glue logic for the MC range.

ASIC8

The final publicly-undocumented ASIC. So far we have very little information about ASIC8, but we believe that it was meant to be a peripheral chip combining features from ASIC4 and ASIC5.

ASIC9

ASIC9 is a composite chip comprising of a V30H processor, ASIC1, ASIC2 and general I/O and PSU control logic all on one IC. ASIC9 thus integrates all the digital logic required to produce a SIBO architecture computer less the memory onto one chip. ASIC9 has a few additional features such as an extra free-running clock (FRC) and a codec interface for sound.

SIBO-SP Slave IDs

 

"Select" is kind of a misnomer, because in actual fact it's a question. The SIBO/EPOC16 device has a list of device IDs it knows how to speak to. Although these device IDs refer to specific ASICs and their modes, it's also possible to think of an ID as an ASIC's "language", For example, ASIC4 can "pretend" to be ASIC5 in Pack Mode. More on this later.

This SSel packet contains an ID number. This ID number refers to one of a number of different ASIC chips that could be in a slave device. Here's a list of the device IDs we've found so far and the devices they refer to.

ID Name
1 ASIC2 Slave
2 ASIC5 Pack Mode
3 ASIC5 Peripheral Mode (“ASIC5 Normal” in OSSIBO.INC)
4 ASIC6 (undocumented, mentioned only in OSSIBO.INC)
5 ASIC8 (undocumented, mentioned only in OSSIBO.INC)
6 ASIC4
31 Unknown (undocumented, detected on Workabout)
48 Unknown (undocumented, detected on Workabout and Workabout mx)
56 Unknown (undocumented, detected on Workabout mx)

Each SIBO/EPOC16 device has a list of IDs it can speak to. When a SIBO-SP port is initialised, the SIBO machine first sends a "Reset All" command. This tells all slaves to stop what they're doing and listen for a SSel packet. Then, the SIBO/EPOC16 device goes through its list of IDs, starting from the top. It asks the slave, "Do you speak ID:x?". If there's no reply, it goes to the next ID on the list until it gets a reply or runs out of IDs.

The list of IDs is different for SIBO Serial Ports and SSD ports. This makes sense - the types of device that could be connected to a SIBO Serial Port are different to what would be put in an SSD port. However, the different types of SSel IDs that each device sends  are interesting.

This is a list of SIBO devices with the IDs they send out on each port. Anything marked "unknown" is because I haven't been able to test it yet (I don't own an MC200 or Workabout 1MB and I don't have the right connectors for the MC or Workabout ranges).

Model SIBO Port SSD Port
MC200 Unknown Unknown
MC400 Unknown 2, 1
Series 3 3, 5 2, 1
Series 3a 3, 5, 6, 2, 6 6, 2
Series 3c N/A 6, 2, 3
Series 3mx N/A 6, 2, 3
Workabout 48, 6, 2, 3 Unknown
Workabout mx 31 (pause) 6, 3, 2, 5 (pause) 3, 5, 6, 2 48, 6, 2, 3 1

1 Wmx also sends ID:56 at boot on the SSD port whether the door is open or closed.

What's interesting is that for every SSD port I could test, it asks for at least one ASIC that can handle some sort of peripheral, all the way back to the MC400, possibly even further. Although I don't know this for certain, I assume an ASIC2 in Slave Mode was a precursor to the ASIC4 in Extended Mixed Mode.

SSD Pins

Facing pins, front of SSD upwards.

Pin Name Description Characteristics
1 CLK SIBO-SP Clock TTL 5V logic
2 GND Ground  
3 VBACKUP Backup power for RAM modules +3.75VDC, always on
4 VPP Used for programming Flash SSDs +15VDC to +18VDC,
drops to +9V on power off. Unregulated
5 VCC Main power +5VDC, stops on power off
6 DATA SIBO-SP bidirectional data TTL 5V logic

 

EPOC16 Processes and Their Properties

EPOC16 is a preemptive multitasking operating system; at any time it can be running any number of processes (up to some limit). Much useful information about processes can be displayed with the SPY program.

Each process has a name, a task number, and a process ID. The task number runs from 1 upwards (the Series 3 is limited to 24), and a task number can be reused whenever a process terminates. The process ID consists of the address of the control block for the process in kernel memory in the bottom 12 bits, and a simple counter in the top 4 bits; this starts at 0 for the first process to use this control block, and is incremented whenever the block is reused.

The name of a process is normally the name of the program (1 to 8 characters), followed by .$ (or .@ for subtasks), and the task number as 2 decimal digits. The code for a process is placed in a segment called by the name of the program followed by .SC. Thus it is not possible to run two programs with the same name at the same time.

Each process has a priority. Non-operating system processes are limited to priority 192; the normal priorities are 128 for foreground and 112 for background. Only the highest priority process(es) able to run will do so; all lower priority ones will wait.

System processes

There are two kinds of system processes: fixed ones and optional ones. The fixed processes are:

Process Name Description
SYS$NULL.$01 handles power off
SYS$MANG.$02 the process and resource manager
SYS$FSRV.$03 the file server
SYS$WSRC.$04 the window server
SYS$SHLL.$05 the process launcher and system screen
TIME.$06 the time and alarm server

The optional processes are:

Process Name Description
SYS$NCP.$??  the remote link manager

Registers

Processes may use the data registers (AX, BX, CX, DX, SI, and DI) without restriction. The kernel may move memory segments about in memory at any time without warning; when it does so, those of the segment registers (CS, DS, ES, and SS) that appear to the kernel to be valid will be adjusted automatically. If it is desired to change these registers at any other time, it should therefore be done with interrupts disabled.

OPL uses CS, DS, and SS, and these should not be altered by assembler code invoked from with OPL. ES is not used by the OPL interpreter, and is normally left the same as DS and SS (which are always the same). Many system calls use data registers to hold pointers; a segment register is also used with each such pointer. The Psionics files SYSCALLS.n indicate when an address is using ES; they do not distinguish DS and SS. Any assembler code called from OPL should exit with ES equal to DS.

The only other values that can usefully be placed in ES are the kernel data segment (using system call GenDataSegment), and segments created with the system call SegCreate. To do the former, just invoke INT $8F; ES will then point to the kernel data segment, and accesses via ES will behave just as if done with the system call GenGetOsData (it is not possible to write in this way). The latter is done as follows:

; Assume the segment handle is in BX.
INT $8F
MOV ES,ES:[BX]
; ES now points to the start of the segment.
; If the segment moves, ES will change automatically.
; Before returning to OPL:
CLI ; with interrupts disabled
PUSH DS ; copy DS to ES
POP ES
STI ; and allow interrupts again

Memory

Each process has a single segment of memory. From zero upwards, this contains:

The heap is divided into allocated and free cells. The SPY program shows the number and total byte count of each kind of cell. The kernel will remove free cells from the end of the heap when it needs space.

The stack is initialized to all 0xFF; it must always hold at least 256 bytes to allow interrupts to be processed (otherwise panic 69 will occur). A typical stack size is 0xA00. The SPY program allows the unused portion of the stack to be refilled with 0xFF (to allow the high water mark to be reset).

The heap consists of consecutive cells:

Offset Length Description
0 2 length of data portion (L)
2 L+1

data portion (whose address is returned by allocators)

@Is that right, or is it 2 to L-1 ?@

 Cells are always aligned to even addresses, and for this and other reasons may be larger than requested.

Specific memory locations

The following table lists some specific use of memory locations.

Offset Length Description
0 2 Initialized to 0xDEAD; should never change
2 4 Used by the kernel
6 2 handle of the segment holding the fold tables @@
8 8 used by the object oriented programming system
16 2 used by the kernel
18 2 address of block <P18>
20 2 handle of the application manager object
22 4 used by the window server
26 4 used by the OPL runtime system
30 2 used by the debugger
32 1 zero when address trapping is turned off (do not alter)
33 1 non-zero when the kernel is modifying the heap
34 2

address of cstr holding the program name; used to determine which list on the system screen a process appears in

@if this word is zero, the process will not be sent X messages)

36 2

address of a heap cell containing a cstr holding the full path name of the program being executed, followed by a qstr holding the program information (see system call FilExecute).

38 2

not used by the kernel or OPL; used by the debugger

40 14

not used by the kernel or OPL

54 2

address of current dialog structure

56 2

@@ DatGate object handle

58 2

non-zero if locked (by OPL "LOCK ON" or equivalent)

60 2

address of cstr to appear in the status window

62 2

address of cstr holding current file being processed

64  

maximum limit of stack (if floating point emulation is in use, the emulator uses offsets 64 to 767)

 

Certain of these memory locations have names in the system documentation:

34 DatProcessNamePtr
36 DatCommandPtr
40 DatApp1
42 DatApp2
44 DatApp3
46 DatApp4
48 DatApp5
50 DatApp6
52 DatApp7
58 DatLocked
60 DatStatusNamePtr
62 DatUsedPathNamePtr

@Location winHandle is the channel number of the console device.

Block <P18> has the following contents:
@this is a "wserv" object@
Offset 32 (word): address of block <P18P32>

Block <P18P32> has the following contents:
Offset 12 (word): address of block <P18P32P12>

Block <P18P32P12> is created by the MINIT keyword and destroyed by the MENU keyword. Outside this range, the block is invalid, and the pointer in the <P18P32> block is invalid. Each MCARD keyword can move this block, thus altering that pointer. The block has the following contents:

Offset Length Description
0 1 number of MCARD calls so far
1   menu information blocks, in order of menu creation

Each menu information block has the following contents:

Offset Length Description
0 2 address of secondary menu information block
2 cstr Menu title

Each secondary menu information block has the following contents:

Offset Length Description
0 4 [Only ever seen 0x7392A1DF]
4 2 number of items in the menu
6 4 [Only ever seen 1 so far]
10 2 address of item table

Each item table has the following contents:

Offset Length Description
0 1 number of items in the menu
1   item information blocks, in order of item

Each item information block has the following contents:

Offset Length Description
0 1 number of bytes in the block, excluding this one
1 1 Psion+ accelerator code (lowercased)
2 cstr item text

Time process

The pending alarms can be located in the memory of the Time process. At some location between offset $0A00 and $0AFF is a block with the form:

Offset Length Description
0 4 0x08040201
4 4 0x00402010
8 4 Unknown (missing from Psionics files)
12 4 first alarm control block

It is reported that on the Series 3c this has moved to somewhere between 0x0C00 and 0x0CFF. It is also reported that on some versions the control block is at offset 10 or 15.

The alarm control blocks are in a circular list, with the last pointing to offset 12 (or 10 or 15) of the above block (which is not an alarm control block); if that location points to itself, there are no alarms. Each block has the form:

Offset Length Description
0 2 next alarm control block
2 2 reported that this is the second next alarm control block
4 2 Unknown (was missing from original Psionics File)
6 2 process ID of process owning alarm
8 1

0 = clock alarm

1 = has time and date

2 = has date

10 4

abstime alarm expires

14 4

abstime displayed in alarm message

18 10 qstr

name of alarm sound

28 66 cstr

text displayed in alarm message

93 163

[unknown; alleged to be part of the block]

The built-in alarm sounds have names consisting of a single byte (thus offset 18 is 1 and offset 19 holds the name):

1=rings, 2=chimes, and 16=silence.

@System screen or Window Server (which?) places info about 14 application
buttons at DatApp1.@

EPOC16 Locale Codes

Psion allocated a number for each locale. This number is often used as part of a file name; for example, the ROM:: filing system contains files whose last two digits are the number of the locale they are for. This document lists the known codes:

Code Locale
00 Testing
01 English - UK
02 French - France
03 German - Germany
04 Spanish
05 Italian
06 Swedish
07 Danish
08 Norwegian
09 Finnish
10 English - USA
11 French - Switzerland
12 German - Switzerland
13 Portuguese
14 Turkish
15 Icelandic
16 Russian
17 Hungarian
18 Dutch
19 Flemish
20 English - Australia
21 English - New Zealand
22 German - Austria
23 French - Belgium