www.riscos.com Technical Support: |
|
It is reasonable to expect that most SWIs can generate an error. For example, if you pass poor parameters you would expect the SWI routine to tell you about it.
SWIs report errors in a consistent way. If no error occurred, and the desired action was performed, the SWI routine will clear the ARM's V (overflow) flag on exit. If an error did occur, the SWI routine will set V on exit. Furthermore, R0 will contain a pointer to an error block, which is described below.
Just before RISC OS passes control back to your program, it checks the V flag. If it is clear (no error occurred) control passes directly back.
If V is set (an error occurred), RISC OS looks at a copy of the original SWI instruction you used:
These two types of SWI are known respectively as error-generating and error-returning SWIs. For every SWI, you can call either version, depending on whether you want to detect the error yourself, or leave the current error handler to deal with it. All the examples in the chapter * Commands and the CLI were error-generating SWIs. If you want to call an error-returning SWI, with bit 17 set:
Just as the 24-bit SWI number is divided into different fields, 32-bit error numbers are also split up.
The bottom byte is often a basic 'error number'.
The middle two bytes identify what generated the error. Third parties generating their own errors must apply to Acorn for an identifier. The following error ranges have been reserved:
Range | Error generator |
---|---|
&000 - &0FF | Operating system - BBC-compatible error |
&100 - &11F | OS_Module errors |
&120 - &13F | OS_ReadVarVal/SetVarVal errors |
&140 - &15F | Redirection manager errors |
&160 - &17F | OS_EvaluateExpression errors |
&180 - &19F | OS_Heap errors |
&1A0 - &1AF | OS_Claim/Release errors |
&1B0 - &1BF | OS_ChangeEnvironment errors |
&1C0 - &1DF | OS_ChangeDynamicArea errors |
&1E0 - &1EF | OS_CLI/miscellaneous errors |
&200 - &27F | Font manager errors |
&280 - &2BF | Wimp errors |
&2C0 - &2FF | Date/time conversion errors |
&300 - &3FF | Econet errors |
&400 - &4FF | FileSwitch errors |
&500 - &5BF | Podule errors |
&5C0 - &5FF | Printer driver errors |
&600 - &63F | General OS errors |
&640 - &6FF | International module errors |
&700 - &7FF | Sprite errors |
&800 - &87F | Debugger errors |
&880 - &8FF | BBC I/O Podule errors |
&900 - &97F | Shell CLI errors, and miscellaneous others |
&980 - &9FF | Draw errors |
&A00 - &A3F | ColourTrans errors |
&A40 - &A7F | ARM3 errors |
&A80 - &ABF | TaskWindow errors |
&AC0 - &AFF | MessageTrans errors |
&B00 - &B3F | Pinboard errors |
&B40 - &B4F | Portable module errors |
&1XX00 - &1XXFF | Errors from filing system number &XX |
(eg &10800 - &108FF ADFS errors) | |
&20000 - &200FF | Sound errors |
&20200 - &21000 | Podule errors, and miscellaneous others |
The top byte contains flags:
&80000000 - &800000FF | Machine exceptions |
&80000100 - &800001FF | CoProcessor exceptions |
&80000200 - &800002FF | Floating Point exceptions |
&80000300 - &800003FF | Econet exceptions |
You may need to know in more detail how RISC OS handles an error that an error-generating SWI creates.
If you want to handle an error yourself, you must instead use the error-returning version of the SWI.
In addition to detecting errors, you might want to generate an error which calls the current error handler, so you can find out about a problem. A common example would be if you detect that Esc is pressed. This is usually a sure sign that the user wants to abandon the current operation. The standard response is for you to acknowledge the escape (see the chapter entitled Character Input for details), and generate an 'Escape' error. This is then dealt with by the current error handler.
To generate the error, you should call the SWI OS_GenerateError. On entry, R0 contains a standard error block pointer. The routine never returns. For example, BASIC's error handler will cause the current BASIC program to terminate, returning control to the command mode, or to execute an ON ERROR statement, if one is active.
You must not write system extension code (such as a module, interrupt handler or transient) that generates errors - users of this code have a right to expect it to work. This means that you must always use the X form of SWIs in such code.
The only time you should call OS_GenerateError from system extension code is to report exception-type errors - that is, when bit 31 of the error number is set. For example, the Floating Point Emulator uses this mechanism to report exceptions from both the hardware and software floating point processors, as coprocessor instructions obviously cannot return with the V bit of the ARM processor set to indicate an error.
Generates an error and invokes the error handler
R0 = pointer to error block
Doesn't return - OS_GenerateError (SWI &2B) or
V flag is set - XOS_GenerateError (SWI &2002B)
Interrupts are enabled by OS_GenerateError, but unaltered by the X form
Fast interrupts are enabled
Processor is in SVC mode
SWI is not re-entrant
OS_GenerateError generates an error and invokes the error handler. Whether or not it returns depends on the type of SWI being used. If XOS_GenerateError is used, the only effect is to set the V flag. This is not very useful.
Here is an example of how OS_GenerateError would be used:
SWI "OS_ReadEscapeState" ; Sets C if escape BLCS acknowledge_escape ; acknowledge it - returns using ; LDMFD R13!,{PC}^ ADRCS R0,escapeBlock ; Get ptr. to error block MOVCS R1,#0 ; Use global messages file MOVCS R2,#0 ; Use internal buffer SWICS "XMessageTrans_ErrorLookup" ; Look up token in message file SWICS "OS_GenerateError" ; Do the error - doesn't return .noEscape ... .escapeBlock EQUD 17 ; Error number for escape EQUS "Escape"+CHR$0 ; Error token to lookup ALIGN
None
ErrorV
Generates errors
*Error [error_no] text
error_no | the error number |
text | a string of printable characters explaining the error |
*Error generates an error with the given error number and explanatory text. This is normally then printed on the screen. This command is useful for reporting errors after trapping them within a command script.
If you omit the error number it is set to the default value of 0.
Errors are also, of course, generated by RISC OS itself.
*Error 100 No such file prints 'No such file'
None
OS_GenerateError (SWI &2B)