Author: | C J Bazley (for APDL) |
---|---|
Date: | 18 Oct 2017 |
Revision: | 8 |
The WimpBasic module provides SWIs for initialising WimpBasic programs and dynamically linking them with a run-time library, which it contains. These SWIs are used by the 'wblinker' program that is automatically included inside every application created using the WimpBasic desktop development environment.
The run-time library and module code have been re-compiled to be 32-bit compatible, using RISCOS Ltd's generic shared C library stubs to avoid onerous external dependencies.
On a 32-bit versions of RISC OS, the SWIs
WimpBasic_Stubs
and WimpBasic_Link
will
now return an error if they are unable to synthesise a branch
instruction because the target address is too far.
WimpBasic_Stubs
has been extended with
additional flags to generate a 'trampoline' that consists of
load-PC instructions
rather than PC-relative
branch instructions. This allows any 32 bit address to be
reached but requires an additional client-supplied buffer to
hold a table of function addresses. Also a trampoline may now
be generated for a non- optimised program (for use with
WimpBasic_Link
).
The SWI
WimpBasic_Info
has been extended to allow clients to
determine the buffer size required for
WimpBasic_Stubs
so that all library functions are
included in the trampoline.
WimpBasic_Link
has been extended with an
additional flag to make it link a program with a
client-supplied trampoline rather than directly to the
relevant library functions (for 32 bit compatibility).
An error will be returned on finalisation (thus refusing to
die) if any programs are believed to be linked with the
module. This safety mechanism had been disabled for unknown
reasons in the last public release of the module (version
2.09, 21 Jul 1999) and possibly other versions. A loophole
has been closed where the client count was not incremented
for optimised programs linked using
WimpBasic_Stubs
. For completeness, the planned SWI
WimpBasic_OkToDie
has been implemented.
Errors from SWIs are
now looked up in a messages file that is compiled into the
module binary and registered with ResourceFS on
initialisation of the module. A service call handler has been
added to re-register this file if ResourceFS is restarted.
The default messages can be overridden by setting system
variable WimpBasic$Path
to point to a directory
containing an alternative file 'Messages'.
Error numbers are now unique and taken from an officially-allocated block (previous versions of the module used '0' for all errors). The standard error number &1E6 and 'BadSWI' message are now used for unrecognised SWI numbers.
Upon initialisation, the WimpBasic module will now check for
the CallASWI module, if running on a version of
RISC OS earlier than 3.7. If it is not present then
it attempts to load it from System$Path
. If it
cannot be loaded then the WimpBasic module refuses to
initialise. (Version 2.10 also relied upon SWI &71 but this dependency
was not enforced.)
Fixed overzealous detection of branch-out-of-range errors during link; had been faulting branches from 'positive' to 'negative' addresses (when treated as signed 2's complement) and vice-versa.
Fixed a longstanding bug where the DrawAction
command would erroneously set GCOL actions in the range 69-82
(patterns) instead of correctly mapping Store
,
And
, AndNot
etc. to the basic
logical plot actions (0-7).
Fixed a longstanding bug where the built-in
FileTypeNumber
function didn't work because the wrong
address was passed to
SWI OS_FSControl 31
.
Changed the implementation of the Cls
command
when output is directed to a window; although the queue of
pending graphics commands is still flushed, commands are then
added to reinstate the prevailing draw action, colours
(foreground, background & font), draw mode (filled or
outline), graphics origin, text font and size. The graphics
cursor will be reset to 0,0.
This fixes a longstanding problem where the
Background
command was effectively useless unless
output was direct to screen (because it only affects the
colour to be used by the next Cls
).
The Cls
command now frees any memory claimed for
a queue of pending graphics commands as well as flushing it
(previously, memory usage could only grow and never shrink).
Fixed longstanding bugs in Cls
and
Origin
commands which caused an arbitrary word of
memory in the heap to be corrupted if output was being cached
for the printer.
The Font
command no longer updates the current
font when graphics output is instead being cached for printer
or window. Also it no longer marks a huge area of the output
window (±10000 from the graphics origin) as requiring
redraw on the next Refresh
or
Update
command.
Fixed a longstanding bug in the Circle
command,
which had been ignoring the graphics origin (as set by
Origin
) when output was directed to the screen.
Fixed a longstanding bug in the Point By
command, which had been modifying the supplied coordinates
according to the current Origin
(whereas they
are relative to the last graphics cursor position).
Fixed a bug in the Rectangle
... To
command (to copy or move an area) when the source rectangle
was specified by only three parameters. However current
versions of the compiler cannot yet cope with this syntax.
Fixed a longstanding bug in the Plot
command,
which was modifying the supplied coordinates according to the
current Origin
regardless of whether the action
code indicated relative or absolute coordinates. The
coordinates are no longer modified unless bit 4 of the code
is set.
Executing Refresh
or Update
commands whilst output is directed to a window that is closed
will no longer cause 'Illegal window handle' errors.
Fixed a memory leak when a window to which graphics output had been redirected was closed and then subsequently re-opened. The queue of pending graphics commands was not deallocated; this now happens when the window is closed.
When outputting to screen a DrawAction
command
will now immediately enforce the new plot action whilst
keeping the current graphics foreground colour (previously it
didn't take effect until the next Foreground
or
Background
command). This is consistent with
output to a window or printer.
The DrawAction
command no longer affects the
background graphics colour (used on Cls
), only
the foreground colour.
Fixed a longstanding bug with output to a window or printer,
where a DrawAction
command would reset the
graphics foreground colour to the last colour set (even if
that was a Background
command). Also, a cached
DrawAction
command could result in an
indeterminate foreground colour being set, if executed prior
to the first Background
or
Foreground
command.
Restored expected layout of the client program's static data (had changed in version 2.14), for compatibility with earlier versions of 'WBlinker'.
Fixed bugs where client programs with no sprites file caused illegal reads from zero page in memory. If those memory accesses did not cause a data abort then they typically resulted in the program claiming an excessive amount of memory.
Initialises a program and links it with the WimpBasic run-time library.
R0 = |
flags
|
||||
R1 = | pointer to program's static data | ||||
R2 = | pointer to start of program | ||||
R3 = | size of program (in bytes) | ||||
R4 = | pointer to trampoline (if flags bit 1 set) |
R0 - R4 preserved
Interrupt status is unchanged
Processor is in SVC mode
SWI is not re-entrant
This call initialises a non-optimised WimpBasic program and links it to the run-time library by synthesising PC-relative branch instructions where appropriate. Originally these were direct branches to library code but a trampoline may now alternatively be used.
On a 32 bit OS this SWI should be called with flags bit 1 set and R4 pointing to a trampoline via which to access the library; otherwise an error will be returned if a library function is out of range (branch instructions only have a range of ±32 MB). The same error will result if the trampoline is too far from the program code.
Unless flags bit 0 is set then the program's static data pointer is copied from &8000 to &8004 and its stack pointer is copied from &813C to &8000 (to support versions of WimpBasic older than 1.4).
If no error occurs then an internal count of the number of programs linked with the WimpBasic run-time library is incremented.
Before version 2.10 of the module any non-zero value of R0 was interpreted as though only bit 0 was set (because R0 was not originally envisaged as a bit field). In practice only values 0 and 1 were used.
WimpBasic_DeLink
WimpBasic_Stubs
WimpBasic_OkToDie
De-registers a program from the WimpBasic module.
All registers undefined
All registers preserved
Interrupt status is unchanged
Processor is in SVC mode
SWI is not re-entrant
This call decrements an internal count of the number of programs linked with the WimpBasic run-time library. The counter is prevented from going negative, although this should never occur with correctly written programs.
Typically this
SWI should be called in the exit handler of a
program that has previously registered with the module
using SWI
WimpBasic_Link
(or WimpBasic_Stubs
with flags bit 1 clear).
WimpBasic_Link
WimpBasic_Stubs
WimpBasic_OkToDie
Creates a trampoline via which to access WimpBasic library functions.
R0 = |
flags
|
||||
R1 = | pointer to buffer for trampoline | ||||
R2 = | pointer to buffer for address table (if flags bit 0 set) |
R0 - R2 preserved
Interrupt status is unchanged
Processor is in SVC mode
SWI is not re-entrant
This call initialises a trampoline (and optionally an
address table) via which a WimpBasic program can access
functions in the run-time library. Originally it was used
only to link optimised programs (which require a
trampoline) but on a 32 bit OS it is also used to support
WimpBasic_Link
.
On a 32 bit OS this SWI should be called with flags bit 0 set and R2 pointing to a buffer in which to write the required address table; otherwise an error will be returned if a library function is out of range (branch instructions only have a range of ±32 MB). An error will also result if the offset from trampoline to address table cannot be encoded in a PC-relative load instruction.
The word at [R1,#-4]
must be readable and
have been initialised as a branch instruction to the
word-aligned address immediately following the
trampoline. This is used by the WimpBasic module to
determine the length of the buffer. If present, the
address table buffer is assumed to be the same length.
If the no. of p-codes supported by this version of the
WimpBasic module (see WimpBasic_Info 1
)
exceeds the buffer length then a truncated trampoline
will be generated and no error returned.
If called with flags bit 1 set then the trampoline will
include different versions of various functions suitable
for calling from non-optimised code (usually including a
short pre-amble). The p-codes affected are
P_INITIALISE
(+0), P_DEFFN
(+568),
P_DEFPROC
(+80), P_ENDPROC
(+24), P_FN_RETURN
(+572),
P_NEXT
(+504) and P_CREATE_MENU
(+20).
If no error occurs and flags bit 1 is clear then an
internal count of programs linked with the WimpBasic
run-time library is incremented. (If generating a
trampoline for a non-optimised program then it is
expected SWI
WimpBasic_Link
will subsequently be called,
thus incrementing the count).
No flags were supported until version 2.10 of the module (i.e. this SWI always produced branch instructions for an optimised program).
WimpBasic_DeLink
WimpBasic_Stubs
WimpBasic_OkToDie
Returns the number of programs registered with the WimpBasic module.
All registers undefined
R0 = | number of registered programs |
Interrupt status is unchanged
Processor is in SVC mode
SWI is re-entrant
This call returns the number of programs currently believed to be linked with the WimpBasic run-time library. If the returned value is greater than 0 then any subsequent attempt to kill the WimpBasic module will fail with an error message.
This SWI was not supported until version 2.10 of the module.
WimpBasic_Link
WimpBasic_DeLink
WimpBasic_Stubs
Query the WimpBasic module for miscellaneous information.
R0 = | reason code |
Registers depend upon the reason code
Interrupt status is unchanged
Processor is in SVC mode
SWI is re-entrant
This call provides an extendible mechanism by which a program can query the WimpBasic module for information. The particular action is given by the reason code in R0, as follows:
R0 | Action |
---|---|
0 | Read expected size of program's static data |
1 | Read number of p-codes known to this version of module |
2 | Read version number of module |
Unknown reason codes cause an error to be returned, except in versions prior to 2.10 where -1 is instead returned in R0.
None
Returns the expected size of a WimpBasic program's static data.
R0 = | 0 (reason code) |
R0 = | expected size of program's static data (in bytes) |
This call can be used to determine how much space to allocate for a WimpBasic program's static data. However since this data must be initialised externally, the usefulness of this call is currently restricted to checking the returned value against the size expected by the program doing the initialisation.
Returns number of p-codes known to this version of WimpBasic module.
R0 = | 1 (reason code) |
R0 = | number of known p-codes |
This call can be used to determine how much space to
allocate before calling
SWI WimpBasic_Stubs
to generate a
trampoline (and associated address table, if 32 bit
compatibility is required). The total number of bytes
required for address table and trampoline (with
pre-pended branch instruction) can be calculated as
(number of p-codes × 2 + 1) × 4.
By this mechanism, the 'wblinker' program included in
WimpBasic applications need not be modified to support
programs that use a greater range of p-codes (although a
newer version of the WimpBasic module would need to be
*RMEnsure
'd in !Run).
Note that optimised programs already include space for a trampoline and therefore the extra required for an address table can instead be decoded from the preceding branch instruction.
This reason code is only supported in 2.10 and subsequent versions of the module.
Returns the version number of the WimpBasic module.
R0 = | 2 (reason code) |
R0 = | version number of WimpBasic module × 100 |
This call can be used to check the version number of the WimpBasic module before relying upon any features introduced in later versions. It returns the version number multiplied by 100 (to make it an integer).
This reason code is only supported in 2.10 and subsequent versions of the module.
&81A713 | "Branch out of range" |
May be returned by
SWIs WimpBasic_Link or
WimpBasic_Stubs .
|
&81A714 | "Address table too far" |
May be returned by
SWI WimpBasic_Stubs .
|
&81A715 | "Unknown WimpBasic_Info reason code" |
May be returned by
SWI WimpBasic_Info .
|
&81A716 | "WimpBasic can't die. <n> tasks registered" | May be returned by module's finalisation code. |
&81A717 | "Internal error IP<n>.<n>" |
May be returned by
SWI WimpBasic_Link .
|
&81A718 | "Internal error UP<n>.<n>" |
May be returned by
SWI WimpBasic_Link .
|