home *** CD-ROM | disk | FTP | other *** search
- NAME
- RISCOS::SWI -- perl interface to SWI calls
-
- SYNOPSIS
- use RISCOS::SWI;
- $number = RISCOS::SWI::swix ('OS_SWINumberFromString', regmask([1]), $name);
- @regs = unpack 'I10', kernelswi ('OS_File', 5, $filename);
-
-
- DESCRIPTION
- This module provides a SWI interface for perl. There are two
- alternative interfaces supported - kernelswi and swi/swix. Both
- take the SWI to call as the first parameter, which can be
- specified by name or number. Although calling a SWI by name
- makes for highly readable code, the name lookup itself often
- takes longer than the actual SWI, so for production code it is
- wise to perform the name lookup once at initialisation using
- `SWINumberFromString' and cache the number in a variable.
-
- `kernelswi' and `swix' both automatically call the `X' (error
- returning) version of the SWI, return undefined on error and
- copy the error block number and message to `$^E'. `swi' calls
- `swix', but will terminate the script with the error number and
- message if an error occurs.
-
- For both interfaces registers are initialised from perl
- variables according to the following rules:
-
- the undefined value is passed as zero
-
- "numbers" are passed as integers
-
- "strings" are passed as pointers to the strings - perl automatically adds
- a `"\0"' at the end to create null terminated strings.
- Overwriting the contents alters the variable's value - it is
- up to the script to ensure that the perl scalar value is
- made long enough before calling the SWI. Note also that
- string constants are treated as read only so attempting to
- call
-
- $number = RISCOS::SWI::swix ('OS_SWINumberFromString', regmask([1]),
- 'OS_SWINumberFromString');
-
-
- would cause a fatal runtime error.
-
-
- "strings" and "numbers" are in quotes because the internals rely
- on perl's flags to determine whether a scalar is a number or
- string. The trouble comes when perl has been implicitly
- converting between the two and thinks that the result of `6*7'
- is `"42"', which it will try to pass in as a pointer to a
- string. The work around is to add zero to parameters that must
- be numeric, and concatenate `''' to parameters that are strings:
-
- $number += 0;
-
- $string = "0"; # This may be interpreted as the number zero
- kernelswi ($swi, 0, $string . '') # Not now.
-
-
- The latter is, to quote Paul Moore, "fairly obscure magic
- (deliberately invalidating the flag which says that the string
- has a valid numeric value, and then using the string before perl
- has a chance to notice that the numeric value is still OK), but
- works fine."
-
- The two interfaces are both built into the perl binary and so
- are always available, with or without this module. They differ
- in the method of passing in and returning results from
- registers.
-
- kernelswi <name>|<number>, [<R0 value>, [<R1 value], ...
- is similar to the C library function of the same name. It
- takes as parameters the SWI to call and optionally up to 10
- more values assigned to `R0' - `R9' in order. Unassigned
- registers have undefined values (not zero, unlike `BASIC').
- If the SWI generates an error then undefined is returned,
- and `$^E' is set to the error number and message from the
- error block (*c.f.* `$!'). If there is no error then
- `kernelswi' returning a single scalar block of length 40,
- the packed return results from `R0' - `R9'. For example,
- these may be converted to an array of integers with code of
- the form
-
- @regs = unpack 'I10', $kernelswi_result;
-
-
- swix <name>|<number>, [<mask>, [<value> ...
- is similar to the alternative C veneer written by Edward
- Nevill and Jonathan Roach and supplied with Acorn C versions
- 4 and later.
-
- Like `kernelswi', swix returns undefined and sets `$^E' if
- an error is generated. If there is no error, swix returns
- the contents of `R0'
-
- *mask* is a bitmask that describes the interpretation to
- place on the remaining parameters. If it is omitted it is
- treated as zero (no parameters). Otherwise it is best
- generated by the `regmask' function. *mask* must be numeric
- - string values are reserved and cause a fatal error at
- runtime.
-
- regmask <in>, [<out>, [<block>]]
- *in* and *out* are references to arrays of register
- numbers to respectively pass into and out from the SWI.
- If either is undefined it is treated as an empty array.
- Registers 0 to 9 can be passed in, 0 to 9 and 15
- returned.
-
- If present, *block* is the number of register to set up
- to point to any remaining parameters "left over". This
- provides a convenient way of generating parameter blocks
- for SWIs such as `Wimp_CreateWindow'.
-
-
- values follow in register number order - first values to
- pass in, then scalars in which the value of registers out
- are returned. The script must ensure that these scalars are
- at least 4 bytes long, as the assembler `swix' veneer makes
- no checks.
-
- Although this interface seems considerably more complex than
- `kernelswi', it does allow much greater flexibility in
- exactly which registers are wanted.
-
- Integer results can be retrieved with code such as
-
- unpack('i', $len)
-
-
- string results by dereferencing pointers
-
- unpack('p', $addr)
-
-
- swi calls `swix', returning `R0 + 0' to ensure a number, or `die's
- with the numeric and string values of `$^E' if there was an
- error.
-
-
- `RISCOS::SWI' also provides conversion functions between SWI
- names and numbers, and symbolic constants for the 4 ARM flags
- and the OS 'X' bit.
-
- V_Flag
-
- C_Flag
-
- Z_Flag
-
- N_Flag
- return the bit corresponding to the position of flag in the
- `PC/PSR'.
-
- XOS_Bit
- returns 0x20000 - which when set marks the error returning
- form of a SWI.
-
- SWINumberToString <SWI number>
- converts a SWI number to a name using the SWI
- `OS_SWINumberToString'. Returns the name of the SWI, or
- undefined if there was an error. Unknown SWI numbers which
- the SWI `OS_SWINumberToString' converts to '`User'' or
- '`XUser'' are returned as '`User (&C00FEE)'' or '`XUser
- (&0B100D)''.
-
- SWINumberFromString <SWI name>
- provides a full inverse to `SWINumberToString'. "User" SWIs
- described above are recognised, as are `OS_WriteI' variants.
- Other SWIs numbers are converted using the SWI
- `OS_SWINumberFromString'.
-
-
- BUGS
- `swix' doesn't automatically ensure that scalars for return
- values exist and are long enough. Additionally the current mask
- system doesn't allow the script to specify whether it wants a
- number, string or fixed length block to be returned, and let the
- perl internals convert and assign the return values
- automatically. String "masks" are reserved for this purpose.
-
- AUTHOR
- Nicholas Clark <nick@unfortu.net>, based on the previous perl
- ports.
-
- The `swi' interface is `syscall' from the perl 5.001 port. The
- `kernelswi' interface is `syscall' from the perl 3 port.
-
-