SWI OS_ChangeEnvironment (&40)


This has been extended since 1.20; there are two new reason codes.

Application space size can be set with reason code 14. This is used in conjunction with the memory remapping facilities.

The Currently Active Object pointer can be set with reason code 15. This is the pointer checked by the MOS before it kills modules, or moves application space.

SWI OS_SubstituteArgs (&43)


This has been extended in Arthur 2: setting the top bit of r0 on entry stops it appending any unused parameters on the end of the output line.

SWI OS_PrettyPrint (&44)


This has been extended in Arthur 2 to cope with compacted text. If character 27 appears in the text to be printed, it indicates that a "dictionary" entry should be substituted instead, and which entry is indicated by the next byte. 1-255 means the nth entry in the passed dictionary. 0 is special: it means substitute the string pointed at by r2 on entry.

The format of a dictionary is a linear list of entries; each entry is a length byte followed by a null-terminated string. Note that this means that a dictionary does not have to have 255 entries; it can be terminated by a zero-length entry. In: r0 -> string to print
r1 -> dictionary (0 means use the MOS internal dictionary)
r2 -> special string

To see the MOS internal dictionary, use the following program:

DIM buffer 3
buffer?0 = 27
buffer?2 = 0
FOR I%=0 TO 255
buffer?1=I%
PRINT"Dictionary entry ";I%
SYS "OS_PrettyPrint",buffer,0,"<special string>"+CHR$0 PRINT
NEXT

SWI OS_ReadArgs (&49)


Inputs: R0 pointer to key definition
R1 pointer to input string
R2 pointer to output vector
        R3 size of output vector
Output: R0-R2 preserved
        R3 bytes left in vector

The key definition string is pretty obvious if you've used RdArgs or DecodeArgs (et al): keywords are alphanumerics or "_", with aliases separated by "=", and qualifiers coming after "/". "," separates arguments. Qualifiers: /A means keyword must always be given a value
/K means keyword must always precede its value
/S means the option is a switch; presence only is reported
/E means the Expression Evaluation SWI should be called to
transform the given value

            /G means GSTRans should be called to transform the given value

Some of these options are of course in conflict: meaning of /S/G etc. is undefined.

Input string: keywords are marked by "-", but "-" does not force the next item to be a keyword; this would cause problems with /E arguments (see below). Keywords can be be given single letter abbreviations. Switch keywords, when given as single letters, can also be elided. Results: if there are n arguments in the R0 string, then R2 starts with
n words, one for each argument. 0 in the word indicates that the argument was missing; for switches, non-zero therefore means the switch was present. For keywords taking values, the word points at the result, somewhere further along in the result vector.

Arguments with no /E or /G qualifiers are simply null-terminated strings. /E argument values are a type byte:
0 means integer, in which case the next 4 bytes are the value (LSB first) non-0 means string: the next 2 bytes are the length, then <length> bytes

                      of string

/G arguments are 2 bytes of length, <length> bytes of result.

Examples:

Key definition: file/a,tabexpand/s
can be matched by

                 -file fred -tabexpand
                 -tf fred
                 -t fred

definition number=times/e,file/k/a can be matched by

                 -n 10 -file jim
                 -times 1+7 -file jim
                 -file thingy
but not by
                 thingy -number 14
                 -number 20 -times 4 -file jim

SWI OS_ReadRAMFsLimits (&4A)


Returns R0 start, R1 end (i.e. 1st byte out of area)

SWI OS_DelinkApplication/SWI OS_RelinkApplication (&4D/&4E)


These SWIs are used by the Switcher to "disconnect" the application, before it is switched out. They deal with any entries on vectors where the code address lies in application space. OS_DelinkApplication:
R0 pointer to buffer
R1 buffer size
Returns R1 bytes left in buffer
The buffer contains records of (vector number, address, R12 value), terminated
by -1 OS_RelinkApplication:
R0 pointer to buffer as set up by Delink

SWI OS_HeapSort (&4F)


There is a routine in Arthur2 to sort objects using the HeapSort algorithm described in Knuth (Sorting and Searching pp.145-149). This is an algorithm of average order 23.08N ln N (for n -> infinity), and is worst case N^2. It is actually guaranteed to be of order N log N, (see the book for more detail). It's not as fast as QuickSort for 'average' QuickSorts, but doesn't use any more memory than that initially passed in.

In r0 = n (number of elements to sort)

       r1 = array(n) of word size objects (r2 determines type)
              bit 31 set -> use r4,r5 on postpass
              bit 30 set -> build (r1) from r4,r5 in prepass
              bit 29 set -> use r6 as temp slot
       r2 = address of comparison procedure
              Special cases:
                0 -> treat r(n) as array of cardinal
                1 -> treat r(n) as array of integer
                2 -> treat r(n) as array of cardinal*
                3 -> treat r(n) as array of integer*
                4 -> treat r(n) as array of char* (case insensitive)
                5 -> treat r(n) as array of char* (case sensitive)
       r3 = wsptr for comparison procedure (only needed if r2 > 5)
       r4 = array(n) of things (only needed if r1 & 0xC0000000)
       r5 = sizeof(element)    ( ---------  ditto  ---------- )
       r6 = address of temp slot (only needed if r5 > 16K or r1 & 0x20000000)

User sort procedure entered in SVC mode, interrupts enabled r0 = contents of array(1)
r1 = contents of array(2)
r0-r3 may be corrupted
r12 = value requested

            (alter at your peril; you'll get the same r12 next time)

User sort procedure returns:

       LT: if f(r0)  < f(r1)
       GE: if f(r0) => f(r1)
(ie. N_bit and V_bit only considered, Z_bit and C_bit irrelevant)

SWI OS_ExitAndDie (&50)


Action: SWI Exit performed, named module killed.
r0-r2 are parameters for Exit
r3 pointer to module name

SWI OS_AddCallBack (&54)


Arthur 2 has a "callback vector", which extends and improves the idea of a callback handler present in Arthur 1.20. The callback handler is the property of the current application, and can be used by the application to do anything it feels like (e.g. task switching).

However, callback is also very useful for a class of resident utilities, e.g. a module that will do a *ScreenSave when a key is pressed. This has a couple of problems if it tries to use the callback handler:

  1. the current application may lose callbacks, and therefore stop working.
  2. if the application is in ReadLine, then the callback doesn't happen until the readline returns. We therefore have the callback vector, which is a list of people who have asked to be called as soon as the MOS isn't busy. Code on the vector is much more restricted than callback handler code; it musn't change into user mode and it must always call X-SWIs. In: R0 = address to call
    R1 = value of R12 to be called with.

    The code must preserve all registers, and exit by MOV PC, r14

    Note that it isn't necessary to do a SWI OS_SetCallBack; adding to the vector means you want to be called anyway.

    The MOS now does the following:

    On exit from a SWI or interrupt routine: While anybody is on the callback vector:

             remove the vector entry
             call them
    

    If callback has been requested, call the callback handler

    While waiting for a key in OS_ReadC or INKEY While anybody is on the callback vector:

             remove the vector entry
             call them
    

    SWI OS_ReadDefaultHandler (&55)


    This SWI can be used to read the MOS default handlers (i.e. those set at reset).

    In: R0 = reason code. The same numbers as SWI OS_ChangeEnvironment are used.

    Out: R1=address, R2=workspace, R3=buffer. 0 means not relevant.

    SWI OS_ReadSysInfo (&58)


    This takes a handle in r0, returns results depending on the handle. Currently r0=0 is the only defined one:

    In: r0 = 0 => Out: r0 = size (in bytes) screen will be after hard reset.

    SWI OS_Confirm (&59)


    If pointer visible, change pointer shape and look at mouse keys too.

                         Flushes mouse buffer first.
    
    Wait until key pressed.
    Returns: (lowercased) character in r0 (if mouse scanned, LH button = 'y',
                                            other buttons = 'n')
    
    C set for Escape
    EQ set if r0 = 'y'