Description of modules by Nicholas Kingsley
*******************************************

(C) Nicholas Kingsley 1995

IMPORTANT : 
-----------

Although you can freely use these modules in your own programs, you may not
modify or reverse engineer them.

In addition, valid output may not be given if incorrect values are used.  
This is especially true for the routines that directly modify the screen, as,
although there are validity checks for addresses, values given may still
be incorrect

You must make no assumptions about how they work, or where internal data
is stored.  However, all values stored in registers are preserved before they
are modified, except when a register returns a value.

I accept no responsibility for any damage caused through the use or
misuse of these modules.
                                                           
I currently don't know whether these modules will work on any other machine
apart from the A3010/20 and 4000.

I have tried to remove all possible bugs, but if you find any or have
any comments, please E-Mail me at : nicholk@dcs.rhbnc.ac.uk (until May '96)

Routines that have test programs have " Has a test program " after them

THE MODULES 
-----------

In this ReadMe file are descriptions of the following SWI's :
         
         SWI Number:

Colour   (&C0000)
Error    (&C0080)
File     (&C0100)
GCIO     (&C0200)
IRQFile  (&C0400)
Menu     (&C0800)
Number   (&C1000)
Read     (&C2000)
Screen   (&C4000)
System   (&C8000)
IRQText  (&D0000)
Random   (&D0040)
Sprite   (&D00C0)
ReDefine (&D01C0)

These modules, although very useful for BASIC programs, are designed to be 
used in languages which don't have certain features built in, for example
assembler doesn't have a random number generator built-in, and thus the
Random SWI could be useful.
                                        
As all modules have full help text, I'll only list the bare essentials
here.

No module is re-entrant, so if you want to use one in an interrupt, then
you've have to use the CallBack routine.
  
MAJOR UPDATE : 4/10/95 - Make sure all SWI's use the X form.  Re-assemble
                         with new version of Extasm.  Replace all checks for
                         memory below &8000 with a valid memory check.
UPDATED : 9/10/95 - Remove bug with routines that use a copy routine

************************************************************************

ERROR MODULE
------------

Error_SError

This module allows you to display a standard error message, as dictated
by the Style Guide.

Registers used : 

R0 - Pointer to program name
R1 - Pointer to error message
R2 - Error number

*SError <Program name> <description of problem> <error number>

 Has test program 

************************************************************************

SCREEN MODULE
-------------

Screen_TextEntry

This provides better input facilities over the INPUT command or OS_ReadLine
SWI.

It can convert lower-case letters to upper-case, only allow numbers, 
display stars for any characters pressed, automatic return, ignore
cursor/function etc. keys.

UPDATED : 22/7/95 - Add new option, improve speed from MOV R0,<n>/SWI OS_WriteC to SWI OS_WriteI+<n>, improve escape detection & removing
UPDATED : 6/8/95  - Add routine to allow the HOME key to reset cursor
position and clear the input line, and to ignore various other keys.  Also
allow both DELETE keys to act in the same way.  Change ANDS Rx,Rx,#T_xxx to
TST Rx,#T_xxxx
UPDATED : 7/9/95  - Allow input area to be filled with any valid ASCII value, if new bit (9) is set
UPDATED : 9/9/95  - Improve conversion to upper-case.  Now does it in three commands
UPDATED : 5/11/95 - Improve checking routines.  Now a few lines less

Registers used : 

R0 - X
R1 - Y
R2 - Length of input
R3 - Input state : Bit 0 - Conversion to uppercase
                   Bit 1 - Allow only alphabetic characters
                   Bit 2 - Allow only numbers
                   Bit 3 - Display star
                   Bit 4 - Return as soon as length reached
                   Bit 5 - Use NULL as terminator instead of CR
                   Bit 6 - Allow spaces
                   Bit 7 - Y,y, N or n only
                   Bit 8 - Allow only non-alphanumeric characters
                   Bit 9 - Use guidance markers
R4 - Start address of input
R5 - ASCII value for filling input area (Guidance markers)

Returns :

R0 - Length of input

 Has a test program 

Screen_CharCopy

This copies a character over a given number of times either to the screen or to memory (in which case it can be used as a memory fill).  It is equivalent
to BASIC's STRING$ command (if address = 0).

UPDATED : 7/9/95 - Allow multiple characters to be stored in memory.  Add memory check.

Registers used : 

R0 - Character (must be > 31, if address is 0)
R1 - Number of iterations
R2 - Start address of storage (used only if > 0)

NOTE : You will only get screen output if address is 0

 Has a test program 

Screen _GotoXY

This moves the cursor to a given X and Y coordinate.  It is especially
useful in machine code as it saves the programmer having to fiddle around
with the code to send VDU bytes

UPDATED : 22/7/95 - Removes branch.  Instead does an SWI OS_WriteI first, followed by 2 OS_WriteC's

Registers used : 

R0 - X
R1 - Y

 Has a test program 

Screen_Box

Screen_Box is only really useful if you re-define the 8 * 8 character
font.  It is designed to draw a box anywhere on the screen using UDG
characters.  This allows boxes to be displayed in text-only modes, or where
pixel co-ordinates are too accurate.

UPDATE : 6/8/95 - Fix bug

Registers used : 

R0 - X
R1 - Y
R2 - X length
R3 - Y length
R4 - ASCII start value

Screen_TextMenu

This SWI is designed to allow text menu creation where all the options
start on the same column.

UPDATED : 6/8/95 - Improve cursor movement slightly by removing LDRB. 
Instead place cursor position in extra register.  Also change memory error
address.  Change ANDS Rx... to TST

UPDATED : 11/8/95 - Remove bug (would only add 1 line)
UPDATED : 5/11/95 - Reduce conversion to upper-case by one line

Registers used : 

R0 - Pointer to text address
R1 - X
R2 - Y
R3 - Vertical line spacing value
R4 - Terminator
R5 - Menu separator
R6 - Validate field value (Bit 0 Set - Convert lower-case characters to upper-case)

Returns :

R0 - Last address used

 Has a test program 

Screen_TelePrint

For some games, displaying characters one at a time followed by a cursor
fits well with the software's theme, and this SWI allows you to "teleprint"
characters, just like The Terminator, Universal Soldier and others.

UPDATED : 6/8/95 - Remove LDRB, by placing row value in register

Registers used : 

R0 - Pointer to start of text
R1 - X
R2 - Y
R3 - Terminator (no pun intended)
R4 - Foreground colour
R5 - Background colour
R6 - Cursor colour
R7 - Extra value

 Has a test program 

Screen_WriteC

This SWI works in much the same way as OS_WriteC, except for 2 important
differences : You set positions by a pixel value , and not by row or column, 
and each line can have a different colour, allowing multi-coloured 
characters.

Registers used : 

R0 - Pointer to start of screen address
R1 - Pointer to start of colour address
R2 - X Size of screen
R3 - ASCII value of character to be displayed
R4 - X
R5 - Y
R6 - X scale value (Bit 31 set - overwriting is performed)
                   (Bit 30 set - each line has individual colour)
R7 - Y scale value

UPDATED : 12/9/95 - Add bit 30 operation, which now allows each line to have
a seperate colour, as the standard every 8 lines

 Has a test program 

Screen_Write0

This routine displays a string of characters, terminated by an ASCII 0
character, using Screen_WriteC.

NOTE : You can produce text that is slanted by modifying a parameter. 
However, doing so will modify the coordinate system, and you must make
appropriate allowances for that.

NOTE : It should be noted that using Screen_Write0 to display 40 characters,
each 8 * 8 takes exactly the same time as OS_Write0.  Increasing the size
of the characters does not exponentially increase the time taken.

NOTE : With Screen_WriteC and Screen_Write0, there is no checking for
out-of-bounds co-ordinates.

Registers used : 

R0 - Pointer to start of screen address
R1 - Pointer to start of colour address
R2 - X size
R3 - Pointer to start of text address
R4 - X
R5 - Y
R6 - X scale (Bit 31 set - perform overwriting)
R7 - Y scale

 Has a test program 

Screen_CentreText

This centres text on a given line, based on the number of columns for a
given mode.  It is totally mode independent.

Registers used : 

R0 - Y
R1 - ASCII value of terminator
R2 - Pointer to start address of text

 Has a test program 

Screen_FilledBox

FilledBox fills a rectangular area of screen with a given character,
background and foreground colour.

UPDATED : 29/10/95 - Remove duplicate code

Registers used : 

R0 - X
R1 - Y
R2 - X Width
R3 - Y Width
R4 - Foreground colour
R5 - Background colour

 Has a test program 

Screen_VerticalWipe

This routine clears a screen, by deleting every second line.  As two lines
start from different positions, you'll find that after the routine has
finished, you'll have a clear screen.

CONVERTED TO MODULE : 1/8/95.  Mode independence added.
UPDATED : 11/8/95 - Allow second screen data to be used instead of colour.

Registers used : 

R0 - Pointer to start address of screen
R1 - Colour value
R2 - Second address

 Has a test program 

Screen_HorizontalWipe

This routine also clears the screen, by deleting every second pixel.  It works in more or less the same way as Screen_VerticalWipe.

CONVERTED TO MODULE : 1/8/95.  Mode independence added.
UPDATED : 11/8/95 - Allow second screen data to be used instead of colour.

Registers used : 

R0 - Pointer to start address of screen
R1 - Colour value
R2 - Second address

 Has a test program 

Screen_StepWipe

This routine also clears the screen, by skipping an increasing number of 
bytes.  

CONVERTED TO MODULE : 6/8/95.  Mode independence added.
UPDATED : 11/8/95 - Allow second screen data to be used instead of colour.

Registers used : 

R0 - Pointer to start address of screen
R1 - Colour value
R2 - Second address

 Has a test program 

Screen_BlockCopy40

This routine allows groups of 40 bytes to be copied from one area of 
memory to another.  This would mostly be used to copy data from one
screen bank to another

CONVERTED TO MODULE : 4/9/95

Registers used : 

R0 - Source address (must be word aligned)
R1 - Destination address (must be word aligned)
R2 - Number of bytes to copy (must be multiples of 40 bytes)
    
NOTE : There has been no checks for word-alignment nor for checking
the number of bytes.  In addition, there have been no allowances for
over-lapping areas of memory.  This is to allow the routine to work at the
fastest speed possible.

 Has a test program 

Screen_BlockCopy1

This routine allows groups of bytes to be copied.

CONVERTED TO MODULE : 4/9/95

Registers used : 

R0 - Source address 
R1 - Destination address 
R2 - Number of bytes to copy 

 Has a test program 

Screen_WriteM

This module is somewhat like Screen_Write0, but allows different colours
in both the horizontal and vertical direction.

Registers used :

R0 - X position (in pixels)
R1 - Y position (in pixels)
R2 - Pointer to start address of character
R3 - Type (Bit 31 Set - Allow any background data to show through)
R4 - Width of screen (in pixels)
R5 - Start address of screen

NOTE : This routine tries to be as quick as possible.

CONVERTED TO MODULE : 8/11/95

 Has a test program 

Screen_RasterBars

This routine displays a number of raster bars, created using the "RasterBars"
program, onto the current screen

Registers used :

R0 - Start address of the current screen
R1 - Start address of the colour data
R2 - Starting row number
R3 - Screen width (in pixels)

NOTE : To make the routine as fast as possible, no memory checking is 
       performed.  This means that you should only use this routine on
       256 screens, which are mulitple of 320 bytes

CONVERTED TO MODULE : 1/12/95

 Has test program 

************************************************************************

MENU MODULE
-----------

Menu_Select

This would mostly be used in conjunction with the Screen_TextMenu SWI.  It
allows easy selection of text-based options, using the cursor key to move
a selecting character up and down and the return key to select an option.
It returns a value for the left and right cursor, so you can choose to
ignore them, or call some function if either are pressed.

Registers used : 

R0 - X
R1 - Start Y value for selecting character
R2 - Number of options
R3 - Starting option number
R4 - ASCII value of selector
R5 - Delay
R6 - Spacing between options

Returns :

R0 - Code
R1 - Position

 Has a test program 

************************************************************************

COLOUR MODULE
-------------

Colour_SetValue

This allows you to set the text colours foreground or background, set the
border colour or clear the screen.  

This allows you to select any colour without worrying about which ColourTrans
value to use, and having to shift values etc.

UPDATED : 6/8/95 - Remove possible bug.  Replace all ANDS Rx, Ry... with
TST Ry...

Registers used : 

R0 - Red value
R1 - Green value
R2 - Blue value
R3 - Type (Bit 0 set - Set forground colour)
          (Bit 1 set - Set background colour)
          (Bit 2 set - Set border colour)
          (Bit 3 set - Clear screen)

 Has test program 

Colour_ScreenBackground

This allows you to set the colour of the screen background, without the need
to clear the screen to invoke the new colour.

Registers used : 

R0 - Pointer to start address of screen
R1 - X size
R2 - Colour
R3 - Replace colour

Colour_FadeText

This allows you to fade text up or down and finish with a given colour
                 
Registers used : 

R0 - Pointer to start address of text
R1 - ASCII value of terminator
R2 - X
R3 - Y
R4 - Control data
R5 - Final colour
       
UPDATED : 5/11/95 - Replace an AND Rx,Ry with a TST Ry

 Has a test program 

Colour_Shade

This routine returns addresses of different coloured shades, which is
especially useful for Screen_WriteC or Screen_Write0

Registers used : 

R0 - Shade number

Returns :

R0 - Address of desired shade

************************************************************************

SYSTEM MODULE
-------------

System_Save

This module allows the users current wimp mode and sound parameters to be
saved to a temporary file, which can then be restored at a later date.
                                                  
NOTE : If an error occurs for some reason, it is up to the user to
shut the file and take appropriate action

UPDATED : 7/8/95 - Allow saving of sound channel numbers

Registers used : 

R0 - Number of sound channels
R1 - Sample length
R2 - Sample period
R3 - Pointer to Channel Handler
R4 - Pointer to Scheduler

System_Load

This module loads a saved system file back into the appropriate
memory locations

UPDATED : 7/8/95 - Allow loading of sound channels

Registers used : 

None

Returns :

R0 - Previous mode number

************************************************************************

READ MODULE
-----------

Read_VduVariable

This module allows you to read a VDU variable without the need to set up
your own arrays.

Registers used : 

R0 - Variable number

Returns :

R0 - Resultant value

 Has a test program 

Read_FreeMemory

This routine allows you to check how much free application memory you have
by storing it in a system variable.

UPDATED : 7/8/95 - Add *command
UPDATED : 5/10/95 - System variable set up when module is loaded.  When run
                    from the command line, it will now display the value in
                    bytes (b), kilobytes (K) or megabytes (Mb) 

Registers used : 

None

Returns :

R0 - Amount of free memory in bytes.

 Has a test program 

Read_OSVersion

This routine shows which RISC OS version the module is currently running on.
In addition, it stores the value in a system variable.
                                       
Registers used :

None

Returns :

R0 - OS Version number

CONVERTED TO MODULE : 17/8/95 - Add system variable
UPDATED : 5/10/95 - System variable is now set up when module is loaded

 Has a test program 

UPDATED : 21/11/95 - Add finalisation code : Now kills defined variables

************************************************************************

RANDOM MODULE
-------------

Random_CreateSeed

This sets the starting seed value.  

Registers used : 

R0 - Seed value

Returns :

R0 - Final seed value

 Has a test program 

Random_Number

This generates a random number between 0 and either 255 or 429496725 depending on a number given.

UPDATED : 4/8/95 - New routine to give number between 0 and 255 or 0 and 429496725

Registers used : 

R0 - Highest range (0 - Creates a random number where the probability of a number less than &80000000 is very remote)

Returns :

R0 - Random number

 Has a test program 

************************************************************************

NUMBER MODULE
-------------

Number_Pad 

This module pads a given positive decimal integer number to a given number
of characters, and with a given ASCII value.  The output length will always
be EXACTLY the length given. 

This SWI is useful for any programs where decimal output must always be of
fixed length, for example scores in games.

UPDATED : 21/7/95 - Improve initial pad display/storing.  Improved display
          calculation & slightly faster character output/storage

Registers used : 

R0 - Number
R1 - ASCII value to use for padding
R2 - Number of characters for padding
R3 - X
R4 - Y
R5 - Address to store text result (if 0 then output to screen)

 Has a test program 

************************************************************************

FILE MODULE
-----------

File_Compress

This routine will compress a given memory range into a file, will the 
result that it should save disk space.  The routine used produces a 
very good size reduction if there is a lot of sequential repetition, and so
is best for graphic data

Registers used : 

R0 - Pointer to start address of filename
R1 - Start address of compression
R2 - End address of compression
R3 - Screen output 

File_Decompress

This routine will decompress data from a file and store it in memory.

Registers used : 

R0 - Pointer to start address of filename
R1 - Start address of decompression
R2 - Type of decompression
R3 - Screen output 

 Has a test program 

File_BinAppend

RiscOS 3.11 doesn't allow files to be appended easily.  This 
routine fixes that problem.

CONVERTED TO MODULE : 13/8/95 - *command added

Registers used :

R0 - Pointer to start address of input filename 1
R1 - Pointer to start address of input filename 2
R2 - Pointer to start address of output filename
R3 - Screen output (if > 0 show how routine is getting on)

 Has a test program 

************************************************************************

GCIO MODULE
----------

GCIO_DetectJoystick

This SWI detects whether the joystick module is active or not.  It returns :

Bit 0 Set - Port 1 present
Bit 1 Set - Port 2 present

Registers used : 

None

Returns :

R0 - Port values

GCIO_Joystick

This SWI is useful if you want to use some offset value in an array,
in order to move objects.  It converts the normal joystick values from 
either port into a direction number between 0 and 10.

The top 3 bits (bits 7 to 5) represent the fire button states.

UPDATED : 6/8/95 - Replace all ANDS Rx, Ry.. with TST Ry

Registers used : 

R0 - Port number

Returns :

R0 - Value

GCIO_Key

This module is useful for games, with the same reasons as AltJoystick.
It reads the keyboard and returns a movement value between 0 and 10.  Bits 
7 to 5 return the 'fire button' status.

Registers used : 

R0 - Pointer to start address of 7 bytes

Returns :

R0 - Value

************************************************************************

IRQFILE MODULE
--------------

IRQFile_DataLoad 

This module will attempt to load a data file into a given area of memory
in the background (under interrupts).  This allows the main program to
continue while the data is loading.  This routine must NOT be called again until it has finished.

Registers used : 

R0 - Pointer to start address of filename
R1 - Start address of load
R2 - Load type
             
 Has a test program 

IRQFile_Status

This routine returns a value based on the progress made while loading the
data

Registers used : 

None

Returns :

R0 - Status of routine

IRQFile_Abort

This routine aborts the loading system, closes the file used and removes
the interrupt system

Registers used : 

None

NOTE : These routines have only been tested on a A3010, and MAY not work on 
the RiscPC600, 700 or 7000.  I hope to be solving this problem soon.
In addition, if you abort a program using the ESC key you will
get an abort on data transfer error, which although is fairly harmless 
should be avoided either by making sure you don't press the ESC key
until the routine has finished, or by setting up another escape handler to 
call IRQFile_Abort.

In addition, this module MAY not work with Risc OS 2 machines.

************************************************************************

IRQTEXT MODULE
--------------

IRQText_Print

This SWI allows text to be printed to the screen under interrupts, allowing
the main program to continue with something else.  This routine must NOT be called again until it has finished.

Registers used :

R0 - Pointer to start of text address
R1 - ASCII value of terminator

UPDATED : 21/11/95 - Fix finishing print bug

 Has a test program 

IRQText_Status

This SWI allows you to check to see whether the interrupt printing has 
finished or not

Registers used :

None

Returns :

R0 - Status of print routine

IRQText_Abort

This SWI aborts the interrupt printing process

Registers used : 

None

NOTE : These routine have only been tested on a A3010, and MAY not work on 
the RiscPC600, 700 or 7000.  I hope to be rectifying this problem soon.
In addition, if you abort a program using the ESC key you will
get an abort on data transfer error, which although is fairly harmless 
should be avoided either by making sure you don't use the ESC key until
you know that the routine has finish, or by setting up another escape handler
to call IRQText_Abort.

If you print something while IRQText_Print is working, all further
characters will be printed at the last cursor position.

In addition, this module MAY not work with Risc OS 2 machines.

************************************************************************

SPRITE MODULE
-------------

Sprite_DisplayNormal

This module is used to display a sprite using internal colour numbers only,
which is the format used in my SprToData program.  It has been designed
with full clipping in mind, and so can be very slow (depending on the size of the sprite).

CONVERTED TO MODULE : 5/9/95 - Mask against background added

Registers used : 

R0 - Start address of sprite data
R1 - Top left X coordinate for plotting
R2 - Top left Y coordinate for plotting
R3 - Internal colour number of mask
R4 - Start address of output (normally screen)
R5 - Width of output area
R6 - Height of output area
R7 - Type field, based on the following :

     Bit 31 Set - Use mask colour against sprite colour
     Bit 30 Set - Use mask colour against colour at current location
     Bits 7-0   - Which sprite that you want displayed
                                            
Returns :

R0 - Last address read

NOTE : Bits 31 and 30 exclude each other
NOTE : This module allows you to store sprite data anywhere in memory, which
       means you don't have to display them!

Sprite_DisplayPreShift

This routine will display a sprite much quicker than with the previous
routine.  To get around the fact that the positioning location has to
be word aligned, the sprite should be pre-shifted.

Registers used :

R0 - Start address of sprite memory
R1 - X Position
R2 - Y Position
R3 - Start address of screen
R4 - Width of screen
R5 - Height of screen

Returns :

R0 - Last address read

CONVERTED TO MODULE : 6/9/95

Sprite_FindPreShifts

This routine MUST be called before Sprite_DisplayPreShift, to speed up
finding which pre-shifted sprite must be destroyed.

Registers used :

R0 - Start address of sprite memory

Returns :

R0 - Pre-shifts NOT found (< 0 - All found)

CONVERTED TO MODULE : 6/9/95

NOTE : These routines require data to be in the format created by the 
"SprToData" program, and may return unpredicatable results if it isn't.

Sprite_DisplayFast

This routine allows sprite data (converted by NewSprPlt program) to be
display anywhere on screen at a very fast rate.  This is done by assuming
that the colour 0 (which can be change in the aformentioned program) is
always skipped.  This means that only non-black pixels are plotted

Registers used :

R0 - Start address of screen
R1 - Start address of sprite data
R2 - X Position
R3 - Y Position
R4 - Screen width

Returns :

Nothing

CONVERTED TO MODULE : 10/11/95 - Increase amount of data read in at once
                                 (now 10 bytes, with offset and colour
                                  interleaved)
                                 Fix bugs in conversion program

 Has a test program 

************************************************************************

REDEFINE MODULE
---------------

ReDefine_SetOfKeys

This routine allows the user to redefine the actions of keys, in games.  All
keys are detected, and are displayed in a given colour after each keypress.
Duplicate keys are not allow, of course.

Registers used :

R0 - Start address of text giving action names to all required keys.  Each 
     name must be seperated by a "|", and the whole list terminated a 0
     byte
R1 - Starting column number for displaying names
R2 - Starting row number for displaying names
R3 - Pointer to address holding 2 * 4 byte &BBRRGG00 colours (foreground, background), for displaying names
R4 - Pointer to address holding 2 * 4 byte &BBRRGG00 colours (foreground, background), for user key presses
R5 - Spacing :

     Bits 31-16 - Row spacing (number of lines between each name)
     Bits 15-0  - Column spacing (number of columns between names and 
                                  enteries)
R6 - Start address of storage
R7 - Bits 7-0 : Use voice number given (if > 0) to warn of duplicates
     Bit  8   : If set, then convert all lowercase characters to uppercase
     Bit  9   : Return as soon as all text and keys have been displayed.  
                This is useful for multi-player games, as it allows you to
                display all the players keys at once.

CONVERTED TO MODULE : 9/9/95 - Conversion to uppercase added, as well as
                      pointers to colours            
UPDATED : 21/11/95 - Add return-as-soon-as-possible code

NOTE : If any codes are not reconized, then "* Undefined *" will be
displayed

 Has a test program 

ReDefine_Chars

This routine allows you to load in a compressed BBC font file, and change
all define characters to the new shapes

Registers used :

R0 - Pointer to start of filename

CONVERTED TO MODULE : 20/9/95 

*RChar

This command resets the current font to the system font

COMMAND ADDED : 20/9/95