HINTS & TIPS

This month's collection of useful Hints and Tips is rounded up by David Spencer and Lee Calcraft.

SYS STRINGS

You may be aware that a string can be passed directly to a SYS call when in fact the native SWI call expects a pointer to a string. In such cases, Basic performs all the necessary conversions. For example:
SYS "OS_Write0","Hello World"+CHR$0
It is, however, also possible to read a string back from a SYS call. Take for example:
DIM buffer 100
SYS "OS_SWINumberToString",&26,buffer, 100 TO ,name$
PRINT name$

This will convert the SWI number &26 into its corresponding name, "OS_GSRead".

The DIM serves to set up a block of memory to hold the converted name, and this is passed to the SWI call as the parameter for register R1. On exit from the call, this register still holds the pointer, and the assignment to name$ forces Basic to read the string back into the string variable. This technique can be used in all cases where a SWI call returns a pointer to a string.

CHANGING DISCS

The RISC OS Desktop on the 300 series offers the very nice feature that if an attempt is made to access a disc which is not currently in the drive, then it will wait until the correct disc is inserted and then continue without any further action being necessary. However, the new drives used on the 400/1 series and the A3000 do not provide a Disc Changed Interrupt (DCIRQ), and this means that if the correct disc is not present, then once it has been inserted you must go and click on the 'OK' icon before the new disc is recognised.

On the good side, the new disc drives have moulded eject buttons which cannot (should not?) fly off.

APPENDING LISTING

We sometimes publish particularly long programs in RISC User in two or more parts. Examples of this are the RISC User Notepad and the Toolbox. It can be very hard to find any mistakes made when a new set of lines are added to an existing program, and a better way is to enter and check the new lines before adding them to the existing program. To do this, enter the new lines as if they formed a complete listing, check it, and save the program as a text file by using the commands:
*SPOOL TextProg
LIST
*SPOOL

Then, load the original program and add the new lines with the command:
*EXEC TextProg
The result will then be a complete program with the new lines added to the existing code.

QUICK PRINT

Under RISC OS, the call:
SYS "OS_PrintChar",code
will send to the printer the single character whose ASCII code is code. This call will work regardless of whether the printer has been enabled with VDU2, or even completely disabled using *FX 3.

INPUT/OUTPUT REDIRECTION

A major, yet little known, feature of both RISC OS and Arthur is the ability to redirect input and output during the execution of a star command. This means that all output that would normally be sent to the screen will instead go to a file, or all input that would be read from the keyboard is read instead from a file. This redirection is achieved by adding one of the following to the star command:
{ > file }to send output to a file
{ >> file }to append output to a file
{ < file }to take input from a file

Spaces are critical, and there must be at least one space around each element, including before the '{' and after the '}'.

The redirection specification, as these are called, can be placed anywhere in the command where a space would otherwise be. For example:
*Basic { > Bout } -Quit MyProg
This will execute the Basic program MyProg, saving all the output in the file Bout, and QUITing when finished.

NO OPTION

A frequent sight in assembly language source code is the following two lines:
1000 [
1010 OPT pass%

This has the disadvantage that the Basic assembler will print the current instruction pointer address after the '[' is encountered, even if the OPT subsequently turns off the listing. This can cause two addresses to flash on the screen while trying to assemble the code with no listing. To get around this, put the two commands on a single line, thus:
1000 [OPT pass%

TYPES DON'T MATCH ERROR

The error message "Types don't match" is given if you try to save a file (using SAVE, *SAVE or OS_File) with a name already used for a directory. If you have a large number of objects in your current directory, you might well not realise the coincidence - and this very unhelpful message only obscures the problem.

If you try to load a directory, you get the much more helpful message:
xxxx is a directory.

SWIS AND INTEGER VARIABLES

When using variables in SWI calls it is advisable to use integer variables, because real variables will give the error "Number too big" if values greater than &7FFFFFFF are ever assigned. This is because Basic converts the assigned value to an integer before passing it to the corresponding SWI call, and the valid range for integers is -&80000000 to +&7FFFFFFF.

LARGE PROGRAMS IN TWIN, AGAIN

In RISC User Volume 2 Issue 5 we gave a hint about overcoming Twin's 6527 line limit with Basic programs. David Pilling reports another solution. When you exit Twin with a program longer than this, Basic renumbers it so that every line is given the number "9". You can then use RENUMBER 1,1 to renumber it correctly. You can even RUN the program with all lines set to 9, providing of course, that no line number references are made.

READING THE COLOUR PALETTE

The SYS call "OS_ReadPalette" can be used to read the colour palette including the border colours. The following procedure makes use of this. It takes a single parameter: the logical colour number to be investigated. If you want information on the border, set this to -1. It returns with the variables red, green, and blue, set to the amounts of red green and blue used in the physical colour (range 0-240). For further information, see the Programmer's Reference Manual part 1.

10 REM >Palette2
20 MODE 12
30 PROCreadpalette(2)
40 PRINT"red ";red
50 PRINT"Green ";green
60 PRINT"Blue ";blue
70 END
80 :
90 DEFPROCreadpalette(logcol)
100 IF logcol=-1 THEN border=TRUE ELSE border=FALSE
110 SYS "OS_ReadPalette",logcol,16-8*border TO ,,first
120 blue=first>>>24
130 green=(first>>>16) AND &FF
140 red=(first>>>8) AND &FF
150 ENDPROC