. > BrazilMan
.   version 3 Roger Wilson
.library "a4atl"
.foot
$rm $c Page ~%page
.endf
.macro example
.ensure 10
.blank 2
$ss Example:$rm
.display flow
.endm
$chead _Brazil Manual_$chead
.blank 4
.picture "*" "100.0" "200.0"
 /acorn {
 /x exch def
 matrix currentmatrix
 currentpoint translate x 288 div dup scale
 /do /fill load def
 /s {16 div 72 mul } def
 /h1 36 s def /f1 .26 def
 -18 s 0 moveto
 -18 3 f1 mul add s h1 f1 mul s
  18 3 f1 mul sub s h1 f1 mul s
 18 s 0 curveto closepath do
 /h2 30 s def /f2 .17 def
 -19 s -3 s moveto
 -19 3 f2 mul add s -3 h2 f2 mul sub s
 19 3 f2 mul sub s -3 h2 f2 mul sub s
 19 s -3 s curveto closepath do
 -20.5 s -17.5 s moveto
 0 -23 s 0 -23 s 22 s -31 s curveto 17 s -33 s lineto
 0 -25 s 0 -25 s -21.25 s -19 s curveto closepath do
 -1.4 s -15 s moveto
 -1.4 s -24 s lineto 1.4 s -24 s lineto 1.4 s -15 s lineto closepath do
 setmatrix
 } def
 0 70 moveto 36 acorn
.endpicture
.blank 4
.tabset 30
.section Contents
.blank 4
$t 1. Introduction
.blank 2
$t 2. Brazil Supervisor
.blank 2
$t 3. ARM Second Processor Memory Map
.blank 2
$t 4. Brazil Kernel
.newpage
.section Introduction
This document describes a set of supervisor calls linking ARM machine code
to the Acorn 6502 MOS as used in the BBC Microcomputer. For further
information on Acorn MOS refer to the User Guide for the BBC Microcomputer,
the DFS or ADFS manual and the Advanced User Guide. Programs should assume
the use of ADFS or ANFS if they wish to do something of file system specific
nature. Refer to the $it ARM CPU Software Manual $rm for details of the machine
instruction set.
.par
The ARM Second Processor consists of an ARM CPU, memory, timing circuitry
and Acorn's Tube interface to the BBC Microcomputer. The BBC Microcomputer
serves as an IO processor; it handles all the input and output devices
(keyboard, rs423, text and graphics displays, printer, disc drives etc). The
BBC Microcomputer requires additional software from the DNFS ROM to deal with
the Tube. The ARM Second Processor contains a ROM to deal with its end of the
Tube, this is the Brazil Kernel. The ROM also contains a set of useful
utilities in the Brazil Supervisor.
.par
To start the system switch on both the BBC Microcomputer and the ARM Second
Processor. For the BBC Microcomputer to recognise the Second Processor it must
be reset or switched on _after_ the Second Processor has been switched on.
The following message, or something similar, should appear on your screen:

.display
$tt Acorn ARM Second Processor 1024K

Acorn DFS

A*
.endd
The 'A*' will appear either as A* on a blue background in mode 7 or as a
large legend in any of the other modes: it is the prompt from the Brazil
Supervisor.
.newpage
.section Brazil Supervisor
When nothing else is using the system, the Brazil Supervisor gives its A*
prompt and its built in commands can be used: anything it does not understand
will be passed to the Acorn MOS CLI. The built in commands are:
.tabset 20
.indent 20
.tempindent 0
$tt BreakClr $t $rm- removes all breakpoints or just the one at the specified
address. Puts the original contents back into the location.
.tempindent 0
$tt BreakList $t $rm- lists the currently set breakpoints.
.tempindent 0
$tt BreakSet $t $rm- set a breakpoint at an address.
.tempindent 0
$tt Buff $t $rm- turn file buffering on
.tempindent 0
$tt Continue $t $rm- start execution from breakpoint saved state. If there
is a breakpoint at the continuation position, then a prompt will be given:
reply Y if it is permissible to execute the instruction at a different
address (i.e. it does not refer to the pc).
.tempindent 0
$tt Help $t $rm- generates reassuring message from Brazil Supervisor:
gives version number of the Brazil Kernel (this manual refers to kernel version
-.008). $tt HELP SUPERVISOR $rm gives the list of commands that the
supervisor accepts.
.tempindent 0
$tt InitStore $t $rm- fills all memory with $tt &EE000000 $rm or the specified data.
.tempindent 0
$tt Memory $t $rm- displays memory in ARM words from the address or register
given to the next address or register given, a + meaning added to the first
address. Default second address means 256 bytes displayed.
.tempindent 0
$tt MemoryA $t $rm- display and alter memory in bytes or words, signalled by
an optional B or b. Given just an address/register it enters an interactive
mode: RETURN to go to next location, - to go back one location, hex digits to
alter a location and proceed, anything else to exit. Alternatively give the
data required on the command line as well.
.tempindent 0
$tt MemoryI $t $rm- disassemble ARM instructions. Syntax as for Memory. Given
a limit it proceeds to the limit, otherwise it disassembles 24 instructions
and waits for a key.
.tempindent 0
$tt NoBuff $t $rm- turns file buffering off
.tempindent 0
$tt Quit $t $rm-Leave the Brazil Supervisor by performing an $tt SWI Exit$rm.
Any other Supervisor will be returned to - or, of course, the Brazil
Supervisor itself.
.tempindent 0
$tt ShowRegs $t $rm- displays the registers caught on one of the four traps
$it (unknown instruction, address exception, data abort, address abort)
.tempindent 0
$tt Transfer $t $rm- copies files from one file area to another. Examples:
.tempindent 10
$tt transfer disc adfs fred $t $rm- copy fred from disc to adfs
.tempindent 10
$tt transfer net adfs fred jim $t $rm- copy fred from net to adfs as jim
.tempindent 10
$tt transfer disc adfs * $t $rm- ALL files in current disc directory
.tempindent 10
$tt transfer disc adfs $t $rm- prompt for file names to be typed
.tempindent 10
$tt transfer dir@$.1 dir@$.2 * $t $rm- all files in $.1 to $.2
.tempindent 10
$tt transfer net`dir@&.1 adfs * $t $rm- all files in net directory &.1 to adfs
.newline
The first two arguments are simply $tt CLI$rm ed, so they can cause quite a
wide range of effects. The character @ in the first two arguments will be
replaced by "#", the character ` in the first two arguments represents a
newline (multiple cli commands) thus one can use transfer between net
fileservers, $tt transfer fs@1.254 fs@0.126 *$rm. Transfer has special code in
it, so that, although it changes filesystems, this does not cause the exec
file to be lost.
.tempindent 0
$tt Go $t $rm- enter program at the address given. No address corresponds
to $tt &1000$rm; R0 to R15 corresponds to the contents of the registers
dumped on a trap. After the address a ; should precede the environment
string. GO is, in fact, implemented at the Brazil Kernel level, so it still
works from inside other systems. GOS enters the Brazil Supervisor: the
caller can be returned to if he has set an Exit handler using the Quit command.
.indent 0
Acorn MOS CLI commands e.g. $tt CAT, KEY $rm or sideways ROM programs
$tt TYPE $rm etc. may be used by typing them directly to the A* prompt. Refer
to the MOS, DFS, ADFS documentation for details of a particular ROM facility.
.blank
Programs from the current filing system are executed simply by typing their
names. Refer to documentation on the particular program for the parameters
it may require. Usually programs will respond to the parameter $tt -help$rm.
.blank
The A* prompt is created by redefining character 255. Spooling is disabled
while this prompt is output using fx3 calls. The character 255 is left as a
solid block. With the ARM Second Processor connected the entire character set
has been exploded, see description of $tt fx20 $rm in the User Guide.
.blank
With the Second Processor connected addresses are used to distinguish between
the memories of the two machines. The ARM Second Processor can use addresses
up to Ramtop (see section 3). The BBC Microcomputer uses addresses FFFXXXXX.
The DFS filing system only has 18 bit addressing; any address greater than
2FFFF is assumed to be in the BBC Microcomputer: use of ADFS or the net
filing systems avoids any problems of restricted addressing.
.section ARM Second Processor Memory Map
.display
$tt ======================================
| Brazil Supervisor ROM (16K)        |
====================================== &3000000
| Nothing: Aborts are caused         |
====================================== &2000000
| Tube IO chip                       |
====================================== &1000000
| Repetitions of the RAM area        |
====================================== Ramtop e.g. &100000
| File buffer RAM                    |
====================================== Ramtop-20K
| User RAM                           |
|                                    |
====================================== &1000   
| System RAM: Stacks etc.            |
====================================== &0D00
| System RAM: Brazil Kernel itself   |
====================================== &0000
.endd
Programs should load in memory at &1000 or higher. If a program is to be run
at an address outside available memory, Brazil will try "wrapping" it around
in available memory: the Twin program is supplied to run at &1D0000: in a
1/4 MByte machine it thinks it has been run at &10000, in a 1MByte machine
it thinks it has been run at &D0000. For a 4MByte machine it could be moved
to &3D0000, however due to the hardware design of the 2 and 4MByte machines
this would cause it not to work on the 2MByte machine, although it would be
fine with the full 4Mbytes. Programs should only use memory up to the Ramtop
limit returned by the GetEnv call, on an otherwise empty machine the Brazil
Kernel uses the top 20K for file buffers.
.section Brazil Kernel
All BBC Microcomputer IO is accessed through SWI calls.
.blank 2
The following information documents all the Brazil Kernel calls that a program
can make using the $tt SWI $rm instruction. $tt A, X, Y $rm represent the
$it 8 bit $tt 6502 $rm registers referred to in the Acorn MOS documentation,
$tt C $rm the $tt 6502 $rm carry flag and the $tt ARM $rm carry flag.
$tt R0 $rm etc are $tt ARM $rm registers. $tt (string) $rm is an indirect
pointer to a string terminated by hex &00, &0A or &0D. $tt R0b $rm means
lsb of $tt R0 $rm (only bottom 8 bits used as an input parameter, top 24 bits
zeroed on result). $tt R0 $rm means all 32 bits of R0. All successful
$tt SWI$rm s will clear the $tt ARM V $rm flag.
.numberpars
WriteC [&00] (Acorn MOS OSWRCH)
.blank
Write $tt R0b $rm to the terminal output.
.example
         MOV R0,~~#"H"
         SWI WriteC

In: R0b
Out:
.endd
.nextp
WriteS [&01]
.blank
Write the bytes following the call to the terminal output. Terminates at first
zero and starts execution at the next 32bit word.
.example
         SWI WriteS
         = "Hello World",10,13,0
         ALIGN
         SWI WriteI+"K"

In:
Out:
.endd
.nextp
Write0 [&02]
.blank
Write the bytes pointed to by register 0 to the terminal output. Terminates at
first zero. $tt R0 $rm points to the byte after the zero on exit.
.example
         ADD R0,PC,~~#data-.-8
         SWI Write0

In: R0
Out: R0 updated
.endd
.nextp
NewLine [&03] (Acorn MOS OSNEWL)
.blank
Write a line feed (&0A) followed by a carriage return (&0D) to the terminal
output.
.example
         SWI NewLine

In:
Out:
.endd
.nextp
ReadC [&04] (Acorn MOS OSRDCH)
.blank
Read a character and validity from the terminal input. $tt C $rm set if an
unusual character (e.g. Escape) is read.
.example
         SWI ReadC
         BCS Escape

In:
Out: R0 contains character; C contains validity
.endd
.nextp
CLI [&05] (Acorn MOS OSCLI)
.blank
Interpret a string as a command. The string is checked for HELP (or valid
abbreviations) and an appropriate message issued. An additional command over
those in the IO processor MOS is the GO command, see the data about the
Brazil Supervisor.
.example
         SWI CLI

In: R0 pointing to string
Out: may not return if another program has been executed
.endd
.nextp
Byte [&06] (Acorn MOS OSBYTE)
.blank
Do an Acorn MOS OSBYTE call with $tt A=R0b, X=R1b, Y=R2b, C=C $rm. For calls
with $tt R0b $rm less than 128 the $tt R2 $rm register is not required or
altered.
.example
         MOV R0,~~#5
         MOV R1,~~#4
         SWI Byte ;select network printer

In: R0, R1, R2
Out: R0, R1, R2, C
.endd
Note: because of the read only file buffering in Brazil the $tt OSBYTE &7F $rm
call checks $tt R1 WORD $rm for being greater than 256 (range of "fast"
handles is 257 to 511).
.nextp
Word [&07] (Acorn MOS OSWORD)
.blank
Do an Acorn MOS OSWORD call with $tt A=R0b $rm and a parameter block pointed
to by $tt R1$rm. Note that call with $tt R0b=0 $rm (Acorn MOS RDLN) does
nothing, the ReadLine call should be used instead.
.example
         MOV R0,~~#1
         SUB R1,SP,~~#5
         SWI Word ;read time

In: R0, R1 pointing to parameter block
Out: parameter block updated.
.endd
.nextp
File [&08] (Acorn MOS OSFILE)
.blank
Do an Acorn MOS OSFILE call with $tt A=R0b $rm. Instead of a parameter block
$tt R1 to R5 $rm contain the data (string pointer, load address, exec address,
start address {length}, end address {attributes}).
.example
         MOV R0,~~#5
         MOV R1,~~#ptr
         SWI File ;file info

In: R0, R1 pointing to string, R2, R3, R4, R5
Out: R2, R3, R4, R5 updated.
.endd
.nextp
Args [&09] (Acorn MOS OSARGS)
.blank
Do an Acorn MOS OSARGS call with $tt A=R0b$rm, file handle in $tt R1$rm, data
value in $tt R2$rm.
.example
         MOV R0,~~#0
         LDR R1,handle
         SWI Args ;read ptr to R2

In: R0, R1 (handle), R2
Out: R2 updated.
.endd
.nextp
BGet [&0A] (Acorn MOS OSBGET)
.blank
Read the next byte from the file whose handle is in $tt R1$rm. Byte returned
in $tt R0 $rm, validity in $tt C $rm (set if end of file). Brazil does local
buffering for Input Only and Output Only files by using handles in the range
256 to 511 - see $it Open$rm.
.example
         LDR R1,handle
         SWI BGet
         BCS EndOfFile

In: R1 (handle)
Out: R0, C.
.endd
.nextp
BPut [&0B] (Acorn MOS OSBPUT)
.blank
Write $tt R0b $rm to the file whose handle is in $tt R1$rm. Brazil does local
buffering for Input Only and Output Only files by using handles in the range
256 to 511 - see $it Open$rm.
.example
         MOV R0,~~#data
         LDR R1,handle
         SWI BPut

In: R0b, R1 (handle)
Out:
.endd
.nextp
Multiple [&0C] (Acorn MOS OSGBPB)
.blank
Read and write multiple bytes from file whose handle is in $tt R1$rm. Control
in $tt R0b$rm; addresses in $tt R2 $rm (data pointer), $tt R3 $rm (number of
bytes), $tt R4 $rm (pointer in file, if required). $tt C $rm is set if the
transfer could not be completed. Brazil local buffering does not apply to the
Multiple call.
.example
         MOV R0,~~#1
         LDR R1,handle
         MOV R2,~~#data
         MOV R3,~~#56
         MOV R4,~~#100
         SWI Multiple ;$rm put 56 bytes to file from 'data' at offset 100 $tt

In: R0b, R1 $rm handle$tt, R2 $rm points to data$tt, R3 $rm number of bytes$tt, R4 $rm position $tt
Out: R2, R3, R4 updated. C set if transfer past end of file.
.endd
.nextp
Open [&0D] (Acorn MOS OSFIND)
.blank
Open and close a file. If $tt R0b=0 $rm then the file whose handle is in
$tt R1 $rm is to be closed; if $tt R1b=0 $rm then all files on the current
filing system are closed. If $tt R0 $rm is not zero a file, whose name
$tt R1 $rm is pointing at, is to be opened, {&40 for Input only, &80 for
Output, &C0 for Update}; the file handle being returned in $tt R0$rm. Brazil
does local buffering for BGet for Input Only and for BPut for Output Only
files by using handles in the range 256 to 511: this feature can be ignored
by masking out the extra bit in the handle, but you must not mix use of the
masked and unmasked handles. Alternatively the command $tt NOBUFF $rm can be
used at the Brazil supervisor prompt (NOT as a CLI call). The buffering
produces the following times for BGet-ing a 64K file:
.display
$tt ANFS     ADFS     Brazil+ANFS  Brazil+ADFS
40sec    32sec    10sec        4sec
.endd
.example
         MOV R0,~~#&40
         MOV R1,NameAddress
         SWI Open

In: R0, R1 (handle/ pointer to name)
Out: R0 (handle if opened)
.endd
.nextp
ReadLine [&0E]
.blank
Read a line of text from the terminal. $tt R0 $rm points to the buffer where
the text will be placed; $tt R1 $rm contains the maximum possible length of
the line; $tt R2 $rm contains the lowest character which will be placed in
the buffer (excluding carriage return); $tt R3 $rm contains the highest
character which will be placed in the buffer. $tt C $rm will be set if the
buffer was terminated by Escape. The input may have been terminated by
&0D or &0A.
.example
         SUB R0,SP,~~#256
         MOV R1,~~#238
         MOV R2,~~#" "
         MOV R3,~~#255
         SWI ReadLine
         BCS Escape

In: R0, R1, R2, R3
Out: R1 length, C set if invalid.
.endd
.nextp
Control [&0F]
Set the control programs for the exception handlers.
.blank
.tabset .+3
.indent .+3
.tempindent .-3
$tt R0 $i $rm address of where to go when an error occurs. (0 for no change)
.tempindent .-3
$tt R1 $i $rm address of a buffer for error status. (0 for no change)
.tempindent .-3
This will contain:
.newline
$tt[R1,~~#0] $it PC $rm when error occured e.g. just after the SWI which called Brazil
.newline
$tt[R1,~~#4] $rm cardinal: error number provided with the error.
.newline
$tt R1+8$rm error string, terminated with a 0
.newline
Continue after errors is simple: just have a handler that reloads the PC with
that in the block; it may like to set the V flag so that the retried code
knows what has happened (normal SWIs clear it). R0 may be incorrect
.tempindent .-3
$ttR2 $i $rm address of escape routine handler. (0 for no change)
.newline
Entered with $tt R11 $rm bit 6 as escape status.
.newline
$tt R12 $rm contains 0/-1 if not in/in the Kernel presently
.newline
$tt R11 $rm and $tt R12 $rm may be altered. Return with $tt MOV PC,R14$rm
.newline
If $tt R12 $rm contains 1 on return then the Callback will be used
.tempindent .-3
$ttR3 $rm address of event handler. (0 for no change)
.newline
Entered with $tt R0, R1 $rm and $tt R2 $rm containing the $tt A, X $rm and
$tt Y $rm parameters. $tt R0, R1, R2, R11 $rm and $tt R12 $rm may be altered.
Return with $tt MOV PC,R14$rm.
.newline
$tt R12 $rm contains 0/-1 if not in/in the Kernel presently.
.newline
$tt R13 $rm contains the IRQ handling routine stack. When you return to the
system $tt LDMFD R13!,{R0,R1,R2,R11,R12,PC}^ $rm will be executed.
If $tt R12 $rm contains 1 on return then the Callback will be used
.indent .-3
.blank         
The handlers are initialised and do not normally need setting. Errors will
cause the error message and number to be written to the terminal. Escape
updates will be counted: the program will be terminated on the third. The
default event handler does nothing. Addresses of 0 do not update the
respective information field. All handlers are reset in Brazil's Supervisor
(* prompt) or when a program is run using CLI.
.example
         MOV R0,errorh
         SUB R1,SP,~~#256
         MOV R2,~~#0
         MOV R3,~~#0
         SWI Control ;control errors

In: R0, R1, R2, R3
Out: previous values
.endd
.nextp
GetEnv [&10]
.blank
Read the program environment.
.display
$tt R0 $rm address of the command string (0 terminated) which ran the program
$tt R1 $rm address of the permitted RAM limit e.g. &10000 for 64K machine.
$tt R2 $rm address of 5 bytes - the time the program started running
.endd
.example
         SWI GetEnv
         SWI Writes ;write environment string to terminal

In:
Out: R0, R1, R2
.endd
.nextp
Exit [&11]
.blank
Leave the program and return to the Brazil Supervisor * prompt. Brazil will
print the time for which the program ran.
.example
         SWI Exit

In: irrelevant
Out: never returns
.endd
.nextp
SetEnv [&12]
.blank
Set the program environment. This call should only be used to alter the
overall environment for sub-programs.
.display
$tt R0 $rm address of the exit routine for Exit above to go to (or 0 if no change)
$tt R1 $rm address of the end of memory limit for GetEnv to read (or 0 if no change)
$tt R2 $rm address of the real end of memory (or 0 if no change)
$tt R3 $rm 0 for no local buffering, 1 for local buffering (anything else no change)
$tt R4 $rm address of routine to handle undefined instructions (or 0 if no change)
$tt R5 $rm address of routine to handle prefetch abort (or 0 if no change)
$tt R6 $rm address of routine to handle data abort (or 0 if no change)
$tt R7 $rm address of routine to handle address exception (or 0 if no change)
.endd
Undefined, abort and exception handlers are initialised on using CLI to run a program.
.example
         ADR R0,EXITROUT
         MOV  R1,~~#&10000
         MOV  R2,~~#0
         MOV  R3,~~#4
         MOV  R4,~~#0
         MOV  R5,~~#0
         MOV  R6,~~#0
         MOV  R7,~~#0
         SWI  SetEnv ;make a small machine

In: R0, R1, R2, R3, R4, R5, R6, R7
Out: previous values in R0, R1, R2, R3, R4, R5, R6, R7
.endd
.nextp
IntOn [&13]
.blank
Enable interrupts.
.nextp
IntOff [&14]
.blank
Disable interrupts.
.nextp
CallBack [&15]
.blank
On an Escape Update or Event routine the user may modify his own flags but
cannot call the system with an SWI call if it was in the Kernel since Brazil
is using the Tube Hardware and would thus become deadlocked. The solution is
a CallBack on Kernel Exit - as the thread of control leaves the kernel,
instead of returning to the original caller the registers are saved in a save
block and a different routine is entered; any necessary kernel calls can be
made and then control can be resumed by reloading from the register save block.
.display
$tt R0 $rm sets the address of the register save block
$tt R1 $rm sets the address of the callback routine
.endd
.example
         ADR   R0,savblock
         ADR   R1,nullroutine
         SWI   CallBack

nullroutine:
         ADDR  R0,savblock
         LDMIA R0,&FFFF^

In: R0, R1
Out: previous values in R0, R1
.endd
.nextp
EnterSVC [&16]
.blank
Gives the caller SVC privilege mode. One should not then use $tt R13 $rm or
rely on $tt R14 $rm being preserved across SWI calls. Exit back to user mode
with $ttTEQP PC,~~#0$rm.
.nextp
BreakPt [&17]
.blank
Cause a break point trap. See BreakCtrl (next).
.nextp
BreakCtrl [&18]
.blank
When the BreakPt SWI is made all the user mode registers will be dumped in a
block and execution continued at the Break control routine. The user can be
continued with a $tt LDMIA <block>,&FFFF^$rm.
.display
$tt R0 $rm sets the address of the register save block; 0 for no change
$tt R1 $rm sets the address of the control routine; 0 for no change

$tt In: R0, R1
Out: previous values in R0, R1
.endd
.nextp
UnusedSWI [&19]
.blank
SWIs of values 512 onwards can be used to add new SWI function calls.
.blank
$tt R0 $rm sets the address of the unused SWI handler; 0 for no change
.blank
The following code has been executed before the handler is reached:
.display
$tt SPSVC  RN R13
TUBER  RN R12
SVCWK0 RN R11
SVCWK1 RN R10
SVC  STMFD SPSVC!,{TUBER,SVCWK0,SVCWK1}
     BIC   TUBER,R14,~~#CCMASK
     LDR   SVCWK0,[TUBER,~~#-4]
     BIC   SVCWK0,SVCWK0,~~#&FF000000
     CMP   SVCWK0,~~#512
     LDRCS PC,HISERV
.endd
The old address should be used to return to the user so as to process any
outstanding CallBacks: Brazil Kernel does the following:-
.display
$tt SLVK LDR   SVCWK0,DOCALL
     TEQ   SVCWK0,~~#1
     BEQ   SKCL
     LDMFD SPSVC!,{TUBER,SVCWK0,SVCWK1}
     BICS  PC,R14,~~#&10000000 ;clear V flag
DOCALL & 0
SKCL MOV   TUBER,~~#0
     TEQP  PC,~~#&0C000003
     STR   TUBER,DOCALL
     LDR   TUBER,CALLBF
     STMIA TUBER!,{R0,R1,R2,R3,R4,R5,R6,R7,R8,R9}
     LDMFD SPSVC!,{R0,R1,R2} ;get TUBER,SVCWK0,SVCWK1 (10,11,12)
     STMIA TUBER!,{R0,R1,R2,R13,R14}^ ;$rm write those 3 and user's 13,14$tt
     BICS  R14,R14,~~#&10000000 ;clear V flag
     STMIA TUBER!,{R14} ;user's PC
     LDR   PC,CALLAD

In: R0
Out: previous value in R0
.endd
.nextp
UpdateMEMC [&1A]
.blank
The $it MEMC $rm chip is a Write Only Memory $it WOM $rm device. Brazil
kernel maintains a software copy of it's current state and provides a kernel
call to update MEMC, which of course (when present) is only accessible by
non-user modes of ARM. To allow the programming of individual bits the call
takes a field and a mask. The new MEMC value is:
.display
$tt newMEMC := (oldMEMC AND NOT R1) OR (R0 AND R1)
R0 := oldMEMC

In: new bits in field R0, field mask R1
Out: previous state of MEMC register
.endd
.nextp
SetCallBack [&1B]
.blank
This kernel call sets the internal call back flag: when the kernel is next exited a CallBack will occur (not when this call to the kernel exits).
.display
$tt In:
Out:
.endd
.nextp
Mouse [&1C]
.blank
This kernel call reads the mouse. Values are 0..65535 or 0..7 (bit 0 is right
down, bit 1 is middle down, bit 2 is left down).
.display
$tt In:
Out: R0 (X), R1 (Y), R2 (buttons)
.endd
.nextp
WriteI [&100]
.blank
Write the character contained in the bottom byte of the SWI call.
.example
         SWI WriteI+" " ;write a space

In:
Out:
.endd
