
\documentclass[12pt,twoside]{report}

\usepackage{a4}
\usepackage{verbatim}

%\input{epsf}

\usepackage{graphicx}
\usepackage{epstopdf}
\DeclareGraphicsRule{.eps}{pdf}{.pdf}{`epstopdf #1}
\pdfcompresslevel=9

%\makeindex

\raggedbottom  % try to avoid widows and orphans

\sloppy
\clubpenalty1000%
\widowpenalty1000%

\addtolength{\oddsidemargin}{6mm}  % adjust margins
\addtolength{\evensidemargin}{-8mm}  % adjust margins

%\renewcommand{\baselinestretch}{1.1} % adjust line spacing to make 
                                      % more readable

\newcommand{\IMPL}[3]{\hspace*{\fill}\small CIN:#1, POS:#2, NAT:#3\\}
 
\begin{document}

\bibliographystyle{plain}

\thispagestyle{empty}

\begin{center}
{\huge {\bf The BCPL Cintsys and Cintpos}}

\bigskip
{\huge {\bf User Guide}}

\Large
\vspace{2mm}
{\it by}
\vspace{2mm}

{\bf Martin Richards}

{\small\verb|mr10@cl.cam.ac.uk|}

{\small\verb|http://www.cl.cam.ac.uk/users/mr10/|}
\vspace{2mm}

{Computer Laboratory

University of Cambridge

Revision date: \input{date}
}
\end{center}

\section*{Abstract}

BCPL is a simple systems programming language with a small fast
compiler which is easily ported to new machines. The language was
first implemented in 1967 and has been in continuous use since then.
It is a typeless and provides machine independent pointer arithmetic
allowing a simple way to represent vectors and structures.  BCPL
functions are recursive and variadic but, like C, does not allow
dynamic free variables, and so can be represented by just their entry
addresses.  There is no built-in garbage collector and all
input-output is done using library calls.

This document describes both the single-threaded BCPL Cintcode System
(called Cintsys) and the Cintcode version of the Tripos portable
operating system (called Cintpos). It gives the definition of standard
BCPL including the recently added features such as floating point
expressions and constructs involving operators such as {\tt<>} and
{\em op\tt:=}. The language has recently been extended to include some
of the pattern matching features of MCPL.  This manual also describes
the standard library and running environment and the native code
version of the system based on SIAL (Simple Intermediate Assembly
Lanugage).  Installation instructions are included. Since May 2013,
the standard BCPL distribution supports both 32- and 64-bit Cintcode
versions.  Since August 2014, standard Cintcode BCPL includes
floating-point constants and operators, and since March 2018 it
includes the FLT (float flag) feature to make it easier to perform
floating-point calculations.  Pattern matching feature was added in
September 2021.  These extensions are now in the standard BCPL
distribution.

\medskip
\noindent
{\bf Keywords:}  Systems programming language, BCPL, Cintcode, Cintpos

\cleardoublepage

\setcounter{page}{1}
\pagenumbering{roman}
\pagestyle{headings}

\tableofcontents

\cleardoublepage


\chapter*{Preface}
\addcontentsline{toc}{chapter}{Preface}

The concept for BCPL originated in 1966 and was first outlined in my
PhD thesis \cite{Richards66}.  Its was first implemented early in 1967
when I was working at M.I.T.  Its heyday was perhaps from the mid 70s
to the mid 80s, but even now it is still continues to be used at some
universities, in industry and by private individuals. It is a useful
language for experimenting with algorithms and for research in
optimizing compilers. Cintpos is the multi-tasking version of the
system based on the Tripos \cite{Tripos79}. It is simple and easy to
maintain and can be used for real-time applications such as process
control.  BCPL was designed many years ago but is still useful in
areas where small size, simplicity and portability are important.
Recently I have decided to augment BCPL with some of the features of
MCPL including particularly the pattern matching mechanism used in
the definition of functions.

This document is intended to provide a record of the main features of
the BCPL in sufficient depth to allow a serious reader to obtain a
proper understanding of philosophy behind the language.  An efficient
interpretive implementation is presented, the source of which is
freely available via my home page \cite{MyHomePage}. The
implementation is machine independent and should be easy to transfer
to almost any architecture both now and in the future.

The main topics covered by this report are:

\begin{itemize} 
\item
A specification of the BCPL language.
  
\item
A description of its runtime library and the extensions used in the
Cintpos system.

\item
The design and implementation of command language interpreters for
both the single and multi-threaded versions of the system.

\item
A description of OCODE, the intermediate code used in the compiler,
and Cintcode, the compact byte stream target code used by the
interpreter.
  
\item
A description of the single and multi-threaded interactive debugger
and other debugging aids.
  
\item
The efficient implementation of the Cintcode interpreter for several
processors including both RISC and i386/Pentium based machines.
  
\item
The profiling and statistics gathering facilities offered by the
system.

\item
The SIAL intermediate code that allows easy translation of BCPL in
native code for most architectures, including, for instance, the
Raspberry Pi.

\item
The MC package that allows machine independent dynamic compilation and
execution of native machine code.

\end{itemize} 

\smallskip
For many example BCPL programs see {\tt bcpl4raspi.pdf} available from
my home page.

\bigskip
\leftline{MR}
%\leftline{Date as above}

\cleardoublepage

\setcounter{page}{1}
\pagenumbering{arabic}
\pagestyle{headings}


\chapter{The System Overview}

This document contains a full description of an interpretive
implementation of BCPL that supports a command language and low level
interactive debugger.  As an introduction, two example console
sessions are presented to exhibit some of the key features of both the
single threaded version of the system (Cintsys) and the interpretive
version of Tripos (Cintpos).

\section{A Cintsys Console Session}

The BCPL Cintcode system can be entered using the {\tt cintsys} shell
command under the host operating system. If {\tt cintsys} is called
with the {\tt-h} option it will output the following information about
other possible options.

\smallskip
{\small
\begin{verbatim}
Valid arguments:
  
-h            Output this help information
-m n          Set Cintcode memory size to n words
-t n          Set Tally vector size to n words
-g n          Set the default global vector upb to n
-q            Set quiet mode. This stops the resident system
              fromm outputing text other than error messages and
              and debugging aids. It also stops the CLI from
              outputting prompts and stops the echoing of
              standar input (normally the keyboard).
-c args       Pass args to interpreter as CLI input
-- args       Pass args to interpreter as CLI input,
              then re-attach stdin
-s file args  Invoke the interpreter with this file as CLI input
-cin name     Set the pathvar environment variable name
-f            Trace use of environment variables in pathinput
-v            Trace the bootstrapping process
-vv           As -v, but include some Cincode level tracing
-d            Cause a dump of the Cintcode memory to DUMP.mem
              if a fault/error is encountered
-slow         Force the slow interpreter to always be selected
\end{verbatim}
}

\smallskip
The Cintsys system is normally started using the {\tt cintsys} shell
command. This demonstration was run when I was logged in as user {\tt
  mr} on a machine called {\tt Cobham}. The BCPL Cintcode system was
already properly installed. The demonstration was run in the root
directory of the BCPL Cintcode system as was entered as follows.

\medskip{\renewcommand{\baselinestretch}{0.8}\small\begin{verbatim} 
mr@Cobham~$ cd $BCPLROOT
mr@Cobham~/distribution/BCPL/cintcode$
mr@Cobham~/distribution/BCPL/cintcode$ cintsys

BCPL 32-bit Cintcode System (18 Jul 2022)
0.000> 
\end{verbatim}
}

\smallskip

The characters \verb|0.000>| are followed by a space character and is
the command language prompt string inviting the user to type a
command.  The number gives the execution time in seconds of the
preceding command. A program called {\tt fact.b} in directory {\tt
cintcode/com} to compute factorials can be displayed using the {\tt type}
command as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000> type com/fact.b
GET "libhdr"

LET start() = VALOF
{ FOR i = 1 TO 5 DO writef("fact(%n) = %i4*n", i, fact(i))
  RESULTIS 0
}

AND fact(n) = n=0 -> 1, n*fact(n-1)
0.000>
\end{verbatim}
}

The directive \verb|GET "libhdr"| \index{GET directive} causes the
standard library declarations to be inserted at that position.  The
text:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET start() = VALOF
\end{verbatim}
}

\noindent
is the heading for the declaration of the function \verb|start| which,
by convention, is the first function to be called when a program is
run.  The empty parentheses \verb|()| indicate that the function
expects no arguments.  The text

{\small
\begin{verbatim}
FOR i = 1 TO 5 DO
\end{verbatim}
}

\noindent
introduces a for-loop whose control variable \verb|i| successively
takes the values from \verb|1| to \verb|5|.  The body of the for-loop
is a call of the library function \verb|writef| whose effect is to
output the format string after replacing the substitution items
\verb|%n| and \verb|%i4| by appropriately formatted representations of
\verb|i| and \verb|fact(i)|.  \index{\tt fact} Within the string
\verb|*n| represents the newline character.  The statement
\verb|RESULTIS 0| exits from the \verb|VALOF| construct providing the
result of \verb|start| that indicates the program completed
successfully.  The text:

{\small
\begin{verbatim}
AND fact(n) =
\end{verbatim}
}

\noindent
introduces the definition of the function \verb|fact| which take one
argument (\verb|n|) and yields \verb|n| factorial.  The word {\tt AND}
causes {\tt fact} and {\tt start} to be defined simultaneously allow
{\tt start} to call {\tt fact}. This program can be compiled by using
the following command:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000> bcpl com/fact.b to fact

32 bit BCPL (18 Jul 2022) with pattern matching, 32 bit target
Code size =   104 bytes 0f 32-bit little ender Cintcode
0.034>
\end{verbatim}
}

\noindent
This command compiles the source file \verb|fact.b| creating an
executable object module in the file called \verb|fact|.  The program
can then be run by simply typing the name of this file.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.034> fact
fact(1) =    1
fact(2) =    2
fact(3) =    6
fact(4) =   24
fact(5) =  120
0.006> 
\end{verbatim}
}

When the BCPL compiler is invoked, it can be given additional
arguments that control the compiler options.  One of these ({\tt d1})
directs the compiler to output the compiled code in a readable form,
as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.010> bcpl com/fact.b to fact d1

BCPL (3 Sep 2019) 32 bit with the FLT feature
   0:  DATAW 0x00000000
   4:  DATAW 0x0000DFDF
   8:  DATAW 0x6174730B
  12:  DATAW 0x20207472
  16:  DATAW 0x20202020
// Entry to:   start      
  20: L10:
  20:     L1  
  21:    SP3  
  22: L12:
  22:    LP3  
  23:     LF  L2
  25:     K9  
  26:    SP9  
  27:    LP3  
  28:    SP8  
  29:    LLL  L19920
  31:    K4G   94
  33: L15:
  33:     L1  
  34:    AP3  
  35:    SP3  
  36:     L5  
  37:    JLE  L12
  39: L14:
  39: L13:
  39:     L0  
  40:    RTN  
  44: L19920:
  44:  DATAW 0x6361660F
  48:  DATAW 0x6E252874
  52:  DATAW 0x203D2029
  56:  DATAW 0x0A346925
  60:  DATAW 0x0000DFDF
  64:  DATAW 0x6361660B
  68:  DATAW 0x20202074
  72:  DATAW 0x20202020
// Entry to:   fact       
  76: L11:
  76:   JNE0  L16
  78:     L1  
  79:    RTN  
  80: L16:
  80:    LM1  
  81:    AP3  
  82:     LF  L11
  84:     K4  
  85:    LP3  
  86:    MUL  
  87:    RTN  
  88:  DATAW 0x00000000
  92:  DATAW 0x00000001
  96:  DATAW 0x00000014
 100:  DATAW 0x0000005E
Code size = 104 bytes 0f 32-bit little ender Cintcode
0.050>
\end{verbatim}
}

\noindent
This output shows the sequence of Cintcode instructions compiled for
the functions {\tt start} and {\tt fact}.  In addition there are some
data words holding the string constant, initialisation data and
symbolic information for the debugger.  The data word at location 4
holds a special bit pattern indicating the presence of a function name
placed just before the entry point.  As can be seen the name in this
case is {\tt start}.  Similar information is packed at location 60 for
the function {\tt fact}.  Most Cintcode instructions occupy one byte
and perform simple operations on the registers and memory of the
Cintcode machine.  For instance, the first two instructions of {\tt
  start} ({\tt L1} and {\tt SP3} at locations 20 and 21) load the
constant {\tt1} into the Cintcode {\tt A} register and then stores it
at word 3 of the current stack frame (pointed to by {\tt P}).  This
corresponds to the initialisation of the for-loop control variable
{\tt i}.  The start of the for-loop body has label {\tt L12}
corresponding to location 22.  The compilation of {\tt fact(i)} is
{\tt LP3~LF~L11~K9} which loads {\tt i} and the entry address of {\tt
  fact} and enters the function incrementing {\tt P} by {\tt 9}
locations.  The result of this function is returned in {\tt A} which
is stored in the stack using {\tt SP9} in the appropriate position for
the third argument of the call of {\tt writef}.  The second argument,
{\tt i}, is setup using {\tt LP3~SP8}, and the first argument which is
the format string is loaded by {\tt LLL~L19920}.  The next instruction
({\tt K4G~94}) causes the routine {\tt writef}, whose entry point is
in global variable 94, to be called incrementing {\tt P} by 4 words as
it does so.  Thus the compilation of the call {\tt
  writef("fact(\%n)~=~\%i5*n",~i,~f(i))} occupies just 11 bytes from
location 22 to 32, plus the 16 bytes at location 44 where the string
is packed.  The next three instructions ({\tt L1~AP3~SP3}) increment
{\tt i}, and {\tt L5~JNE~L12} jumps to label L12 if {\tt i} is less
than or equal to {\tt5}.  If the jump is not taken, control falls
through to the instructions {\tt L0~RTN} causing {\tt start} to return
with result {\tt 0}.  Each instruction of this function occupies one
byte except for the {\tt LF}, {\tt LLL}, {\tt K4G} and {\tt JNE}
instructions which each occupy two.  The body of the function {\tt
  fact} is equally easy to understand.  It first tests whether its
argument is zero ({\tt JNE0~L10}).  If it is, it returns one ({\tt
  L1~RTN}).  Otherwise, it computes {\tt n-1} by loading {\tt-1} and
adding {\tt n} ({\tt LM1~AP3}) before calling {\tt fact} ({\tt
  LF~L11~K4}).  The result is then multiplied by {\tt n} ({\tt
  LP3~MUL}) and returning ({\tt RTN}).  The space occupied by this
code is just 12 bytes.

The debugger can be entered using the abort command.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.030> abort

!! ABORT 99: User requested
*
\end{verbatim}
}

\noindent
The asterisk is the prompt inviting the user to enter a debugging
command.  The debugger provides facilities for inspecting and changing
memory as well as setting breakpoints and performing single step
execution.  As an example, a breakpoint is placed at the first
instruction of the routine \verb|clihook| which is used by the command
language interpreter (CLI) to transfer control to a command.  Consider
the following commands:

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
* g4 b1
* b
1:   clihook     
*
\end{verbatim}
}

\noindent
This first loads the entry point of \verb|clihook| (held in global
variable 4) and sets (\verb|b1|) a breakpoint numbered 1 at this
position.  The command \verb|b|, without an argument, lists the
current breakpoints confirming that the correct one has been set.
Normal execution is continued using the \verb|c| command.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
* c
0.006>
\end{verbatim}
}

If we now try to execute the factorial program, we immediately hit the 
breakpoint.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000> fact

!! BPT 1:        clihook
    A=            0 B=            0   25172:    K4G  1   (=G1)
*
\end{verbatim}
}

\noindent
This indicates that the breakpoint occurred when the Cintcode
registers {\tt A} and {\tt B} were both zero, and that the program
counter is set to 25172 where the next instruction to be obeyed is
\verb|K4G 1|. Single step exection can now be performed using the
\verb|\| command.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
* \ A=            0 B=            0   60124:     L1
* \ A=            1 B=            0   60125:    SP3
* \ A=            1 B=            0   60126:    LP3
* 
\end{verbatim}
}

\noindent
After each single step execution, a summary of the current state is
printed.  In the above sequence we see that the execution of the
instruction \verb|L1| loading \verb|1| into the \verb|A| register.
The execution of \verb|SP3| does not have an immediately observable
effect since it updates a local variable held in the current stack
frame, but the stack frame can be displayed using the \verb|t|
command.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
* p t4

P    0:        60276        25174        start            1
*
\end{verbatim}
}

\noindent
This confirms that location \verb|P3| contains the value \verb|1|
corresponding to the initial value of the for-loop control variable
\verb|i|.  At this stage it is possible to change its value to
\verb|3|, say.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
* 3 sp3
* p t4

P    0:        60276        25174        start            3
*
\end{verbatim}
}

If single stepping is continued for a while we observe the evaluation 
of the recursive call \verb|fact(3)|.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
* \ A=            3 B=            1   60127:     LF  60180
* \ A=         fact B=            3   60129:     K9
* \ A=            3 B=            3   60180:   JNE0  60184
* \ A=            3 B=            3   60184:    LM1
* \ A=           -1 B=            3   60185:    AP3
* \ A=            2 B=            3   60186:     LF  60180
* \ A=         fact B=            2   60188:     K4
* \ A=            2 B=            2   60180:   JNE0  60184
* \ A=            2 B=            2   60184:    LM1
* \ A=           -1 B=            2   60185:    AP3
* \ A=            1 B=            2   60186:     LF  60180
* \ A=         fact B=            1   60188:     K4
* \ A=            1 B=            1   60180:   JNE0  60184
* \ A=            1 B=            1   60184:    LM1
* \ A=           -1 B=            1   60185:    AP3
* \ A=            0 B=            1   60186:     LF  60180
* \ A=         fact B=            0   60188:     K4
* \ A=            0 B=            0   60180:   JNE0  60184
* \ A=            0 B=            0   60182:     L1
* \ A=            1 B=            0   60183:    RTN
* \ A=            1 B=            0   60189:    LP3
* \ A=            1 B=            1   60190:    MUL
* \ A=            1 B=            1   60191:    RTN
* \ A=            1 B=            1   60189:    LP3
* \ A=            2 B=            1   60190:    MUL
* \ A=            2 B=            1   60191:    RTN
* \ A=            2 B=            1   60189:    LP3
* \ A=            3 B=            2   60190:    MUL
* \ A=            6 B=            2   60191:    RTN
* \ A=            6 B=            2   60130:    SP9
* \ A=            6 B=            2   60131:    LP3
* \ A=            3 B=            6   60132:    SP8
* \ A=            3 B=            6   60133:    LLL  60148
* \ A=        15037 B=            3   60135:    K4G  94   (=G94)
*
\end{verbatim}
}

\noindent
At this moment the routine \verb|writef| is just about to be entered
to print an message about factorial 3.  We can unset breakpoint 1 and
continue normal execution by typing \verb|0b1 c|.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
* 0b1 c
fact(3) =    6
fact(4) =   24
fact(5) =  120
0.036>
\end{verbatim}
}

\noindent
As one final example in this session we will re-compile the BCPL
compiler.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.010> bcpl com/bcpl.b to junk

32 bit BCPL (18 Jul 2022) with pattern matching, 32 bit target
Code size = 21824 bytes of 32-bit little ender Cintcode
Code size = 20544 bytes of 32-bit little ender Cintcode
Code size = 15832 bytes of 32-bit little ender Cintcode
0.569>
\end{verbatim}
}

\noindent
This shows that the total size of the compiler is 58,200 bytes and
that it can be compiled (on a 2.17GHz CPU) in 0.569~seconds. Since this
involves executing 54,579,958 Cintcode instructions, the rate is about
96 million Cintcode instructions per second with the current
interpreter. This Cintcode execution rate can be confirmed by running
the {\tt sysinfo} command.

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.569> sysinfo

TGZDATE: Fri  3 Mar 16:55:54 GMT 2023
Build: Linux
Flags: SOUND CALLC
The hst is a little ender machine
Host address size = 64 bits
BCPL word size    = 32 bits
Execution rate    = 96,796,486 Cintcode instrctions per second

1.642>
\end{verbatim}
}



\section{A Cintpos Console Session}

When the Cintpos system is started (on a machine called meopham) in
the directory \verb|Cintpos/cintpos|, its opening message is as
follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
meopham$ cintpos

Cintpos System (09 Mar 2010)
0.000 1> 
\end{verbatim}
%$
}

There is a directory called {\tt com} that holds the BCPL source code
of several Cintpos commands, such as {\tt bcpl.b}, {\tt bench100.b}
and {\tt fact.b}. We can inspect {\tt fact.b} using the {\tt type}
command as follows.

{\label{factdemo}\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000 1> type com/fact.b
SECTION "fact"

GET "libhdr"

LET f(n) = n=0 -> 1, n*f(n-1)

LET start() = VALOF
{ FOR i = 1 TO 10 DO
    writef("f(%i2) = %i8*n", i, f(i))
  RESULTIS 0
}
0.000 1> 
\end{verbatim}
%$
}

\noindent
It can be compiled and run as follows.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000 1> c bc fact
bcpl com/fact.b to cin/fact hdrs POSHDRS 

BCPL (20 Oct 2009)
Code size =   120 bytes
0.020 1> fact
f( 1) =        1
f( 2) =        2
f( 3) =        6
f( 4) =       24
f( 5) =      120
f( 6) =      720
f( 7) =     5040
f( 8) =    40320
f( 9) =   362880
f(10) =  3628800
0.000 1> 
\end{verbatim}
%$
}

\noindent
There is a benchmark program called {\tt bench100.b} which can be
compiled and run as follows.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000 1> c bc bench100
bcpl com/bench100.b to cin/bench100 hdrs POSHDRS 

BCPL (20 Oct 2009)
Code size =  1444 bytes
0.040 1> bench100

bench mark starting, Count=1000000

starting

finished
qpkt count = 2326410  holdcount = 930563
these results are correct
end of run
9.170 1> 
\end{verbatim}
%$
}

\noindent
The latest prompt ({\tt 9.170 1>}) indicates that the benchmark
program took 9.17 seconds to run and that we are connected to the root
command language interpreter running as task one.

When Cintpos starts these are six resident tasks which can be seen
using the {\tt status} command as follows.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000 1> status
Task  1: Root_Cli         running CLI         Loaded command: status     
Task  2: Debug_Task       waiting DEBUG      
Task  3: Console_Handler  waiting COHAND     
Task  4: File_Handler     waiting FH0        
Task  5: MBX_Handler      waiting MBXHAND    
Task  6: TCP_Handler      waiting TCPHAND    
0.010 1> 
\end{verbatim}
%$
}

\noindent
Task 2 is an interactive debugging aid, task 3 handles communication
between tasks and the keyboard and display devices, task 4 handles
communication between tasks and the filing system, task 5 provides a
mailbox facility that allows communication of short text messages
between tasks and, finally, task 6 handles TCP/IP communication
between tasks and the internet.

Tasks may be dynamically created and destoyed. For instance, the
{\tt run} command will create a new CLI task giving it a command
to run.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.010 1> run status
0.000 1> Task  1: Root_Cli         waiting CLI        No command loaded
Task  2: Debug_Task       waiting DEBUG      
Task  3: Console_Handler  waiting COHAND     
Task  4: File_Handler     waiting FH0        
Task  5: MBX_Handler      waiting MBXHAND    
Task  6: TCP_Handler      waiting TCPHAND    
Task  7: Run_Cli          running CLI         Loaded command: status     
\end{verbatim}
%$
}

\noindent
Notice that the root CLI (task 1) completes the execution of the {\tt run}
command and issues a prompt ({\tt0.000 1>}) before the newly created CLI
(task 7) has had time to load and run the {\tt status} command.
As soon as task 7 finishes running the {\tt status} command it commits
suicide leaving the original 6 tasks.


The {\tt bounce.b} program provides a demonstration of how
communication between Cintpos tasks works.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000 1> type com/bounce.b
SECTION "bounce"

GET "libhdr"

LET start() BE qpkt(taskwait()) REPEAT
0.000 1> 
\end{verbatim}
%$
}

\noindent
It can be compiled and run as follows.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000 1> c bc bounce
bcpl com/bounce.b to cin/bounce hdrs POSHDRS 

BCPL (20 Oct 2009)
Code size =    60 bytes
0.010 1> run bounce
0.000 1> status
Task  1: Root_Cli         running CLI         Loaded command: status     
Task  2: Debug_Task       waiting DEBUG      
Task  3: Console_Handler  waiting COHAND     
Task  4: File_Handler     waiting FH0        
Task  5: MBX_Handler      waiting MBXHAND    
Task  6: TCP_Handler      waiting TCPHAND    
Task  7: Run_Cli          waiting CLI         Loaded command: bounce     
0.000 1>
\end{verbatim}
%$
}

\noindent
The {\tt status} output shows that the {\tt bounce} program is running
as task 7 and is suspended in {\tt taskwait} waiting for another task
to send it a packet. When it receives a packet it immediately returns
it to the sender and waits for another to arrive.  We can send a
suitable packet to {\tt bounce} using the {\tt send} command whose
source code is as follows.

{\renewcommand{\baselinestretch}{0.75}\small
\begin{verbatim} 
0.000 1> type com/send.b
SECTION "send"

GET "libhdr"

GLOBAL { task: 200; count: 201 }

LET start() BE 
{ LET pkt = VEC 2
  LET argv = VEC 50

  UNLESS rdargs("TASK/n,COUNT/n", argv, 50) DO
  { writef("Bad arguments for SEND*n")
    stop(20)
  }

  task, count := 7, 1_000_000
  IF argv!0 DO task  := !argv!0
  IF argv!1 DO count := !argv!1

  pkt!0, pkt!1, pkt!2 := notinuse, task, count

  writef("*nSending a packet to task %n, %n times*n", task, count)

  { LET k = pkt!2
    UNLESS k BREAK
    pkt!2 := k-1
    qpkt(pkt)
    pkt := taskwait()
  } REPEAT

  writes("Done*n")
}
0.010 1> 
\end{verbatim}
%$
}

\noindent
This program creates a packet consisting of a vector (one dimensional
array) of three elements. The first is used by the system for chaining
packets together and must be initialised the the special value {\tt
notinuse}. The next element of the packet (\verb|pkt!1|) holds the
destination task number and the final element (\verb|pkt!2|) holds a
value (initially 1000000) which is going to be used as a counter.  The
{\tt REPEAT} loop decrements this counter field and sends the packet
using {\tt qpkt} to the bounce task suspending itself in {\tt
taskwait} until the packet returns. Control leaves the {\tt REPEAT}
loop when the counter reaches zero, causing {\tt send} to output the
message {\tt Done}.  We can compile and run {\tt send} as follows.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.010 1> c bc send
bcpl com/send.b to cin/send hdrs POSHDRS 

BCPL (20 Oct 2009)
Code size =   252 bytes
0.020 1> send

Sending a packet to task 7, 1000000 times
Done
3.940 1> 
\end{verbatim}
%$
}

\noindent
This demonstration shows that a packet may be sent from one task to
another 2 million times in 3.94 seconds. This corresponds to a rate of
just over half a million times per second.
 

\cleardoublepage


\chapter{The BCPL Language}

The design of BCPL owes much to the work done on CPL (originally
Cambridge Programming Language) which was conceived at Cambridge to be
the main language to run on the new and powerful Ferranti Atlas
computer to be installed in 1963.  At that time there was another
Atlas computer in London and it was decided to make the development of
CPL a joint project between the two Universities.  As a result the
name changed to Combined Programming Language. It could reasonably be
called Christopher's Programming Language in recognition of Christpher
Strachey whose bubbling enthusiasm and talent steered the course of
its development.

CPL was an ambitious language in the ALGOL tradition but with many
novel and significant extensions intended to make its area of
application more general.  These included a greater richness in
control constructs such as the now well known \verb|IF|,
\verb|UNLESS|, \verb|WHILE|, \verb|UNTIL|, \verb|REPEATWHILE|,
\verb|SWITCHON| statements.  It could handle a wide variety of data
types including string and bit patterns and was one of the first
strictly typed languages to provided a structure mechanism that
permitted convenient handling of lists, trees and directed graphs.
Work on CPL ran from about 1961 to 1967, but was hampered by a number
of factors that eventually killed it.  It was, for instance, too large
and complicated for the machines available at the time, and the desire
for elegance and mathematical cleanliness outweighed the more
pragmatic arguments for efficiency and implementability.  Much of the
implementation was done by research students who came and left during
the lifetime of the project.  As soon as they knew enough to be useful
they had to transfer their attention to writing theses.  Another
problem (that became of particular interest to me) was that the
implementation at Cambridge had to move from EDSAC II to the Atlas
computer about halfway through the project.  The CPL compiler thus
needed to be portable.  This was achieved by writing it in a simple
subset of CPL which was then hand translated into a sequence of low
level macro calls that could be expanded into the assembly language of
either machine.  The macrogenerator used was GPM\cite{Strachey65}
designed by Strachey specifically for this task.  It was a
delightfully elegant work of art in its own right it is well worth
study.  A variant of GPM, called BGPM, is included in the standard
BCPL distribution.

BCPL was initially similar to this subset of CPL used in the encoding
of the CPL compiler.  An outline of BCPL's main features first
appeared in my PhD thesis \cite{Richards66} in 1966 but it was not
fully designed and implemented until early the following year when I
was working at Project MAC of the Massachussetts Institute of
Technology.  Its first implementation was written in Ross's Algol
Extended for Design (AED-0)\cite{Ross64} which was the only language
then available on CTSS, the time sharing system at Project MAC, other
than LISP that allowed recursion.

\section{Language Overview}

A BCPL program is made up of separately compiled sections, each
consisting of a list of declarations that define the constants, static
data and functions belonging to the section.  Within functions it is
possible to declare dynamic variables and vectors that exist only as
long as they are required.  The language is designed so that these
dynamic quantities can be allocated space on a runtime stack.  The
addressing of these quantities is relative to the base of the stack
frame belonging to the current function activation.  For this to be
efficient, dynamic vectors have sizes that are known at compile time.
Functions may be called recursively and their arguments are called by
value.  The effect of call by reference can be achieved by passing
pointers. Input and output and other system operations are provided by
means of library functions.

The main syntactic components of BCPL are: expressions, commands, and
declarations.  These are described in the next few sections.  In
general, the purpose of an expression is to compute a value, while the
purpose of a command is normally to change the value of one or more
variables or to perform input/output.


\subsection{Comments}

There are two form of comments.  One starts with the symbol {\tt //}
and extends up to but not including the end-of-line character, and the
other starts with the symbol {\tt /*} and ends at a matching
occurrence of {\tt */}.  Comment brackets ({\tt /*} and {\tt */} may
be nested, and within such a comments the lexical analyser is only
looking for {\tt /*} and {\tt */} and so special care is needed when
commenting out fragments of program containing {\tt//} comments and
string constants.  Comments are equivalent to white space and so may
not occur within of multi-character symbols such as identifiers or
constants.

\subsection{The {\tt GET} Directive}

A directives of the form {\tt GET~"}{\em filename}{\tt"} is replaced
by the contents of the named file. Early versions of the compiler only
inserted the file up to the first occurring dot but now the entire
file is inserted. By convention, {\tt GET} directives normally appear
on separate lines. If the filename does not end in {\tt.h} or {\tt.b}
the extension {\tt.h} is added.

The name is looked up by first searching the current directory and
then the directories specified by the environment variable whose name
is held in the {\tt rtn\_hdrsvar} of the rootnode, but this can be
overridden using the {\tt hdrs} compiler option.  The default
environment variable for BCPL headers is {\tt BCPLHDRS} under Cintsys
and {\tt POSHDRS} under Cintpos. Header files are normally in the {\tt
g/} directory in the root directory of the current system. To check
whether the environment variables are set correctly, enter {\tt
cintsys} or {\tt cintpos} with the {\tt-f} option as suggested in
Section~\ref{envvars}.

\subsection{Conditional Compilation}

A simple mechanism, whose implementation takes fewer than 20 lines of
code in the lexical analyser allows conditional skipping of lexical
symbols. It uses directives of the following form:

\begin{flushleft}
\hspace{15mm}\verb|$$|{\em tag}\\
\hspace{15mm}\verb|$<|{\em tag}\\
\hspace{15mm}\verb|$~|{\em tag}\\
\hspace{15mm}\verb|$>|{\em tag}\\
\end{flushleft}

\noindent
where {\em tag} is conditional compilation tag composed of letters,
digits, dots and underlines.  All tags are initially unset, but may be
complemented using the \verb|$$|{\em tag} directive.  All the lexical
tokens between \verb|$<|{\em tag} and \verb|$>|{\em tag} are skipped
(treated as comments) unless the specified tag is set. All the lexical
tokens between \verb|$~|{\em tag} and \verb|$>|{\em tag} are skipped
unless the specified tag is not set. 

The following example shows how this conditional compilation feature
can be used.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
$$Linux                    // Set the Linux conditional compilation tag

$<Linux                    // Include if the Linux tag is set
  $<WinXP $$WinXP $>WinXP  // Unset the WinXP tag if set
  writef("This was compiled for Linux")
$>Linux
$<WinXP                    // Include if the WinXP tag is set
  writef("This was compiled for Windows XP")
$>WinXP
\end{verbatim}
\end{samepage}

\subsection{Section Brackets}

Historically BCPL used the symbols {\tt \$(} and {\tt\$)} to bracket
commands and declarations. These symbols are called section brackets
and are allowed to be followed by tags composed of letters, digits,
dots and underlines. A tagged closing section bracket is forced to
match with its corresponding open section bracket by the automatic
insertion of extra closing brackets. Use of this mechanism
is no longer recommended since it often leads to obscure programming
errors. BCPL has been extended to allow all untagged section
brackets to be replaced by \verb|{| and \verb|}| as appropriate.


\section{Expressions}

Expressions are composed of names, constants and expression operators
and may be grouped using parentheses.  The precedence and
associativity of the different expression constructs is given in
Section~\ref{exprprec}.  BCPL expressions always vield values of the
same size, normally of length 32 or 64 bits.


\subsection{\label{names}Names}

A name is of a sequence of letters, digits, dots and underlines
starting with a letter, but it must not one of the reserved words
(such as {\tt IF}, {\tt WHILE} or {\tt RESULTIS}). The use of dots in
names is no longer recommended, and should be replaced by underscores.
Double dots are no longer permitted in names because {\tt..}  is the
range operator used in the pattern matching extension.

A name may be declared as a local variable, a static variable, a
global variable, a manifest constant, a label or a function or
routine.  Since the language is typeless, the value of a name is just
a bit pattern whose interpretation depends on how it is used. This is
similar to the way values in central registers of most computers are
used.

\subsection{\label{constants}Constants}

Decimal numbers consist of a sequence of digits, while binary, octal
or hexadecimal are represented, respectively, by \verb|#B|, \verb|#O|
or \verb|#X| followed by digits of the appropriate sort. Letters in
hexadecimal numbers may use both upper and lower case and the case of
the letters {\tt B}, {\tt O} or {\tt X} after \verb|#|. The {\tt O}
may be omitted in octal numbers.  Underlines may be inserted within
numbers to improve their readability.  The following are examples of
valid numbers:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
          1234
          1_234_456
          #B_1011_1100_0110
          #o377
          #X3fff
          #x_DEADC0DE
\end{verbatim}
\end{samepage}

Since August 2014, floating point constants are now allowed, such as
the following:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
          1234.0
          12.
          .34
          1.234_456e-5
          10e6
\end{verbatim}
\end{samepage}

\noindent

Note that {\tt12.34} is a floating point number, but {\tt12..34} is
{\tt12} followed by the range operator {\tt..} and {\tt34}.  A
floating point constant must contain a decimal point ({\tt.}) or an
exponent sign ({\tt e} or {\tt E}). A decimal point can start or end a
floating point number.

BCPL uses the standard IEEE representation for floating point numbers
using the same word length as other BCPL values For 32-bit BCPL the
format is as follows. The left most bit is the sign with 1
representing negative.  The next 8 bits hold an unsigned number $e$ in
the range 0 to 255. $e=0$ and $e=255$ are used to specify in the
representation of some special values such as zero, infinity or
various error values. The values between 1 and 254 specify binary
exponents in the range -126 to +127 equal to $e-127$.  The remaining
23 bits are the fractional bits of the significand.  For non zero
values, the significand has 24 bits with its left most bit being 1
followed by these 23 fractional bits.  This represents a value greater
than or equal to 1.0 and less than 2.0. Note that 1+8+23=32. The value
of the floating point number is the significand multiplied by
$2^{e-127}$.  As a special case, the number 0.0 is represented by a
bit pattern of zeroes.

For 64-bit numbers the exponent has 11 bits and the significand has
53. Note that 1+11+52=64.

The compiler does not use any floating point operators or constants
using, where necessary, calls of the form {\tt sys(Sys\_flt,...)} to
perform any floating point calculations needed. This allows the
compiler to be compiled using older versions of the compiler.
Floating point constants are currently only compiled correctly if the
BCPL word length of the compiler is the same as that of the target
code.

{\tt TRUE} and {\tt FALSE} are reserved words that have values {\tt-1}
and {\tt 0}, respectively, representing the two truth values. They can
be used in manifest constant expressions.  Whenever a boolean test is
made, the value is compared with with {\tt FALSE} ({\tt=0}).  {\tt
  BITSPERBCPLWORD} is also a reserved word whose value is 32 or 64
giving the BCPL word length currently being used.  This constant was
added on 16 May 2013 to allow the same header file to be used on both
32- and 64-bit BCPL systems. It is used in the MANIFEST declarations
of constants such as {\tt bytesperword} and {\tt minint} that are word
length dependent.  If you are using an older BCPL compiler with the
latest version of {\tt libhdr.h} you will need to un-comment a line
that declares {\tt BITSPERBCPLWORD} as a MANIFEST constant with the
appropriate value for the system you are using.

The so called Jump commands {\tt BREAK}, {\tt LOOP}, {\tt NEXT}, {\tt
  EXIT}, {\tt ENDCASE}, {\tt RETURN}, {\tt RESULTIS E} and {\tt GOTO
  E} are now permitted in expressions and have the same effect as the
corresponding commands as described in
Section~\ref{breakcommand}. They all provide a way to escape from the
normal flow of execution of expressions.  Except for {\tt RESULTIS E}
they provide nothing new since they could all have been prefixed by
{\tt VALOF} and have the same effect they have always had. The only
new feature is that {\tt RESULTIS E} will escape to an already
existing {\tt VALOF} block enclosing the current expression.

A question mark ({\tt?}) may be used as a constant with undefined
value.  It can also be used in statements such as:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
          LET a, b, count = ?, ?, 0
          sendpkt(notinuse, rdtask, ?, ?, Read, buf, size)
\end{verbatim}
\end{samepage}

Constants of the form: {\tt SLCT}~{\em len}{\tt:}{\em shift}{\tt:}{\em
offset} pack the three constants {\em len}, {\em shift} and {\em
offset} into a word.  Such packed constants are used by the field
selection operator {\tt OF} to access fields of given length, shift
and offset relative to a pointer as described in
Section~\ref{infixed}. The {\em len} and {\em shift} components are
optional. Their omission has the following effect.

\bigskip
\noindent
\begin{tabular}{lll}
{\tt SLCT}~{\em shift}{\tt:}{\em offset} & means &
{\tt SLCT~0:}{\em shift}{\tt:}{\em offset}\\
{\tt SLCT}~{\em offset} & means & 
{\tt SLCT~0:0:}{\em offset}
\end{tabular}
\bigskip

Character constants consist of a single character enclosed in single
quotes ({\tt'}).  Character constants behave like integers typically
in the range 0 to 255 corresponding to its normal ASCII encoding, but
can be larger using unicode characters as describer below.

\label{stringescapes}
Character (and string) constants may use the following
escape sequences.

\bigskip
\begin{center}
\begin{tabular}{|p{14mm}|p{100mm}|}
\hline
Escape         & Replacement \rule[-3mm]{0mm}{8mm}\\ \hline
\verb|*n|     & A newline (end-of-line) character.\\
\verb|*c|     & A carriage return character.  \\
\verb|*p|     & A newpage (form-feed) character.  \\
\verb|*s|     & A space character.  \\
\verb|*b|     & A backspace character.  \\
\verb|*t|     & A tab character.  \\
\verb|*e|     & An escape character.  \\
\verb|*"|     & \verb|"|  \\
\verb|*'|     & {\tt '}  \\
\verb|**|     & \verb|*|  \\
\verb|*x|$hh$ & The single character with number $hh$ (two hexadecimal 
                digits denoting an integer in the range [0,255]). \\
\verb|*|$ddd$ & The single character with number $ddd$ (three 
                octal digits denoting an integer in the range [0,255]). \\
\verb|*#g|    & Set the encoding mode to GB2312 for the rest of this
                string or character constant. The default encoding is UTF8
                unless speified by the GB2312 compiler option, See the
                specification of the {\tt bcpl} command on 
                page~\pageref{bcplcommand}.\\
\verb|*#u|    & Set the encoding mode explicitly to UTF8 for the rest of
                 this string or character constant.\\
\verb|*#|$hhhh$ & In UTF8 mode, this specifies a single Unicode character
                  with up to four hexadecimal digits.  In string constants,
                  this is converted to a sequence of bytes giving its UTF-8
                  representation. In character constants, it yields the
                  integer $hhhh$. Thus \verb|'*#C13F'=#xC13F|. \\
\verb|*##|$h..h$ & In UTF8 mode, this specifies a Unicode character with up to 
                   eight hexadecimal digits, but is otherwise treated
                   as the \verb|*#hhhh| escape. \\
\verb|*#|$dddd$ & In GB2312 mode, this specifies the GB2312 decimal code
                  ($dddd$) for an extended character.  In string constants,
                  this is converted to a sequence of bytes giving its GB2312
                  representation. In character constants, it yields the
                  integer $dddd$. Thus \verb|'*#g*#4566'=4566|. \\

\verb|*|$f..f$\verb|*|
              & This sequence is ignored, 
                where $f..f$ stands for a sequence of white space
                characters. In this context, comments introduced by
                {\tt'//'} are treated as white space, but those
                introduced by {\tt'/*'} are not. \\
\hline 
\end{tabular} 
\end{center}

\bigskip

A string constant consists of a sequence of zero or more characters
enclosed within quotes ({\tt "}).  Both string and character constants
use the same character escape mechanism described above.  The value of
a string is a pointer where the length and bytes of the string are
packed.  If {\tt s} is a string then {\tt s\%0} is its length and {\tt
s\%1} is its first character, see Section~\ref{infixed}.  The
\verb|*#| escapes allow Unicode and GB2312 characters to be handled.
For instance, if the following statements output to a suitable UTF8
configured device:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
          writef("*#uUnicode hex 2200 prints as: '*#2200'*n")
          writef("%%# in writef can also be used: '%#'*n", #x2200)
\end{verbatim}
\end{samepage}

\noindent
the result is as follows

\medskip
\begin{samepage}
\noindent
\verb|Unicode hex 2200 prints as: '|$\forall$\verb|'|
\noindent
\verb|%# in writef can also be used: '|$\forall$\verb|'|
\end{samepage}

\medskip
\noindent
A static vector can be created using an expression of the following
form: {\tt TABLE~}$K_0,\ldots,K_n$ where $K_0,\ldots,K_n$
are manifest constant expressions, see Section~\ref{manexpr}.  The
space for a static vector is allocated for the life time of the
program and its elements are updateable.

\subsection{\label{calls}Function Calls}

Syntactically, a function call is an expression followed by a,
possibly empty, argument list enclosed in paretheses as in the
following examples.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
          newline()
          mk3(Mult, x, y)
          writef("f(%n) = %n*n", i, f(i))
          f(1,2,3)
          (fntab!i)(p, @a)
\end{verbatim}
\end{samepage}

\noindent
The parentheses are required even if no arguments are given.  The last
example above illustrates a call in which the function is specified by
an expression. If the function being called was defined by a routine
definition, the result of the call will be undefined. The arguments
are evaluated and laid out in consecutive stack locations where they
become the initial values of the formal parameters of the called
function or routine. There is no need for the number of arguments to
be the same as the number of formal parameters. See
Section~\ref{procdecl} for more details. If the expression specifying
the function to be called has the {\tt FLT} tag the so does the result
of the call.


\subsection{\label{mthcalls}Method Calls}

Method calls are designed to make an object oriented style of
programming more convenient.  They are syntactically similar to a
function calls but uses a hash symbol (\verb|#|) to separate the
function specifier from its arguments.  The expression:

\medskip
\begin{center}
$E$\verb|#(|$E_1${\tt,..,}$E_n${\tt)}
\end{center}

\medskip
\noindent
is defined to be equivalent to:

\medskip
\begin{center}
{\tt(}$E_1${\tt!0!}$E${\tt)(}$E_1${\tt,..,}$E_n${\tt)}
\end{center}

\medskip
\noindent
Here, $E_1$ points to the fields of an object, with the convention
that its zeroth field ($E_1${\tt!0}) is a pointer to the methods
vector containing the possible functions to call.  Element $E$ of this
vector is applied to the given set of arguments.  $E$ is normally a
manifest constant. An example program illustrating method calls can be
found in {\tt BCPL/bcplprogs/demos/objdemo.b} in the BCPL
distribution.


\subsection{Prefixed Expression Operators}

An expression of the form {\tt!}$E$ returns the contents of the memory
word pointed to by the value of $E$.

An expression of the form {\tt@}$E$ returns a pointer to the BCPL word
sized location specified by $E$.  $E$ can only be a variable name or
an expression with leading operator {\tt!}. Pointers to consecutive
locations are consecutive integers.

Expressions of the form: {\tt+}$E$, {\tt-}$E$, {\tt ABS} $E$,
\verb|~|$E$ and {\tt NOT} $E$ return the result of applying the given
prefixed operator to the value of the expression $E$.  The operator
{\tt+} returns the value unchanged, {\tt-} returns the integer
negation, {\tt ABS} returns the absolute value, \verb|~| return the
bitwise complement of the value.
 
{\tt FLOAT \em E} converts the integer {\em E} to its corresponding
floating point value.  {\tt FIX \em E} converts the floating point
value {\em E} to its closest integer representation. {\tt\#ABS \em E}
returns the absolute value of the floating point number {\em E}, and
{\tt\#+} and {\tt\#-} perform monadic plus and minus on floating point
values.


\subsection{\label{infixed}Infixed Expression Operators}

An expression of the form $E_1${\tt!}$E_2$ evaluates $E_1$ and $E_2$
to yield respectively a pointer, $p$ say, and an integer, $n$ say.
The value returned is the contents of the $n^{th}$ word relative to
$p$. Since words of memory have consecutive integer addresses, the
expression $E_1${\tt!}$E_2$ is exactly equivalent to
{\tt!(}$E_1${\tt+}$E_2${\tt)}.

An expression of the form $E_1${\tt[}$E_2${\tt]} has recently
been added. It is syntactically like a function call but is equivalent
to $E_1${\tt!}$E_2$.

An expression of the form $E_1${\tt\%}$E_2$ evaluates $E_1$ and $E_2$
to yield a pointer, $p$ say, and an integer, $n$ say.  The expression
returns the unsigned byte at position $n$ relative to $p$.

\label{slctop}
An expression of the form $K$~{\tt OF}~$E$ \/accesses a field of
consecutive bits in memory. $K$ must be a manifest constant (see
section~\ref{manexpr}) equal to {\tt SLCT}~{\em length}{\tt:}{\em
shift}{\tt:}{\em offset} and $E$ must yield a pointer, $p$ say. The
field is contained entirely in the word at position $p${\tt+}{\em
offset}. It has a bit length of {\em length} and is {\em shift} bits from
the right hand end of the word. A length of zero is interpreted as the
longest length possible consistent with {\em shift} and the word length
of the implementation.

An {\tt OF} expression can be used on right and left hand sides
of assignments but not as the operand of \verb|@|. When used in a
right hand context the selected field is shifted to the right
with vacated positions filled with zeros. A shift to the
left is performed when a field is updated. Suppose \verb|p!3| holds
\verb|#x12345678|, the expression \verb|(SLCT 12:8:3) OF p| yields
\verb|#x456| and after the assignment:

\bigskip
\centerline{\tt (SLCT 12:8:3) OF p := \#xABC}
\bigskip
\noindent
the value of \verb|p!3| will be \verb|#x123ABC78|.

\noindent
The operator {\tt::} is a synonym of {\tt OF}.


An expression of the form $E_1${\tt<<}$E_2$ (or $E_1${\tt>>}$E_2$)
evaluates $E_1$ and $E_2$ to yield a bit pattern, $w$ say, and an
integer, $n$ say, and returns the result of shifting $w$ to the left
(or right) by $n$ bit positions.  Vacated positions are filled with
zeroes. Shifts of the word length or more return 0, and negative
shifts return undefined typically zero results, although on some
versions of BCPL they reverse the direction of the shift.

Expressions of the form: $E_1${\tt*}$E_2$, $E_1${\tt/}$E_2$,
$E_1$~{\tt MOD}~$E_2$, $E_1${\tt+}$E_2$, $E_1${\tt-}$E_2$.  $E_1$~{\tt
  EQV}~$E_2$ and $E_1$~{\tt XOR}~$E_2$ return the result of applying
the given operator to the two operands.  The operators are,
respectively, integer multiplication, integer division, remainder
after integer division, integer addition, integer subtraction, bitwise
equivalent and bitwise not equivalent (exclusive OR).

Expressions of the form: $E_1${\tt\&}$E_2$ and $E_1${\tt|}$E_2$
return, respectively, the bitwise AND or OR of their operands unless
the expression is being evaluated in a boolean context such as the
condition in a while command, in which case the operands are tested
from from left to right until the value of the condition is known.

An expression of the form: $E$~{\em relop}~$E$~{\em relop}~\ldots~{\em
relop}~$E$ where each {\em relop} is one of {\tt =}, \verb|~=|, {\tt
<=}, {\tt >=}, {\tt <} or {\tt >} returns {\tt TRUE} if all the
individual relations are satisfied and {\tt FALSE}, otherwise.  The
operands are evaluated from left to right, and evaluation stops as
soon as the result can be determined.  Operands may be evaluated more
than once, so don't try \verb|'0'<=rdch()<='9'|.

An expression of the form: $E_1${\tt ->}$E_2${\tt,}$E_3$ evaluates
$E_1$ in a boolean context, and, if this yields {\tt FALSE}, it
returns the value of $E_3$, otherwise it returns the value of $E_2$.

The floating point operators {\tt\#*}, {\tt\#/}, {\tt\#+}, {\tt\#-},
{\tt\#=}, \verb|\#~=|, {\tt\#<}, {\tt\#>}, {\tt\#<=}, {\tt\#>=} and
{\tt\#->} have recently been added to standard BCPL. They have the
same binding power as the corresponding integer operators. Beware
that, with older versions of the BCPL compiler that do not implement
the FLT feature, it is easy make mistakes such as {\tt -1.2} which
performs integer negation of the bit patterns representing {\tt 1.2}.
The expression should have been written {\tt\#-1.2}. With the FLT
feature {\tt-} would have been automatically replaced by {\tt\#-} in
this situation. See Section~\ref{fltfeature} for details.

\subsection{Boolean Evaluation}

Expressions used to control the flow of execution in coditional
constructs, as in {\tt IF} and {\tt WHILE} commands, are evaluated
in a {\em Boolean context}. This effects the treatment of the operators
\verb|~| {\tt\&} and {\tt|} whose operands are evaluated in Boolean
contexts. In a Boolean context, the operands of {\tt\&} and {\tt|} are
evaluated from left to right until the value of the condition is
known, and \verb|~| negates the condition.


\begin{samepage}

\subsection{\label{matchexp}{\tt MATCH} Expressions}

A {\tt MATCH} expression has the following form:

\medskip
\begin{tabular}{p{15mm}l}
      &{\tt MATCH (} {\em args} {\tt)}\\
      &{\tt:} $P$ {\tt,..,} $P$ {\tt=>} {\em E}\\
      &{\tt...}\\
      &{\tt:} $P$ {\tt,..,} $P$ {\tt=>} {\em E}\\
      &{\tt.}
\end{tabular}
\end{samepage}

\medskip
\noindent
It consists of the word {\tt MATCH} followed by a list of arguments
enclosed in parentheses, followed by a sequence of one or more match
items terminated by an optional dot. The match items are applied to
the arguments as described in Section \ref{patterns}, yielding the
value of the expression in the first match item to be satisfied.  If
the {\tt MATCH} expression is being evaluated in {\tt FLT} mode, all
its result expressions are evalated in {\tt FLT} mode. If none are
satisfied the result is zero (either 0 or 0.0).

Within a match item the command {\tt NEXT} causes control to pass to
the next match item, and {\tt EXIT} causes the {\tt MATCH} expression
to terminate yielding the value 0 or 0.0.

\begin{samepage}

\subsection{\label{everyexp}{\tt EVERY} Expressions}

An {\tt EVERY} expression has the following form:

\medskip
\begin{tabular}{p{15mm}l}
      &{\tt EVERY (} {\em args} {\tt)}\\
      &{\tt:} $P$ {\tt,..,} $P$ {\tt=>} {\em E}\\
      &{\tt...}\\
      &{\tt:} $P$ {\tt,..,} $P$ {\tt=>} {\em E}\\
      &{\tt.}
\end{tabular}
\end{samepage}

\medskip
\noindent

It consists of the word {\tt EVERY} followed by a list of arguments
enclosed in parentheses, followed by a squence of one or more match
items terminated by an optional dot. The match items are applied to
the arguments as described in Section \ref{patterns}, yielding the sum
of the values of the expressions of successful match items. IF the
{\tt EVERY} expression is being evaluated in {\tt FLT} mode, all it
result expressions are also evaluated in {\tt FLT} mode and the sum
performed using {\tt\#+}. If none are succesful the result is 0 or
0.0.

Within a match item the command {\tt NEXT} causes control to pass to
the next match item, and {\tt EXIT} causes the {\tt EVERY} expression
to terminate yielding the sum accumulated so far.

\subsection{{\tt VALOF} Expressions}

An expression of the form {\tt VALOF}~$C$, where $C$ is a command, is
evaluated by executing the command $C$.  On encountering a command of
the form {\tt RESULTIS}~$E$ within $C$, execution terminates,
returning the value of $E$ as the result. {\tt VALOF} expressions are
often used as the bodies of functions.

\subsection{\label{exprprec}Expression Precedence}

So that the separator semicolon ({\tt;}) can be omitted at the end of
lines, there is the restriction that infixed operators may not occur
as the first token of a line.  If the first token on a line is {\tt
  !}, {\tt +} or \verb|-|, these must be prefixed operators.

The syntax of BCPL is specified by the diagrams in Appendix A, but a
summany of the precendence of expression operators is given in
table~\ref{precedence}.  The precedence values are in the range 0 to
10, with the higher values signifying greater binding power. The
letters L and R denote the associativity of the operators.  For
instance, the dyadic operator {\tt-} is left associative and so {\tt
a-b-c} is equivalent to {\tt (a-b)-c}, while {\tt a->x,b->y,z} is
right associative and so is equivalent to {\tt a->x,(b->y,z)}.

\begin{table}[tbh!]
\begin{center}
\begin{tabular}{|l|l|c|}
\hline  %-----------------------------------------------------------
10  & Names, Literals, {\tt?}, &                              \\
    & {\tt TRUE}, {\tt FALSE}, {\tt BITSPERBCPLWORD}, &       \\
    & {\tt BREAK}, {\tt LOOP}, {\tt ENDCASE}, &               \\
    & {\tt NEXT}, {\tt EXIT}               &                  \\
    & {\tt RETURN}, {\tt RESULTIS}         &                  \\
    & {\tt(E)},                            &                  \\
    & Function and method calls            &                  \\
    & Subscripted expressions using {\tt[} and {\tt]} &       \\
10  & {\tt SLCT :}                         & SLCT constant    \\
\hline  %-----------------------------------------------------------
9L  & \verb|!   %   OF|                    &       Dyadic     \\
8   & \verb|FLOAT FIX !   @|               &       Monadic    \\
\hline  %-----------------------------------------------------------
8L  & \verb|*  /  MOD     #*  #/  #MOD| &                     \\
\hline  %-----------------------------------------------------------
7   & \verb|+  -  ABS     #+  #-  #ABS| & Monadic and Dyadic          \\
\hline  %-----------------------------------------------------------
6   & \verb| =   ~=   <=   >=   <   >|  & Extended Relations    \\
    & \verb|#=  #~=  #<=  #>=  #<  #>|                      \\
\hline  %-----------------------------------------------------------
5L  & \verb|<<  >>|                        &                  \\
\hline  %-----------------------------------------------------------
4   & \verb|~|                             & Bitwise and Boolean operators \\
4L  & {\tt \&}                             &                       \\
3L  & {\tt |}                              &                       \\
2L  & \verb|EQV XOR|                       &                  \\
\hline  %-----------------------------------------------------------
1R  & {\tt -> ,}                           & Conditional expressions\\
\hline  %-----------------------------------------------------------
0   & {\tt MATCH EVERY VALOF TABLE}        &                        \\
\hline  %-----------------------------------------------------------
\end{tabular}
\end{center}
\caption{\label{precedence}Operator precedence}
\end{table}

\begin{samepage}
\noindent
Notice that these precedence values imply that

\begin{center}
\begin{tabular}{|rcl|}
\hline
\verb|! f (x,y)|          & means & \verb|! (f (f,y))| \\
\verb|FLOAT v!i|          & means & \verb|FLOAT (v!i)| \\
\verb|! @ x|              & means & \verb|! (@ x)| \\
\verb|@ ! x|              & means & \verb|@ (! x)| \\
\verb|! v ! i ! j|        & means & \verb|! ((v!i)!j)| \\
\verb|@ v ! i ! j|        & means & \verb|@ ((v!i)!j)| \\
\verb|x << 1+y >> 1|      & means & \verb|(x<<(1+y))>>1)| \\
\verb|~ x!y|              & means & \verb|~ (x!y)| \\
\verb|~ x=y|              & means & \verb|~ (x=y)| \\
\verb|b1-> x, b2 -> y,z|  & means & \verb|b1 -> x, (b2 -> y, z)| \\
\verb|b1->  b2 -> x,y, z| & means & \verb|b1 -> (b2 -> x, y), z| \\

\hline
\end{tabular}
\end{center}
\end{samepage}

\subsection{\label{manexpr}Manifest Constant Expressions}

Manifest constant expressions are expressions whose values can be
determined before the program is run.  They may only consist of
manifest constant names, numbers and character constants, {\tt TRUE},
{\tt FALSE}, {\tt BITSPERBCPLWORD}, {\tt?}, the operators {\tt MOD},
{\tt SLCT}, {\tt FIX}, {\tt FLOAT}, {\tt*}, {\tt/}, \verb|+|,
\verb|-|, {\tt ABS}, the relational operators, {\tt\#*}, {\tt\#/},
\verb|#+|, \verb|#-|, {\tt\#ABS}, {\tt\#MOD}, the floating point
relational operators, \verb|<<|, \verb|>>|, {\tt NOT}, \verb|~|,
\verb|&|, \verb/|/, {\tt EQV}, {\tt XOR}, and conditional expressions.
Manifest expressions are used in {\tt MANIFEST}, {\tt GLOBAL} and {\tt
  STATIC} declarations, the upper bound in vector declarations and the
step length in {\tt FOR} commands, and as the left hand operand of
{\tt OF}.

Manifest constants are evaluated at compile time using arithmetic of
the word length of the compiler. So on a 32 bit compiler, integers can
only be represented correctly if they have no more than about 9
decimal digits and floating point constants will have a precision
limited to 6 or 7 digits, and this will be true even when compiling
for a 64 bit target. When using a 64 bit compiler integers may have up
to 18 of 19 digits and the precision of floating point numbers is
about 15 digits. If a 64 bit compiler has a 32 bit target the range
and precision of constants is, of course, limited to what can be
represented by 32 bit words.

\section{Commands}

The primary purpose of commands is to update variables, to perform
input/output operations, and to control the flow of control.
They are described in the following sections.

\subsection{Assignments}

Simple assignments have the following possible forms:

\smallskip

\centerline{$L${\tt:=}$E$}
\centerline{$L${\tt\#:=}$E$}
\centerline{$L${\em op\tt:=}$E$}

\smallskip

\noindent
where {\em op} is one of the following operators: \verb|!|, \verb|*|,
\verb|/|, \verb|MOD|, \verb|+|, \verb|-|, \verb|#*|, \verb|#/|,
\verb|#MOD|, \verb|#*|, \verb|#-|, \verb|<<|, \verb|>>|, \verb|&|,
\verb/|/, \verb|EQV| or \verb|XOR| and $L$ is a variable name or an
expression of one of the following forms: $E_1${\tt!}$E_2$, {\tt!}$E$,
$E_1${\tt\%}$E_2$, \%{\tt\%}$E$ or $K$ {\tt OF} $E$. $K$ is normally a
selector of the form {\tt SLCT \em length\tt:\em shift\tt:\em
  offset}. For {\tt :=} and {\tt\#:=} assignments, the right hand side
is evaluated and used to update the location specified by the left
hand side. For {\em op\tt:=} assignments, the value to assign is
$L${\em op\tt:=}$R$. If {\tt\#} is present a floating point assignment
is performed. This causes the right hand side to be evaluated in FLT
mode with the restriction that the left hand side must refer to a full
word. See Section~\ref{fltfeature} for details. Typical simple
assignments are as follows:

\smallskip
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
          cg_x := 1000
          v!i := x+1
          !ptr := mk3(op, a, b)
          str%k := ch
          %strp := 'A'
          SLCT 8:10:1 OF p +:= 1
          p &:= #x7F
          w!p #*:= a
\end{verbatim}
\end{samepage}

\smallskip
\noindent
Assignments are not permitted to start with any of the following
keywords: {\tt MATCH},  {\tt EVERY},  {\tt BREAK},  {\tt LOOP},  {\tt
  ENDCASE},  {\tt NEXT} or {\tt EXIT}.

\bigskip

A multiple assignment has the following possible forms:

\bigskip
\centerline{$L_1${\tt,..,}$L_n$ {\tt:=} $E_1${\tt,..,}$E_n$}
\centerline{$L_1${\tt,..,}$L_n$ {\tt\#:=} $E_1${\tt,..,}$E_n$}
\centerline{$L_1${\tt,..,}$L_n$ {\em op\tt:=} $E_1${\tt,..,}$E_n$}
\bigskip

\noindent
These constructs allows a single command to make several assignments
without the need to have to enclose them in section brackets.  The
assignments are done strictly from left to right and are exactly
eqivalent to:

\bigskip
\centerline{$L_1${\tt:=}$E_1$ {\tt;}\ldots {\tt;} $L_n$ {\tt:=} $E_n$}
\centerline{$L_1${\tt\#:=}$E_1$ {\tt;}\ldots {\tt;} $L_n$ {\tt\#:=} $E_n$}
\centerline{$L_1${\em op\tt:=}$E_1$ {\tt;}\ldots {\tt;} $L_n$ {\em op\tt:=} $E_n$}
\bigskip

This conversion is performed before the application of the rules of
the FLT feature.  See Section~\ref{fltfeature} for details.

\subsection{Routine Calls}

Both function calls and method calls as described in sections
\ref{calls} and \ref{mthcalls} are allowed to be executed as
commands. Any results produced are discarded.

\subsection{Conditional Commands}

The syntax of the three conditional commands is as follows:

\begin{flushleft}
\hspace{15mm}{\tt IF} $E$ {\tt DO} $C_1$\\
\hspace{15mm}{\tt UNLESS} $E$ {\tt DO} $C_2$\\
\hspace{15mm}{\tt TEST} $E$ {\tt THEN} $C_1$ {\tt ELSE} $C_2$\\
\end{flushleft}

\noindent
where $E$ denotes an expression and $C_1$ and $C_2$ denote commands.
The symbols {\tt DO} and {\tt THEN} are synonyms and may be omitted
whenever they are followed by a command keyword.  To execute a
conditional command, the expression $E$ is evaluated in a Boolean
context.  If it yields a non zero value and $C_1$ if present is
executed.  If it yields zero and $C_2$ if present is executed.

\subsection{\label{repcom}Repetitive Commands}

The syntax of the repetitive commands is as follows:

\begin{flushleft}
\hspace{15mm}{\tt WHILE} $E$ {\tt DO} $C$\\
\hspace{15mm}{\tt UNTIL} $E$ {\tt DO} $C$\\
\hspace{15mm}$C$ {\tt REPEAT}\\
\hspace{15mm}$C$ {\tt REPEATWHILE} $E$ \\
\hspace{15mm}$C$ {\tt REPEATUNTIL} $E$ \\
\hspace{15mm}{\tt FOR} $N$ {\tt=} $E_1$ {\tt TO} $E_2$ 
{\tt BY} $K$ {\tt DO} $C$\\
\hspace{15mm}{\tt FOR} $N$ {\tt=} $E_1$ {\tt TO} $E_2$ {\tt DO} $C$\\
\hspace{15mm}{\tt FOR} $N$ {\tt=} $E_1$ {\tt BY} $K$ {\tt DO} $C$\\
\hspace{15mm}{\tt FOR} $N$ {\tt=} $E_1$ {\tt DO} $C$\\
\end{flushleft}

The symbol {\tt DO} may be omitted whenever it is followed by a
command keyword.  The {\tt WHILE} command repeatedly executes the
command $C$ as long as $E$ is non-zero.  The {\tt UNTIL} command
executes $C$ until $E$ is zero.  The {\tt REPEAT} command executes $C$
indefinitely.  The {\tt REPEATWHILE} and {\tt REPEATUNTIL} commands
first execute $C$ then behave like {\tt WHILE}~$E$~{\tt DO}~$C$ or
{\tt UNTIL}~$E$~{\tt DO}~$C$, respectively.

A {\tt FOR} command declares the control variable $N$ as a new local
variable initialised with the value of $E_1$.  The scope of the
control variable is the body of the {\tt FOR} command. The control
variable may not be given the {\tt FLT} tag. If {\tt BY} is present,
the step length is $K$ which must be a manifest constants (see Section
\ref{manexpr}), but if omitted {\tt BY~1} is assumed.  If {\tt TO} is
present, the end limit is $E_2$, but if omitted an infinite end limit
with the same sign as the step length is assumed, requiring no
termination test. If the step value is negative $N$ is stepped until it
is less than the end limit, otherwise it is stepped until greater than
the end limit.

Since January 2026 the effect of {\tt BREAK} and {\tt LOOP} have been
slightly modified. They are now only valid when withing the body of a
repetive command. {\tt LOOP} causes control to jump to the end of the
body when the repetition condition is normally tested. {\tt BREAK}
causes a transfer of control to the point just after the petitive
command.  Note that {BREAK} and {\tt LOOP} occurring in the initial
value or end limit expression must be within the body of an enclosing
repetitive command. Similarly {\tt BREAK} and {\tt LOOP} within the
repetition conditions in {\tt WHILE}, {\tt UNTIL}, {\tt REPEATWHILE}
and {\tt REPEATUNTIL} command must be within the body of enclosing
repetitive commands.

\subsection{\label{switchon}{\tt SWITCHON} command}

A {\tt SWITCHON} command has the following form:

\begin{center}
{\tt SWITCHON \em E \tt INTO \verb|{| $C_1$ \tt;\ldots\tt; $C_n$ \verb|}|}
\end{center}

\noindent
Labels of the form {\tt DEFAULT:} or {\tt CASE~$K$:} are permitted in
the command sequence.  $E$ is evaluated and control is passed to the
matching case label if it exists, otherwise a jump is made to the
default label but, if that is not given, control passes to the point
just after the switchon command.


\begin{samepage}

\subsection{\label{matchcom}{\tt MATCH} Command}

A {\tt MATCH} command has the following form:

\medskip
\begin{tabular}{p{15mm}l}
      &{\tt MATCH (} {\em args} {\tt)}\\
      &{\tt:} $P$ {\tt,..,} $P$ {\tt BE} {\em C}\\
      &{\tt...}\\
      &{\tt:} $P$ {\tt,..,} $P$ {\tt BE} {\em C}\\
      &{\tt.}
\end{tabular}
\end{samepage}

\medskip
\noindent
It consists of the word {\tt MATCH} followed by a list of zero or more
arguments enclosed in parentheses. This is followed by followed by one
or more match items and optionally terminated by a dot. The match
items are applied in turn to the arguments as described in Section
\ref{patterns} executing the command in the first match item to be
satisfied. If none are satisfied the match command has no effect.
Within a match item the the command {\tt NEXT} causes control to pass
to the next match item, if any, and the command {\tt EXIT} causes the
{\tt MATCH} command to terminate.


\begin{samepage}

\subsection{\label{everycom}{\tt EVERY} Command}

An {\tt EVERY} command has the following form:

\medskip
\begin{tabular}{p{15mm}l}
      &{\tt EVERY (} {\em args} {\tt)}\\
      &{\tt:} $P$ {\tt,..,} $P$ {\tt BE} {\em C}\\
      &{\tt...}\\
      &{\tt:} $P$ {\tt,..,} $P$ {\tt BE} {\em C}\\
      &{\tt.}
\end{tabular}
\end{samepage}

\medskip
\noindent
It consists of the word {\tt EVERY} followed by a list of arguments
enclosed in parentheses, followed by a sequence of one or more match
items optionally terminated by a dot. The match items are applied in
turn to the arguments as described in Section \ref{patterns} executing
the commands of every match item that is satisfied.

Within a match item the commands NEXT causes control to pass to the
next match item, if any, and EXIT causes termination of the entire
match list. If in a {\tt MATCH} expression or a function definition
the result is zero, but if in an {\tt EVERY} expression the
result is the sum accumulated so far. {\tt MATCH} and {\tt EVERY}
commands and routines do not return results.



\subsection{Flow of Control\label{breakcommand}}

The commands in this section affect the flow of control.

\medskip
\noindent
{\tt RESULTIS }$E$ causes $E$ to be evaluated and returned as the
result of the smallest textually enclosing {\tt VALOF} expression
which must be within the current function or routine.

\medskip
\noindent
{\tt RETURN} normally causes a return from the current routine, but if
encountered in a function it returns with the value zero.

\medskip
\noindent
{\tt LOOP} causes a jump to the point just after the end of the body
of the smallest textually enclosing repetitive command (see
Section~\ref{repcom}).  The destination of the jump must be within the
current function or routine. For a {\tt REPEAT} command, {\tt LOOP}
causes the body to be executed again.  For a {\tt FOR} command, it
causes a jump to where the control variable is incremented, and for
the {\tt REPEATWHILE} and {\tt REPEATUNTIL} commands, it causes a jump
to the place where the controlling expression is re-evaluated.

\medskip
\noindent
{\tt BREAK} causes a jump to the point just after the smallest
enclosing repetitive command which must be within the current function
or routine.

\medskip
\noindent
{\tt ENDCASE} causes execution to jump to the point just after the end
of the smallest enclosing {\tt SWITCHON} command which must be within
the current function or routine.

\medskip
\noindent
{\tt GOTO }$E$ command jumps to the point whose address is the value
of $E$.  $E$ is typically a label. See Section~\ref{labels} for
details on how labels are declared.  The destination of a {\tt GOTO}
must be within the current function or routine.

\medskip
\noindent
{\tt NEXT} is a newly added command that can only be used inside a the
pattern or body of a match item. It causes control to pass to the
start of the next match item, if any.

\medskip
\noindent
{\tt EXIT} is a newly added command that can only be used inside a the
pattern or body of a match item. It causes termination of the match
construct.If in a {\tt Match} expression or function body, it returns
a zero result. If in an {\tt EVERY} expresion, it returns the sum
acccumulated so far. {\tt MATCH} and {\tt EVERY} commands and routine
do not return results.


\medskip
\noindent
{\tt FINISH} only remains in BCPL for historical reasons and should
not be used. It is equivalent to the call {\tt stop(0,~0)} which
causes the current program to terminate.  See the description of
{\tt stop(code,~res)} page~\pageref{stop}.

\subsection{Compound Commands}

It is often useful to be able to execute commands in a sequence, and
this can be done by writing the commands one after another, separated
by semicolons and enclosed in section brackets. The syntax is as
follows:

\begin{center}
{\verb|{| $C_1$\tt;\ldots ; $C_m$ \verb|}|}\\
\end{center}

\noindent
where $C_1$ to $C_m$ are commands. It is permissible to have no
commands in a command sequence, thus \verb|{}| is allowed and performs
no commands.

Any semicolon occurring at the end of a line may be omitted.  For this
rule to work, infixed expression operators may never start a line (see
Section~\ref{exprprec}).

A command sequence can also be formed using the symbol {\tt <>} which
behaves like semicolon but is more binding than {\tt DO}, {\tt THEN},
{\tt ELSE}, {\tt REPEATWHILE}, {\tt REPEATUNTIL} and {\tt REPEAT}. It
purpose is to reduce the need for section brackets (\verb|{| and
\verb|}|) as in


\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
          IF x<y DO t:=x <> x:=y <> y:=t
\end{verbatim}
\end{samepage}

\noindent
which is equivalent to:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
          IF x<y DO { t:=x; x:=y; y:=t }
\end{verbatim}
\end{samepage}

\noindent
This sequencing operator has been included since it was in the
extended non standard version of BCPL at MIT and extensively used in
the PAL compiler. See for instance {\tt com/pal75.b}.

\subsection{Blocks}

A block is similar to a compound command but may start with some
declarations.  The syntax is as follows:

\begin{center}
{\verb|{| $D_1$\tt;\ldots; $D_n$\tt; 
$C_1$\tt;\ldots\tt; $C_m$ \verb|}|}\\
\end{center}

\noindent
where $D_1$ to $D_n$ are delarations and $C_1$ to $C_m$ are commands.
The declarations are executed in sequence to initialise any variables
declared.  A name may be used on the right hand side of its own and
succeeding declarations and the commands (the body) of the block.





\section{Declarations}

Each name used in BCPL program must in the scope of its declaration.
The scope of names declared at the outermost level of a program
include the right hand side of its own declaration and all the
remaining declarations in the section. The scope of names declared at
the head of a block include the right hand side of its own
declaration, the succeeding declarations and the body of the block.
Such declarations are introduced by the keywords {\tt MANIFEST}, {\tt
STATIC}, {\tt GLOBAL} and {\tt LET}. A name is also declared when it
occurs as the control variable of a for loop.  The scope of such a
name is the body of the for loop. 

\subsection{\label{labels}Labels}

The only other way to declare a name is as a label of the form
$N${\tt:}. This may prefix a command or occur just before the closing
section bracket of a compound command or block. The scope of a label
is the body of the block or compound command in which it was declared.

\subsection{\label{mandecl}Manifest Declarations}

A {\tt MANIFEST} declaration has the following form:

\begin{center}
{\tt MANIFEST \verb|{| $N_1$ \tt= $K_1$\tt;...;
  $N_n$ \tt= $K_n$ \verb|}|}
\end{center}

\noindent
where $N_1${\tt,...,}$N_n$ are names (see Section~\ref{names}) and
$K_1${\tt,...,}$K_n$ are manifest constant expressions (see Section
\ref{manexpr}).  Each name is declared to have the constant value
specified by the corresponding manifest expression.  The details have
recently changed due to the introduction of the {\tt FLT} feature, see
Section~\ref{fltfeature} on page~\pageref{fltfeature}.  Manifest names
with the {\tt FLT} tag have floating point values otherwise they are
integers.  If a value specification ({\tt=}$K_1$) is omitted in the
declaration of the first name, the value 1 or 1.0 is assumed.  If a
value specification ({\tt=}$K_i$) is omitted in later declarations a
value 1 or 1.0 greater than the value of the previous name is used. An
automatic conversion between integer and floating point is performed
if necessary.  Thus, the declaration:

\begin{center}
\verb|MANIFEST { A; B; FLT C=10; D; E=C+100 }|
\end{center}

\noindent
declares {\tt A}, {\tt B}, {\tt C}, {\tt D} and {\tt E} to have
manifest values {\tt 0}, {\tt 1}, {\tt 10.0}, {\tt 11} and
{\tt 110}, respectively.


\subsection{\label{globdecl}Global Declarations}

The global vector is a permanently allocated region of memory that may
be directly accessed by any (separately compiled) section of a program
(see Section~\ref{sepcomp}).  It provides a mechanism for
linking together separately compiled sections. A GLOBAL declaration
allows a names to be explicitly associated with elements of the global
vector.  The syntax is as follows:

\begin{center}
{\tt GLOBAL \verb|{| $N_1$\tt:$K_1$\tt;...;
  $N_n$\tt:$K_n$ \verb|}|}
\end{center}

\noindent
where {$N_1$\tt,...,$N_n$} are names possibly prefixed by {\tt FLT}
(see Section~\ref{names}) and {$K_1$\tt,...,$K_n$} are manifest
constants (see Section \ref{manexpr}).  Each constant
specifies which global vector element is associated with each
variable, and if {\tt FLT} is specified the variable is assumed to
hold a floating point number.

If a global number ({\tt:}$K_i$) is omitted, the next global variable
element is implied.  If {\tt:}$K_1$ is omitted, then {\tt:0} is
assumed. Thus, the declaration:

\begin{center}
{\tt GLOBAL \verb|{| a; b:200; c; d:251 \verb|}|}
\end{center}

\noindent
declares the variables {\tt a}, {\tt b}, {\tt c} and {\tt d} occupy
positions 0, 200, 201 and 251 of the global vector, respectively.



\subsection{\label{statdecl}Static Declarations}

A {\tt STATIC} declaration has the following form:

\begin{center}
{\tt STATIC \verb|{| $N_1$\tt=$K_1$\tt;...; $N_n$\tt=$K_n$ \verb|}|}
\end{center}

\noindent
where $N_1${\tt,...,}$N_n$ are names possibly prefixed by {\tt FLT}
(see Section~\ref{names}) and $K_1${\tt,...,}$K_n$ are manifest
constant expressions (see Section \ref{manexpr}).  Each name is
declared to be a statically allocated variable initialised to the
corresponding manifest expression.  If a value specification
({\tt=}$K_i$) is omitted, the a value 0 or 0.0 is implied.  Thus, the
declaration:

\begin{center}
\verb|STATIC { A; B; FLT C=10; D; E=100 }|
\end{center}

\noindent
declares {\tt A}, {\tt B}, {\tt C}, {\tt D} and {\tt E} to be static
variables having initial values {\tt 0}, {\tt 0}, {\tt 10.0}, {\tt 0}
and {\tt 100}, respectively.


\subsection{{\tt LET} Declarations}

{\tt LET} declarations are used to define local variables, local
vectors, and functions. The textual scope of names declared in a {\tt
  LET} declaration is the right hand side of its own definition (to
allow recursive functions), and subsequent definitions, declarations
and commands.

Local variable, local vector, function definitions can be
combined using the word {\tt AND}. The only effect of this is to
extend the scope of names defined back to the word {\tt LET}, thus
allowing the definition of mutually recursive functions.

\subsubsection{Local Variable Definitions}

A local variable definition has the following form:

\smallskip

\centerline{$N_1${\tt,...,} $N_n$ {\tt=} $E_1${\tt,...,} $E_n$}

\smallskip

\noindent
where $N_1${\tt,...,}$N_n$ are names possibly prefixed by {\tt FLT}
(see Section~\ref{names}) and $E_1${\tt,...,}$E_n$ are
expressions. The names, $N_i$, are allocated space in the current
stack frame and are initialized with the corresponding values of
$E_i$. Such variables are called {\em dynamic} variables since they are
allocated when the definition is executed and cease to exist when
control leaves their scope.

The variables $N_1${\tt,...,}$N_n$ are allocated consecutive locations
in the stack frame of the current function and so, for instance, the
variable $N_i$ may be accessed by the expression $({\tt
  @}N_1){\tt!(i-1)}$. This feature is a recent addition to the
language. When a local variable has the {\tt FLT} tag it initial value
expression is evaluated in {\tt FLT} mode. For details see
Section~\ref{fltfeature} on page~\pageref{fltfeature}.

The query expression ({\tt ?}) should be used on the right hand side
when a variable does not need a specified initial value.
 

\subsubsection{Local Vector Definitions}

\begin{center}
$N$ {\tt= VEC} $K$
\end{center}

\noindent
where $N$ is a name which may not be qualified by the {\tt FLT} tag
and $K$ is a manifest constant. A location is allocated for $N$ and
initialized to point to a vector whose lower bound is {\tt 0} and
whose upper bound is $K$.  The variable $N$ and the vector elements
($N${\tt!0} to $N${\tt!}$K$) reside in the stack frame of the current
function and only continue to exist while control remains within the
function.


\subsubsection{\label{procdecl}Function Definitions}

These definitions have the following form:

\smallskip

\centerline{$N$ {\tt(} $N_1${\tt,...,} $N_n$ {\tt) =} $E$}
\centerline{$N$ {\tt(} $N_1${\tt,...,} $N_n$ {\tt) BE} $C$}


\smallskip

\noindent
where $N$ is the name possibly prefixed by {\tt FLT} of the function
being defined, and $N_1${\tt,...,}$N_n$ are its formal parameters,
each of which may be prefixed by {\tt FLT}.  A function defined using
{\tt=} returns $E$ as result, but one defined using {\tt BE} and
executes the command $C$ and does not return a defined a
result. Functions defined using {\tt BE} are often called routines.
If the function name has the {\tt FLT} prefix, the result, if any, of
a call is assumed to be a floating point value. For details see
Section~\ref{fltfeature} on page~\pageref{fltfeature}.

Some example functions definitions are as follows.

\smallskip

\begin{verbatim}
      LET wrpn(n) BE { IF n>9 DO wrpn(n/10)
                       wrch(n MOD 10 + '0')
                     }
      LET gray(n) = n XOR n>>1
      LET next() = VALOF { c := c+1
                           RESULTIS !c
                         }
\end{verbatim}

\smallskip

A function can be defined using pattern matching by giving its name,
which may be prefixed by {\tt FLT}, followed a one or more match items
of the form:

\smallskip

\begin{tabular}{p{15mm}lll} 
     & {\tt:} {\em Plist} {\tt =>} {\em E}.
\end{tabular}

\smallskip

\noindent
optionally followed by a dot. The way patterns work is described in
on page~\pageref{patterns}.
  
\medskip
\noindent


A routine can be defined using pattern matching by giving its name followed a
one or more match items of the form:

\smallskip

\begin{tabular}{p{15mm}lll} 
     & {\tt:} {\em Plist} {\tt BE} {\em C}.
\end{tabular}

\smallskip

\noindent
optionally followed by a dot. The way patterns work is described in
on page~\pageref{patterns}.
  
\medskip
\noindent

If the name of a pattern function has an {\tt FLT} prefix, its
result is assumed to be a floating point number.





\medskip

If a function or routine is defined in the scope of a global variable
with the same name, the global variable is given an initial value
representing that function or routine (see section~\ref{sepcomp}).

Since March 2023, functions, routine and pattern functions and
routines to can have their names prefixed by {\tt FLT}. Calls of
functions with the {\tt FLT} tag are assumed to return floating point
results. If a function is declared having the FLT tag is in the scope
of a global variable of the same name, the global must also have been
declared with the FLT tag. If the function did not have the FLT tag,
the global should also not have the tag. If a match expression is
evaluated in FLT mode, all its result expressions are evaluated in FLT
mode. Likewise, if an {\tt EVERY} expression is evaluated in FLT mode
the result is the floating point sum of its successful result
expressions.

If a function is called as a command its result is thrown away, and if
a routine is called when a result is required its result is undefined.
See section~\ref{calls} for information about the syntax of function
and routine calls.

The arguments of a functions and routines behave like named elements
of a dynamic vector and so exist only for the lifetime of the call.
This vector has as many elements as there are formal parameters and
they receive their initial values from the actual parameters of the
call.  Functions and routines are variadic; that is, the number of
actual parameters need not equal the number of formals.  If there are
too few actual parameters, the missing ones are left uninitialized,
and if there are too many actual parameters, the extra ones are
evaluated and then discarded.  Notice that arguments can be accessed
by the expressions {\tt (@x)!0}, {\tt (@x)!1}, {\tt (@x)!2},\ldots
where {\tt x} is the first argument.  This feature is useful in the
definition of functions, such as {\tt writef}, having a variable
number of arguments. The scope of the formal parameters is the body of
the function or routine.

Function and routine calls are cheap in both space and execution time,
with a typical space overhead of three words of stack per call plus
one word for each formal parameter.  In the Cintcode implementation,
the execution overhead is typically just one Cintcode instruction for
the call and one for the return.

There are two important restrictions concerning functions and
routines.  One is that a {\tt GOTO} command cannot make a jump to a
label not declared within the current function or routine, although
such non local jumps can be made using {\tt level} and {\tt longjump},
described on page~\pageref{longjump}.  The other is that dynamic free
variables are not permitted.

\subsection{Dynamic Free Variables}

Free variables of a function or routine are those that are used but
not declared in the function or routine, and they are restricted to be
either manifest constants, static variables, global variables,
functions, routines or labels.  This implies that they are not
permitted to be dynamic variables (ie local variables) of another
function or routine.  There are several reasons for this restriction,
including the ability to represent a function or routine by a single
BCPL word, the ability to provide a safe separate compilation with the
related ability to assign functions and routines to variables. It also
allows calls to be efficient.  Programmers used to languages such as
Algol or Pascal will find that they need to change their programming
style somewhat; however, most experienced BCPL users agree that the
restriction is well worthwhile.  Note that C adopted the same
restriction, although in that language it is imposed by the simple
expedient of insisting that all functions are declared at the
outermost level, thus making dynamic free variables syntactically
impossible.

A style of programming that is often be used to avoid the dynamic free
variable restriction is exemplified below.

\begin{samepage}
{\small
\begin{verbatim}
        GLOBAL { var:200 }

        LET f1(...) BE
        { LET oldvar = var    // Save the current value of var
          var := ...          // Use var during the call of f1
          ...
          f2(...)             // var may be used in f2
          ...
          IF ... DO f1(...)   // f1 may be called recursively
          var := oldvar       // restore the original value of var
        }

        AND f2(...) BE        // f2 uses var as a free variable
        {  ... var ...  }
\end{verbatim}
}
\end{samepage}



\section{\label{patterns}Patterns}

This section describes the MCPL style pattern matching mechanism that
is now included in BCPL.

Pattern matching is an important feature since it provides a mechanism
to select an outcome based on the values of locations in a structure
referenced directly or indirectly from a set of arguments. Names,
called pattern variables, can be associated with locations in the
structure. Such variables have much in common with ordinary local
variables. A name declared in the pattern of a match item can only be
used in the pattern, expression or command in the match item.

Patterns are used in function and routine definitions and in {\tt
  MATCH} and {\tt EVERY} commands and expressions. They are applied to
the arguments given by the function or routine calls or the arguments
of {\tt MATCH} and {\tt EVERY} constructs.

Each match construct contains a list of one or more match items, each
consisting of a pattern followed by either {\tt=>} and an expression
or {\tt BE} and a command.


The list of match items is optionally terminated by a dot.
If the first match item in the list uses the operator {\tt=>} then
all the subsequent items must also use {\tt=>}, otherwise all the
match items must use {\tt BE}.

For functions, routines and {\tt MATCH} expressions and commands, the
patterns are tested in turn and the first to be successful causes the
related expression or command to be evaluated.

For an {\tt EVERY} command, the commands in all successful match items
are executed, and for an {\tt EVERY} expression the values of the
expressions of all successful match items are summed and returned as
the result.

A pattern is composed of terms and three pattern operators: comma
({\tt,}), vertical bar ({\tt|}) and juxaposition. The syntax
specification is given in Figure~\ref{b-pat} on
page~\pageref{b-pat}. A term typically tests the contents of a memory
location. It can be a relational operator such as {\tt<=} or {\tt\#>}
which compares the contents of the current location with the value of
its right hand operand. It can be a possibly sign constant which is
directly compared with the location. It can be a range test consisting
of the operator {\tt..} or {\tt\#..} applied to two operands which
must be names or possibly signed numerical constants.  This construct
succeeds if the value in the current location is not less than the left
operand and not greater than the right hand one.


The term query ({\tt?}) always matches its location. If a term is just
a manifest constant name it behaves as an explicit constant with that
value. If it is a non manifest name, it is a local variable
declaration associating the name with the current location 
and, as with other local variables, the name can have a {\tt FLT}
prefix. Such declarations always successfully match their locations.

A term can also be one of the escape commands {\tt BREAK}, {\tt LOOP},
{\tt ENDCASE}, {\tt NEXT} or {\tt EXIT}. They provide an escape
mechanism behaviing in exactly the same way as the corresponding
commands.

If $T_1$ and $T_2$ are two terms, the juxtaposition $T_1$~$T_2$
matches if $T_1$ and $T_2$ both successfully match the current
location. The pattern $T_1${\tt|}$T_2$ is successful if one or both
terms match the current location. The pattern $T_1${\tt,}$T_2$ matches
if $T_1$ matches the current location and $T_2$ matches the location
whose address is one greater than that of the current location.
Juxtaposition has the highest precedence and comma has the
lowest. Vertical bar is less binding than juxtaposition but more
binding than comma. A term may use parentheses to override the normal
precedence of these operators.

The last form of term encloses a pattern in square brackets as in
{\tt[}$P${\tt]} where $P$ is a pattern. This construct matches $P$
with the location pointed to by the contents of current location.

The following examples illustrate how pattern matching can be used.

\smallskip

\begin{verbatim}
       LET ways
       : 0,         ?  => 1
       : ?,       [0]  => 0
       : s, coins[>s]  => ways(s, coins+1)
       : s, coins[v ]  => ways(s, coins+1) + ways(s-v, coins)

       LET eval
       : [Id,     x], e => lookup(x, e)
       : [Num,    k], ? => k
       : [Mul, x, y], e => eval(x, e) * eval(y, e)
       : [Div, x, y], e => eval(x, e) / eval(y, e)
       : [Add, x, y], e => eval(x, e) + eval(y, e)
       : [Sub, x, y], e => eval(x, e) - eval(y, e)
\end{verbatim}

If a pattern variable is associated with an argument of the match
construct it behaves exactly like an ordinary local variable
addressing a location with a known offset relative to the P
pointer. But if the variable is inside one or more square bracket
terms its location is determined by a sequence of indirections. For
example consider the following routine.

\smallskip
\begin{verbatim}
LET r : a, b[x, [y]], c BE { b:=c; x:=y }
\end{verbatim}
\smallskip

Here {\tt x} is treated as {tt b!0} and {\tt y} is equivalent to {\tt
  b!1!0}, so the assignment {\tt x:=y} is equivalent to {\tt
  b!0:=b!1!0} which is executed after the assignment {\tt b:=c}.

A more significant example is the function {\tt rotleft} defined in
{\tt bcplprogs/patdemos/splay.b}. This function is worth diligent
study. It performs a transformation of a binary tree represented by
nodes of the form {\tt [key,val,parent,left,right]}.

\smallskip

{\small
\begin{verbatim}
AND rotleft    // Promote right child      p          p
: n[key, val,                         //   |          |
    np[?,?,?,npl,npr],                //   n    =>    r
    nx,                               //  / \        / \
    nr[?,?,nrp,nry[?,?,nryp,?,?],nrz] // x   r      n   z
   ] BE                               //    / \    / \
                                      //   y   z  x   y
{ LET y = nry
  // The order of the assigments was chosen with great care.

  TEST np              // Test if n has a parent.
  THEN TEST n=npl
       THEN npl := nr  // Update the parent's left branch.
       ELSE npr := nr  // Update the parent's right branch.
  ELSE root := nr      // n has no parent, so r is the new root.
  IF nry DO nryp := n  // If y exists, its parent should be n.

  nrp := np
  nry := n
  np  := nr
  nr  := y
}
\end{verbatim}
}




\section{\label{sepcomp}Separate Compilation}

Large BCPL programs can be split up into sections that can be compiled
separately.  When loaded into memory they can communicate with each
other using a special area of store called the {\em Global Vector}.
This mechanism is simple and machine independent and was put into the
language since linkage editors at the time were so primitive and
machine dependent.


Variables residing in the global vector are declared by GLOBAL
declarations (see section~\ref{globdecl}). Such variables can be
shared between separately compiled sections. This mechanism is similar
to the used of BLANK COMMON in Fortran, however there is an additional
simple rule to permit access to functions and routines declared in
different sections.


If the definition of a function or routine occurs within the scope of
a global declaration for the same name, it provides the initial value
for the corresponding global variable.  Initialization of such global
variables takes place at load time.

The three files shown in Table 2.1 form a simple example of how
separate compilation can be organised.
\bigskip

\begin{samepage}
\begin{center}
\tt
\begin{tabular}{|l|l|l|}
\hline
{\rm File} demohdr &  {\rm File} demolib.b &   {\rm File} demomain.b\\[6pt]
\hline
GET "libhdr"       &  GET "demohdr"        &   GET "demohdr"\\[10pt]

\verb|GLOBAL { f:200 }|
                   & LET f(...) = VALOF    & LET start() BE\\
                   & \verb|{| ...          & \verb|{| ...\\
                   & \verb|}|              & \quad f(...)\\
                   &                       & \verb|}|\\
\hline
\end{tabular}
\end{center}

\centerline{Table 2.1 - Separate compilation example}
\end{samepage}

\bigskip


When these sections are loaded, global 200 is initialized to the entry
point of function {\tt f} defined in {\tt demolib.b} and so can be
called from the function {\tt start} defined in {\tt demomain.b}.

The header file, {\tt libhdr}, contains the global declarations of all
the resident library functions and routines making all these
accessible to any section that started with: {\tt GET "libhdr"}.  The
library is described in the next chapter.  Global variable 1 is called
{\tt start} and is, by convention, the first function to be called
when a program is run.


Automatic global initialisation also occurs if a label declared by
colon (\verb|:|) occurs in the scope of a global of the same name.


Although the global vector mechanism has disadvantages, particularly
in the organisation of library packages, there are some compensating
benefits arising from its extreme simplicity.  One is that the output
of the compiler is available directly for execution without the need
for a link editing step.  Sections may also be loaded and unloaded
dynamically during the execution of a program using the library
functions {\tt loadseg} and {\tt unloadseg}, and so arbitrary
overlaying schemes can be organised easily.  An example of where this
is used is in the implementation of the Command Language Interpreter
described in Chapter~\ref{CLI}.  The global vector also allows for a
simple but effective interactive debugging system without the need for
compiler constructed symbol tables.  Again, this was devised when
machines were small, disc space was very limited and modern day
linkage editors had not been invented; however, some of its advantages
are still relevant today.

\section{The {\tt FLT} Feature\label{fltfeature}}

BCPL was originally designed for the implemention of compilers and
other system software such as text editors, pagination programs and
operating systems. These applications typically did not require
floating arithmetic and so the language did not include such
features. Indeed, many early machines on which BCPL ran had word
lengths of 16 or 24 bits which were of insufficient for useful
floating point numbers. Even on 32-bit machines the precision of
floating point numbers is limited to about 6 decimal digits which is
insufficient for serious scientific calculation. For 50 years I
resisted putting floating point into BCPL but have recently given
in. This is mainly due to the need to use 32-bit floating point in the
BCPL interface with the OpenGL graphics library described {\tt
  bcplraspi.pdf}. The same document also describes a flight simulator
where the inaccuracy of 32-bit floating point can be put down to
random turbulence of the air through which the aircraft is flying.
Single precision floating point is also useful when representing
samples in digital sound.

The FLT feature was added to BCPL in March 2018 to make computations
involving floating point numbers more convenient. This feature may
look as if data types have been added to BCPL, but the language still
retains its typeless nature in the sense that all expression values
are the same size and the compiler generates no error messages
relating to data types. The sole effect of this feature is to cause
some integer operators such as {\tt+} and {\tt-} to be replaced
automatically by their floating point versions {\tt\#+} and {\tt\#-}
and to automatically replace some integer constants by floating point
ones when required.  These conversions are specified by some simple
rules, but before applying them it is assumed that all simultaneous
assignments and variable definitions have been automatically replaced
by sequences of non simultaneous constructs.

Some expressions such are the operands of {\tt\#+} are evaluated in
{\em FLT mode} meaning that they are expected to yield floating point
results. Expressions may also have the {\em FLT tag} when they are
believed to return floating point values. The rules relating to FLT
tag and FLT evaluation are as follows.

\medskip
\noindent
(1) Global, static and manifest, local variable and formal parameter
names can be prefixed by {\tt FLT} giving them the {\tt FLT} tag.  All
other names, namely {\tt FOR} loop control variables, vectors and
program labels, may not be given the {\tt FLT} tag. A global variable
with an {\tt FLT} tag is assumed to hold a floating point value, or
if it holds a function its result is assumed to be a floating point
value.

\medskip
\noindent
(2) An expression has the {\tt FLT} tag if it is a name declared with
the {\tt FLT} tag, a floating point constant or it has one of the
following leading operators {\tt FLOAT}, {\tt\#ABS}, {\tt\#*},
{\tt\#/}, {\tt\#MOD}, {\tt\#+}, {\tt\#-} and {\tt\#->}.

\medskip
\noindent
(3) If one of the operators {\tt ABS}, {\tt *}, {\tt/}, {\tt MOD},
{\tt+}, {\tt-}, \verb|=|, \verb|~=|, \verb|<|, \verb|<=|, \verb|>|,
\verb|>=|, \verb|:=|, \verb|ABS:=|, \verb|*:=|, \verb|/:=|,
\verb|MOD:=|, \verb|+=| or \verb|-=| has an operand with the {\tt FLT}
tag, the operator is replaced by the corresponding floating point
version.  The operator {\tt->} is replaced by {\tt\#->} if its second
or third operand has the {\tt FLT} tag.

\medskip
\noindent
(4) Expressions are evaluated in either {\tt FLT} or non-{\tt FLT}
mode. Expressions are evaluated in {\tt FLT} mode if they are operands
of {\tt FIX}, {\tt\#ABS}, {\tt\#*}, {\tt\#/}, {\tt\#MOD}, {\tt\#+},
{\tt\#-}, {\tt\#=}, \verb|#~=|, \verb|#<|, \verb|#<=|, \verb|#>| or
\verb|#>=|. The second and third operands of {\tt\#->} and the second
operand of \verb|#:=|, \verb|#ABS:=|, \verb|#*:=|, \verb|#/:=|,
\verb|#MOD:=|, \verb|#+:=| and \verb|#-:=| are evaluated in FLT mode.
Expressions giving the values of static, manifest and local variable
names with the {\tt FLT} tag are also evaluated in FLT mode.  All
other expressions are evaluate in non-{\tt FLT} mode.

\medskip
\noindent
(5) If the leading operator of an expression evaluated in {\tt FLT}
mode is one of {\tt ABS}, {\tt*}, {\tt/}, {\tt MOD}, {\tt+}, {\tt-} or
{\tt->} it is replaced by the floating point version. If an integer
constant is evaluated in {\tt FLT} mode it is replaced by the
corresponding floating point constant.

(6) If a function is declared in the scope of a global of the same
name they must either both have {\tt FLT} tags or neither should
have that tag.

\medskip
These rules are applied repeatedly until there is no further
change. As an example, the following function:

\smallskip
{\small
\begin{verbatim}
LET f(a, FLT b, c) = VALOF
{ a, b, c := 1/2, 1/2, 2 * (a + b)
  RESULTIS a + 2.0 * c + (0|#x3840000)
}
\end{verbatim}
}

\noindent
is automatically converted to:

\smallskip
{\small
\begin{verbatim}
LET f(a, FLT b, c) = VALOF
{ { a := 1/2; b #:= 1.0#/2.0; c #:= 2.0 #* (a #+ b) }
  RESULTIS a #+ 2.0 #* c #+ (0|#x3840000)
}
\end{verbatim}
}

\noindent
Notice that the user almost never needs to use \verb|#| to specify
floating point operations. Note also that the expression
\verb/(0|#x3840000|)/ is a way to protect an expression
(\verb|#x38400000|) from being evaluated in {\tt FLT} mode.  See {\tt
  com/xcmpltest.b} and {\tt bcpl4raspi.pdf} from my home page for
examples of the use of the FLT feature.

To see why the name in a vector declarations may not be given the {\tt
  FLT} tag, consider {\tt LET v = VEC 5}. This initialises {\tt v}
with a pointer to a vector with 6 elements and the expression {\tt
  v+1} would point to the element at subscript position one. Had {\tt
  v} been given the {\tt FLT} tag, {\tt v+1} would have been
automatically converted to {\tt v\#+1.0} which is clearly meaningless.

The {\tt FLT} tag is not permitted to qualify {\tt FOR} loop control
variables since, due to floating point truncation and rounding errors,
the number of iterations of a loop such as
\verb|FOR FLT x = 0.0 TO 10.0 BY 0.1 DO...| is properly defined since
0.1 cannot be represented precisely by a floating point number.

\section{The {\tt objline1} Feature}

If a file named {\tt objline1} is found in the current directory or
the other directories searched by {\tt GET} directives, its first line
is copied as the first line of the compiled Cintcode module.  This
will typically put a line such as:

\bigskip
\verb|#!/usr/local/bin/cintsys -c|
\bigskip

\noindent
as the first line of the compiled object module. This line is ignored
by the CLI but under Linux it allows Cintcode programs to be called
directly from a Linux shell. If {\tt objline1} cannot be found no such
line is inserted at the start of the object module.



\cleardoublepage


\chapter{\label{library}The Library}

This manual describes three variants of the BCPL system. The simplest
is invoked by the shell command {\tt cintsys} and provides a single
threaded command language interpreter. The system invoked by {\tt
cintpos} provides a multi-threaded system where the individual threads
(called tasks) are run in parallel and are pre-emptible. A third
version is available for some architectures and provides a single
threaded version in which the BCPL source is compiled into native
machine code. Although this version is faster, it is more machine
dependent, has fewer debugging aids and will only run a single
command.

The libraries of these three systems have much in common and so are
all described together.  The description of all constants, variables
and functions have a right justified line such as the following

\medskip
\rightline{\IMPL{y}{y}{n}}

\medskip
\noindent
where {\tt CIN:}, {\tt POS:} and {\tt NAT:} denote the single
threaded, multi-threaded and native code versions, respectively, and
the letters y and n stand for yes and no, showing whether the
corresponding constant, variable or function is available on that
version of the system.

The resident library functions, variables and manifest constants are
declared in the standard library header file {\tt g/libhdr.h}. Most of
the functions are defined in BCPL in either {\tt sysb/blib.b} or {\tt
sysb/dlib.b}, but three functions ({\tt sys}, {\tt chgco} and {\tt
muldiv}) are in the hand written Cintcode file {\tt
cin/syscin/syslib}. Most functions relating to the multi-threaded
version are defined in {\tt klib.b}.

The following three sections describe the manifest constants,
variables and functions (in alphabetical order) provided by the
standard library.

\section{Manifest constants}

\bigskip
\noindent
{\bf B2Wsh}\IMPL{y}{y}{y}
\indent
This constant holds the shift required to convert a BCPL pointer into
a byte address.  Most implementations pack 4 bytes into 32-bit words
requiring {\tt B2Wsh=2}, but on 64-bit implementations, such as native
code on the DEC Alpha or the 64-bit Cintcode version of BCPL, its
value is 3.

\bigskip
\noindent
{\bf bootregs}\IMPL{y}{y}{n}
\indent
This is the location in Cintcode memory used in Cintpos to hold
Cintcode registers during system startup.

\bigskip
\noindent
{\bf bytesperword}\IMPL{y}{y}{y}
\indent
Its value is \verb|1<<B2Wsh| being the number of bytes that can be
packed into a BCPL word. On 32-bit implementations it is 4, and on
64-bit versions it is 8.

\bigskip
\noindent
{\bf bitsperbyte}\IMPL{y}{y}{y}
\indent
This specifies the number of bits per byte. On most systems
{\tt bitsperbyte} is 8.

\bigskip
\noindent
{\bf bitsperword}\IMPL{y}{y}{y}
\indent
It value is {\tt bitsperbyte*bytesperword} being the number of bits
per BCPL word. It is usually 32, but can be 64.

\bigskip
\noindent
{\bf CloseObj}\IMPL{y}{y}{y}
\indent
This identifies the position of the {\tt close} method in objects
using BCPL's version of object oriented programming. Typical use is as
follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        CloseObj#(obj)
\end{verbatim}
\end{samepage}
 
\noindent For more details, see {\tt mkobj} described on
page~\pageref{mkobj}.

\bigskip
\noindent
{ \bf co\_c, co\_fn, co\_list, co\_parent, co\_pptr,
co\_size}\IMPL{y}{y}{y} 
\indent
These are the system fields as the base of coroutine stacks.  If a
coroutine is suspended, its {\tt pptr} field holds the stack frame
pointer (P) at the time it became suspended.  The {\tt parent} field
points to the parent coroutine, if it has one, or is {\tt-1} for root
coroutines, and is zero otherwise. The {\tt list} field holds the next
coroutine in the list of coroutines originating from global {\tt
colist}.  The {\tt fn} and {\tt size} fields hold the coroutine's main
function and stack size, and the {\tt c} field is a system work
location.  For more information about coroutines, see {\tt createco}
described on page~\pageref{createco}.

\bigskip
\noindent
{\bf deadcode}\IMPL{y}{y}{n}
\indent
To aid debugging, the entire Cintcode memory is initialised to {\tt
deadcode}.  Typically {\tt deadcode=\#xDEADC0DE}.

\bigskip
\noindent
{\bf endstreamch}\IMPL{y}{y}{y}
\indent
This is the value returned by {\tt rdch} when reading from a stream
that is exhausted. Its value is normally {\tt-1}.

\bigskip
\noindent
{\bf entryword}\IMPL{y}{y}{n}
\indent
To aid debugging, every functions entry point is marked by {\tt
entryword}. This is normally followed by a function name compressed
into a string of 11 characters. If the function name is too long its
first and last five character are packed into the string separated by
a single quote {\tt'}.  Typically {\tt entryword=\#x0000DFDF}.

\bigskip
\noindent
{\bf fl\_\ldots}\IMPL{y}{y}{n}
\indent
Constants of the form {\tt fl\_...} are mnemonics for the floating point
operations performed by the call {\tt sys(Sys\_flt, \em op\tt, ...)}
as described near page~\pageref{sysflt}.

\bigskip
\noindent
{\bf globword}\IMPL{y}{y}{n}
\indent
This constant is used to assist the debugging of Cintcode programs.
If the $i^{th}$ global variable is not otherwise set, its value is
{\tt globword+}$i$.  Typically {\tt globword=\#x8F8F0000}.

\bigskip
\noindent
{\bf id\_inscb, id\_inoutscb, id\_outscb}\IMPL{y}{y}{n}
\indent
These constants are mnemonics for the possible values of the {\tt id}
field of a stream control block. See {\tt scb\_id} below. 

\bigskip
\noindent{\bf InitObj}\IMPL{y}{y}{y}
\indent
This identifies the position of the {\tt init} method in objects using
BCPL's version of object oriented programming. Typical use is as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        InitObj#(obj, arg1, arg2)
\end{verbatim}
\end{samepage}
 
\noindent For more details, see {\tt mkobj} described on page~\pageref{mkobj}.

\bigskip
\noindent
{\bf isrregs}\IMPL{n}{y}{n}
\indent
Under Cintpos this is the location in Cintcode memory used to hold the
Cintcode registers representing the state at the start of the
interrupt service routine.

\bigskip
\noindent
{\bf klibregs}\IMPL{n}{y}{n}
\indent
Under Cintpos This is the location in Cintcode memory used to hold
Cintcode registers during system startup.

\bigskip
\noindent
{\bf  mcaddrinc}\IMPL{y}{y}{y}
\indent
This is the difference between machine addresses of consecutive words
in memory and is usually 4 or 8. Very occasionally, BCPL implementions
have negatively growing stacks, in which case {\tt mcaddrinc} will be
negative.

\bigskip
\noindent
{\bf maxint, minint}\IMPL{y}{y}{y}
\indent
The constant {\tt minint} is \verb|1<<(bitsperword-1)| and {\tt
maxint} is {\tt =minint-1}. They hold the most negative and largest
positive numbers that can be represented by a BCPL word.  On 32-bit
implementations, they are normally \verb|#x80000000| and
\verb|#x7FFFFFFF|.

\bigskip
\noindent
{\bf pollingch}\IMPL{n}{y}{n}
\indent
This is the value returned by {\tt rdch} if a charcter is not
immediately available from the currently selected stream.  Its value
is normally {\tt-3}.  Currently only TCP streams under Cintpos provide
the polling mechanism.

\bigskip
\noindent
{\bf rootnodeaddr}\IMPL{y}{y}{n}
\indent
This manifest constant is used in Cintsys and Cintpos to hold the
address of the root node. Its value is otherwise zero.

\bigskip
\noindent
{\bf rtn\_\ldots}\IMPL{y}{y}{y}
\indent
The root node is a vector accessible to all running programs to
provide access to all global information. It is available in all
versions of BCPL but many of its fields are only used in Cintpos.  The
global variable {\tt rootnode} holds a pointer to the root node. On
some systems the address of the root node is also held in the manifest
constant {\tt rootnodeaddr}.  Manifest constants starting with {\tt
rtn\_} give the positions of the fields within the root node.

\bigskip
\noindent
{\bf rtn\_abortcode}\IMPL{y}{y}{n}
\indent
This rootnode field holds the most recent return code from a command
language interpreter (CLI). It is used by commands such as {\tt
dumpsys} and {\tt dumpdebug} when inspecting Cintcode memory dumps.

\bigskip
\noindent
{\bf rtn\_adjclock}\IMPL{y}{y}{n}
\indent
This rootnode field holds a correction in minutes to be added to the
time of day supplied by the system. It is normally set to zero.

\bigskip
\noindent
{\bf rtn\_blklist}\IMPL{y}{y}{y}
\indent
All blocks of memory whether free or in used are chained together in
increasing address order. This rootnode field points to the first in
the chain.

\bigskip
\noindent
{\bf \bf rtn\_blib}\IMPL{y}{y}{n}
\indent
Under Cintsys and Cintpos this rootnode field holds the appropriate
versions of the modules {\tt BLIB}, {\tt SYSLIB} and {\tt DLIB}
chained together.

\bigskip
\noindent
{\bf rtn\_boot}\IMPL{y}{y}{n}
\indent
Under Cintsys and Cintpos this rootnode field holds the
appropriate version of the {\tt BOOT} module.

\bigskip
\noindent
{\bf rtn\_boottrace}\IMPL{y}{y}{n}
\indent
Under Cintsys and Cintpos this rootnode field holds 0, 1, 2 or 3.  The
default value is 0 but can be incremented using the {\tt -v}
option. Larger values of {\tt boottace} generate more tracing
information.

\bigskip
\noindent
{\bf rtn\_bptaddr, rtn\_bptinstr}\IMPL{y}{y}{n}
\indent
These each hold vectors of 10 elements used by the standalone debugger
to hold breakpoint addresses and operation codes overwritten by {\tt
BRK} instructions. They are in the rootnode to make them accessible to
the debug task in Cintpos and to the {\tt dumpdebug} command.

\bigskip
\noindent
{\bf rtn\_clkintson}\IMPL{n}{y}{n}
\indent
Under Cintpos, this boolean field controls whether clock interrupts
are enabled. It is provided to make single step execution possible
within the interactive debugger without interference from clock
interrupts. For more details see the chapter on the debugger starting
on page~\pageref{debugging}.

\bigskip
\noindent
{\bf rtn\_clwkq}\IMPL{n}{y}{n}
\indent
Under Cintpos, this field is used to holds the ordered list of packets
waiting to be released by the clock device.

\bigskip
\noindent
{\bf rtn\_context}\IMPL{y}{y}{n}
\indent
Under certain circumstances the entire Cintcode memory is dumped in a
compacted form to the file {\tt DUMP.mem} for later inspection by
commands such as {\tt dumpsys} and {\tt dumpdebug}. This field is set
at the time a dump file is written to specify why the dump was
requested. The possible values are as follows:

\begin{tabular}{cl}
1: & dump caused by second SIGINT\\
2: & dump caused by SIGSEGV\\
3: & fault in BOOT or standalone debug\\
4: & dump by user calling \verb|sys(Sys_quit, -2)|\\
5: & dump caused by non zero user fault code\\
6: & dump requested from standalone debug\\
\end{tabular}

\bigskip
\noindent
{\bf rtn\_crntask}\IMPL{y}{y}{n}
\indent
Under Cintpos, this rootnode field point to the TCB of the currently
running task, which is the highest priority task that can run.

\bigskip
\noindent
{\bf rtn\_days}
\IMPL{y}{y}{n}
\indent
This field holds the number of days since 1 January 1970. It is
updated by the interpreter normally within a milli-second of the date
changing.


\bigskip
\noindent
{\bf rtn\_dbgvars}\IMPL{y}{y}{n}
\indent
This rootnode field holds vectors of 10 elements used by the
standalone debugger to hold the debugger variables {\tt V0} to {\tt
V9}. It is in the rootnode to make it accesible to the debugger
and to programs that inspect Cintcode memory dumps.

\bigskip
\noindent
{\bf rtn\_dcountv}\IMPL{y}{y}{n}
\indent
This holds a pointer to the debug count vector. These counters can be
incremented by calls of the form {\tt sys(Sys\_incdcount, n)} or by
similar calls in C within the Cintcode interpreter. The zeroth element
of {\tt dcountv} holds it upper bound which is typically 511.


\bigskip
\noindent
{\bf rtn\_devtab}\IMPL{y}{y}{n}
\indent
Under Cintpos, this holds the Cintpos device table. The zeroth entry
is the table's upperbound and each other entries is either zero, or
points to the device control block (DCB) of the corresponding
device. Some devices are handled by polling in the interpreter thread
based on the count of Cintcode instructions obeyed. Currently the
clock (device {\tt-1}) and {\tt ttyout} (device {\tt-3}) are handled
in this way. This improved the performance of output to the screen and
causes the clock to have a resolution of about 1 milli-second although
the actual clock precision is usually limited by the underlying
operating system.

\bigskip
\noindent
{\bf rtn\_dumpflag}\IMPL{y}{y}{n}
\indent
If {\tt dumpflag} is {\tt TRUE} when Cintsys or Cintpos exits, the
entire Cintcode memory is dumped in a compacted form to the file {\tt
DUMP.mem} for later inspection by commands such as {\tt dumpsys} or
{\tt dumpdebug}.
  
\bigskip
\noindent
{\bf rtn\_envlist}\IMPL{y}{y}{n}
\indent
This rootnode field holds the list of logical name-value pairs used by
the functions {\tt setlogval} and {\tt getlogval}, and the CLI command
{\tt setlogval}. The environment variable held in {\tt envlist} are
distinct from those such as {\tt BCPLROOT} held by the underlying
operating system but have a similar purpose.

\bigskip
\noindent
{\bf rtn\_hdrsvar}\IMPL{y}{y}{n}
\indent
This field holds the name of the environment variable giving the
directories holding BCPL headers, typically "BCPLHDRS" or "POSHDRS".
See Section~\ref{envvars} for more details.

\bigskip
\noindent
{\bf rtn\_idletcb}\IMPL{n}{y}{n}
\indent
This rootnode field holds the TCB of the IDLE task for used by the
standalone debugger and the commands {\tt dumpsys} and {\tt
dumpdebug}. The task number of the IDLE task is zero but it is not a
proper task and does not have an entry in the task table. The Cintpos
scheduler gives it control when all other tasks are suspended.

\bigskip
\noindent
{\bf rtn\_info}\IMPL{y}{y}{n}
\indent
This rootnode field holds a vector of information that can be shared
between all tasks. It is typically a vector of 50 elements.
The use of these elements are system dependent.

\bigskip
\noindent
{\bf rtn\_insadebug}\IMPL{n}{y}{n}
\indent
This rootnode field is used by the keyboard input device of Cintpos to
tell it whether to place a newly received character in a request
packet or just store it in the {\tt lastch} field.

\bigskip
\noindent
{\bf rtn\_intflag}\IMPL{y}{y}{n}
\indent
This flag is set to {\tt TRUE} on receiving an interrupt from the user
(typically a SIGINT signal generated by ctrl-C) and is reset to {\tt
FALSE} whenever the standalone debugger is entered. Cintsys or
cintpos exits if a user interrupt is received when {\tt intflag} is
{\tt TRUE} or if control is within {\tt BOOT} or {\tt sadebug}.

\bigskip
\noindent
{\bf rtn\_gvecsize}\IMPL{y}{y}{n}
\indent
This field holds the size of global vectors created from now on. The
default size is now 2000 but it can be set using the {\tt-g} argument
when entering {\tt cintsys} or {\tt cintpos}.

\bigskip
\noindent
{\bf rtn\_keyboard}\IMPL{y}{y}{n}
\indent
This rootnode field holds the stream control block for the standard
keyboard device.

\bigskip
\noindent
{\bf rtn\_klib}\IMPL{y}{y}{n}
\indent
Under Cintpos this rootnode filed holds the the {\tt KLIB} module. It
is otherwise zero.

\bigskip
\noindent
{\bf rtn\_lastch}\IMPL{n}{y}{n}
\indent
This rootnode field holds the most recent character received from the
keyboard device.  The standalone debugger uses it for polling
input. On reading this field the standalone debugger resets it to {\tt
pollingch=-3}.

\bigskip
\noindent
{\bf rtn\_lastg, rtn\_lastp, \bf rtn\_lastst}\IMPL{y}{y}{n}
\indent
These rootnode fields hold the most recent settings of the Cintcode
{\tt P}, {\tt G} and {\tt ST} registers. They are used by the commands
{\tt dumpsys} and {\tt dumpdebug} when inspecting a Cintcode memory
dump caused by faults such as memory violation (SIGSEGV) when all
other Cintcode dumped registers are invalid.

\bigskip
\noindent
{\bf rtn\_mc0, rtn\_mc1, rtn\_mc2, rtn\_mc3}\IMPL{y}{y}{n}
\indent
These hold the machine address of the start of the Cintcode memory
and other values used by the MC package.

\bigskip
\noindent
{\bf rtn\_membase, rtn\_memsize}\IMPL{y}{y}{n}
\indent
These rootnode fields hold, respectively, the start of the memory
block chain and the upper bound in words of the Cintcode memory.

\bigskip
\noindent
{\bf rtn\_msecs}
\IMPL{y}{y}{n}
\indent
This field holds the number of milli-seconds since midnight.  It is
repeatedly updated by the interpreter and its value is normally
correct to the nearest milli-second.


\bigskip
\noindent
{\bf rtn\_pathvar}\IMPL{y}{y}{n}
\indent
This field holds the name of the environment variable giving the
directories searched by loadseg, typically "BCPLPATH" or "POSPATH".
See Section~\ref{envvars} for more details.

\bigskip
\noindent
{\bf rtn\_quietflag}\IMPL{y}{y}{n}
\indent
This field holds {\tt TRUE} if {\tt cintsys} or {\tt cintpos} was
entered with the {\tt -q} option. This implies that the system is
running in quiet mode.

\bigskip
\noindent
{\bf rtn\_rootvar}\IMPL{y}{y}{n}
\indent
This field holds the name of the environment variable holding the
system root directory, typically "BCPLROOT" or "POSROOT".
See Section~\ref{envvars} for more details.

\bigskip
\noindent
{\bf rtn\_scriptsvar}\IMPL{y}{y}{n}
\indent
This field holds the name of the environment variable giving the
directories holding CLI script files, typically "BCPLSCRIPTS" or "POSSCRIPTS".
See Section~\ref{envvars} for more details.

\bigskip
\noindent
{\bf rtn\_screen}\IMPL{y}{y}{n}
\indent
This rootnode field holds the stream control block for the standard
screen device.

\bigskip
\noindent
{\bf rtn\_sys}\IMPL{y}{y}{n}
\indent
Under Cintsys and Cintpos, this holds the entry point to the {\tt sys}
function.

\bigskip
\noindent
{\bf rtn\_system}\IMPL{y}{y}{y}
\indent
This rootnode field holds 1 when Cintsys is running or 2 when Cintpos
is running.  It is otherwise zero.

\bigskip
\noindent
{\bf rtn\_tallyv}\IMPL{y}{y}{n}
\indent
This rootnode field points to a vector used to hold profile execution
counts. When tallying is enabled, the value of \verb|tallyv!i| is the
count of how often the Cintcode instruction at location {\tt i} has
been executed. The upper bound of {\tt tallyv} is held in
\verb|tallyv!0|. For more information about the profile facility see
the {\tt stats} command described on page~\pageref{stats}.

\bigskip
\noindent
{\bf rtn\_tasktab} \IMPL{y}{y}{n}
\indent
Under Cintpos, this rootnode field holds the Cintpos task table. The
zeroth entry is the table's upperbound and the other entries are
either zero or points to the task control block (TCB) of the
corresponding task. Note that the IDLE task is not held in this table
since it is not a proper task. The IDLE task TCB is held in the
rootnode's {\tt idletcb} field.

\bigskip
\noindent
{\bf rtn\_tcblist}\IMPL{y}{y}{n}
\indent
Under Cintpos, all TCBs are chained together in decreasing priority
order.  This rootnode field points to the first TCB in this chain and
so refers to the highest priority task. The last TCB on the chain has
priority zero and represents the idle task. If not in Cintpos this
field holds zero.  If not in Cintpos this field holds zero.


\bigskip
\noindent
{\bf rtn\_upb}\IMPL{y}{y}{n}
\indent
This is the upperbound of the rootnode. It value is typically 80.

\bigskip
\noindent
{\bf rtn\_vecstatsv}\IMPL{y}{y}{n}
\indent
This points to a vector holding counts of how many blocks of each
requested size have been allocated by {\tt getvec} but not yet
returned. It is used by the {\tt vecstats} command.

\bigskip
\noindent
{\bf rtn\_vecstatsvupb}\IMPL{y}{y}{n}
\indent
This field hold the upper bound of {\tt vecstatsv}.

\bigskip
\noindent
{\bf saveregs}\IMPL{n}{y}{n}
\indent
This is the location in Cintcode memory used in Cintpos to hold
the Cintcode registers at the time of the most recent interrupt.

\bigskip
\noindent
{\label{scbfields}\bf scb\_\ldots}\IMPL{y}{y}{n}
\indent
Each currently open stream has a stream control block (SCB) that holds
all that the system needs to know about the stream. Manifest constants
beginning {\tt scb\_} allow convenient access to the SCB fields. These
are described below.

\bigskip
\noindent
{\bf scb\_blength}\IMPL{y}{y}{n}
\indent
This SCB field holds the length of the buffer in bytes. It is typically
4096.

\bigskip
\noindent
{\bf scb\_block}\IMPL{y}{y}{n}
\indent
This SCB field holds the current block number of a disc file. The
first block of a file has number zero.

\bigskip
\noindent
{\bf scb\_buf}\IMPL{y}{y}{n}
\indent
This SCB field is either zero or points the buffer of bytes,
allocated by {\tt getvec}, associated with the stream.

\bigskip
\noindent
{\bf scb\_bufend}\IMPL{y}{y}{n}
\indent
This SCB field holds the size of the buffer in bytes.

\bigskip
\noindent
{\bf scb\_encoding}\IMPL{y}{y}{n}
\indent
This SCB field controls how {\tt codewrch} treats extended characters
written to this stream. If its value is GB2312, the extended character
is translated into one or two bytes in GB2312 format, otherwise the
translation is to a sequence of bytes in UTF-8 format. This field is
normally set using either {\tt codewrch(UTF8)} or {\tt
codewrch(GB2312)}.

\bigskip
\noindent
{\bf scb\_end}\IMPL{y}{y}{n}
\indent
This SCB field hold the number of valid bytes in the buffer or -1, if the
stream is exhausted.

\bigskip
\noindent
{\bf scb\_endfn}\IMPL{y}{y}{n}
\indent
This SCB field is either zero or the function to close the stream.  It
is given the SCB as its argument and it returns {\tt TRUE} if the call
is successful.  It otherwise returns {\tt FALSE} with an error code in
{\tt result2}.

\bigskip
\noindent
{\bf scb\_fd scb\_fd1\label{scbfd}}\IMPL{y}{y}{n}
\indent
These SCB fields hold a machine dependent file or mailbox descriptor
which is often implemented as a native machine code address.  On some
machines machine addresses are 64 bits long and so cannot be held in a
variable of a 32 bit version of BCPL. So the BCPL system allocates two
consecutive words to hold such values. In order to allow the same
header files be used for 32 and 64 bit BCPL and for 32 and 64 bit
machines, two words are allocated even when one word would be
sufficient.  How a machine addresse is packed in a pair of BCPL words
is implementation dependent except that null pointers cause both words
to be set to zero. This mechanism is used whenever native machine
addresses are held in BCPL variables.


\bigskip
\noindent
{\bf scb\_id}
\IMPL{y}{y}{n}
\indent
This SCB field holds one of the values {\tt id\_inscb}, {\tt
id\_outscb} or {\tt id\_inoutscb}, indicating whether the stream is
for input, output or both.


\bigskip
\noindent
{\bf scb\_lblock}\IMPL{y}{y}{n}
\indent
This SCB field holds the number of last block. The first block of a
stream is numbered zero.

\bigskip
\noindent
{\bf scb\_ldata}\IMPL{y}{y}{n}
\indent
This SCB field holds the number of bytes in the last block of a stream.

\bigskip
\noindent
{\bf scb\_pos}\IMPL{y}{y}{n}
\indent
This SCB field points to the position within the buffer of the next
character to be transferred. This field is updated every time a character
is transferred to or from a stream.

\bigskip
\noindent
{\bf scb\_rdfn}
\IMPL{y}{y}{n}
\indent
This SCB field is zero if the stream cannot perform input, otherwise
it is the function to refill (or replenish) the buffer with more
characters.  It is given the SCB as its argument and returns {\tt
TRUE} if it successfully replenishes the buffer with at least one
character. It otherwise returns {\tt FALSE} setting {\tt result2} to
{\tt-1} if the end of file has been encountered, {\tt-2} if there was
a timeout before any character were read, {\tt-3} no character was
available in polling mode. Any other value in {\tt result2} is an
error code.

\bigskip
\noindent
{\bf scb\_reclen}\IMPL{y}{y}{n}
\indent
A file is normally regarded as a potentially huge sequence of bytes,
but can also be treated as a sequence of fixed length records. The
{\tt reclen} SCB field holds the length in bytes of such records. The
first record of a file has number zero. Unless the length of a file is
a multiple of the record length, the length of last record of a file
will be too short.

\bigskip
\noindent
{\bf scb\_size}\IMPL{y}{y}{n}
\indent
This constant is equal to the number of words in a stream control
block.


\bigskip
\noindent
{\bf scb\_timeout}\IMPL{y}{y}{n}
\indent
This SCB field holds the stream timeout value for TCP streams.  If it
is zero no timeout is applied. If it is negative, data is only
tranferred if it is immediately available. If it is strictly positive
it represents a timeout value in milli-seconds.

\bigskip
\noindent
{\bf scb\_timeoutact}\IMPL{y}{y}{n}
\indent
This SCB field controls the effect of a time out on this stream while
reading using {\tt rdch}. A value of 0 causes the time out to be
ignored, a value of {\tt-1} caused the {\tt rdch} to return with the
value {\tt endstreamch}, and a value of {\tt-2} causes {\tt rdch} to
return with the value {\tt timeoutch}.

\bigskip
\noindent
{\bf scb\_type}\IMPL{y}{y}{n}
\indent
This SCB field holds the type of the stream which will be one of the
following: {\tt scbt\_net}, {\tt scbt\_file}, {\tt scbt\_ram}, {\tt
scbt\_console} or {\tt scbt\_mbx}, {\tt scbt\_tcp}. The last three
have strictly positive values causing output to be triggered by
end-of-line characters, while the first three are negative and only
trigger output when the IO buffer is full. TCP streams have type {\tt
net} or {\tt tcp}, streams to and from disk file have type {\tt file},
stream to or from a vector in main memory have type {\tt ram}, {\tt
mbx} specifies mailbox streams, and {\tt console} indicates that the
stream is either to standard output or from standard input which are
normally the screen and keyboard, respectively.


\bigskip
\noindent
{\bf scb\_task}\IMPL{y}{y}{n}
\indent
Under Cintpos, this SCB field holds either zero or the number of the
handler task associated with the stream, if it has one.

\bigskip
\noindent
{\bf scb\_upb}\IMPL{y}{y}{n}
\indent
This constant is the upperbound of a stream control block. its value
is {\tt scb\_size-1}.

\bigskip
\noindent
{\bf scb\_wrfn}\IMPL{y}{y}{n}
\indent
This SCB field is zero if the stream cannot perform output, otherwise it
is the function to output (or deplete) the buffer.  It is given the
SCB as its argument and returns {\tt TRUE} if it successfully outputs
the contents of the buffer. It otherwise returns {\tt FALSE} with an
error code in {\tt result2}.

\bigskip
\noindent
{\bf scb\_write}\IMPL{y}{y}{n}
\indent
This SCB field is {\tt TRUE} if the buffer has been updated by
functions such as {\tt wrch} since it was last written out (depleted).


\bigskip
\noindent
{\bf scbt\_net, scbt\_file, scbt\_ram,
scbt\_console, scbt\_mbx, scbt\_tcp}\\
\IMPL{y}{y}{n}
\indent
These constants are mnemonics for the possible values of the {\tt type}
field of a stream control block. See {\tt scb\_type} above. 

\bigskip
\noindent
{\bf sectword}\IMPL{y}{y}{n}
\indent
This word occurs near the start of a section of code just before a
compiled string of 11 character representing the section name if a
section name is specified in the source code. If the name is less than
11 characters long it is padded with spaces at the end. If the name
has more than 11 characters, the string consists of the first and last
five separated by a prime ({\tt'}).  Typically {\tt
  sectword=\#x0000FDDF}.

\bigskip
\noindent
{\bf stackword}\IMPL{y}{y}{n}
\indent
As an aid to debugging, all words in runtime stacks are initialised to
{\tt stackword}.  Typically {\tt stackword=\#xABCD1234}.

\bigskip
\noindent
{\bf Sys\_\ldots}\IMPL{y}{y}{y}
\indent
Manifest constants of the form {\tt Sys\_...} provide mnemonics for
the operations invoked by the {\tt sys} function. The use of these
manifest constants is described in pages following Section~\ref{sys}
starting on page~\pageref{sys}.

\bigskip
\noindent
{\bf t\_bhunk, t\_bhunk64, t\_end, t\_end64, t\_hunk, t\_hunk64, 
t\_reloc, t\_reloc64}\\
\IMPL{y}{y}{n}
\indent
These are constants identifying components of Cintcode object modules.
Cintcode modules hold the relocatable byte stream interpretive code
used by all BCPL interpretive systems. Constants with names ending
with {\tt64} are used in the 64-bit version of Cintcode. For more
details, see the description of {\tt loadseg} on
page~\pageref{loadseg}.

\bigskip
\noindent
{\bf tickspersecond}\IMPL{y}{y}{n}
\indent
This constant no longer exists since time is now measured in
milli-seconds (and dates in days).  In both Cintsys and Cintpos,
delays measured in milli-seconds can be achieved using {\tt
delay(msecs)} and delays until a specified absolute time can be done
using {\tt delayuntil(days, msecs)}. Under Cintpos, the clock device
now takes packets that specify absolute times (in days since 1 January
1970 and milli-second since midnight) for their release. For example,
\verb|sendpkt(notinuse, -1, 0, 0, 0, days, msecs)| will resume
execution when the time specified by {\tt days} and {\tt msecs} is
reached. The second argument ({\tt-1}) specifies the clock device.

\bigskip
\noindent
{\bf timeoutch}\IMPL{n}{y}{n}
\indent
This is the value returned by {\tt rdch} when a timeout occurs while
trying to read from a stream. Its value is normally {\tt-2}.
Currently only TCP streams under Cintpos provide the timeout
mechanism.

\bigskip
\noindent
{\bf ug}\IMPL{y}{y}{y}
\indent
This constant specified the first Global variable available to user
programs. Currently {\tt ug=200} so globals below this value are
reserved for system use and the standard library. Since {\tt ug} may
change it would be wise to use it.


\section{Global Variables}

This section describes the global variables declared in {\tt
libhdr.h}.

\bigskip
\noindent
{\bf cis, cos}\IMPL{y}{y}{y}
\indent
These are, respectively, the currently selected input and output
streams. Zero indicates that no stream is selected.

\bigskip
\noindent
{\bf colist}\IMPL{n}{y}{n}
\indent
This holds the list of currently existing coroutines.

\bigskip
\noindent
{\bf consoletask}\IMPL{n}{y}{n}
\indent
This is a variable used by command language interpreters.

\bigskip
\noindent
{\bf currco}\IMPL{n}{y}{n}
\indent
This points to the currently executing coroutine.

\bigskip
\noindent
{\bf currentdir}\IMPL{n}{y}{n}
\indent
This is a string holding the name of the current working directory.

\bigskip
\noindent
{\bf globsize}\IMPL{y}{y}{y}
\indent
This variable is in global zero and holds the size of the global
vector.  Its value is normally 1000.

\bigskip
\noindent
{\bf mainco\_busy}\IMPL{n}{y}{n}
\indent
This is a variable used in the implementation of {\tt gomultievent}
under Cintpos.

\bigskip
\noindent
{\bf multi\_count}\IMPL{n}{y}{n}
\indent
This is a variable used in the implementation of {\tt gomultievent} under
Cintpos.

\bigskip
\noindent
{\bf pktlist}\IMPL{n}{y}{n}
\indent
Under Cintpos when running in multi-event mode, {\tt pktlist} contains
mapping from packets to their corresponding coroutines.

\bigskip
\noindent
{\bf randseed}\IMPL{y}{y}{y}
\indent
This is the seed used by the random number generator {\tt randno}.

\bigskip
\noindent
{\bf result2}\IMPL{y}{y}{y}
\indent
This global variable is used by some functions to return a second
result.

\bigskip
\noindent
{\bf returncode}\IMPL{y}{y}{n}
\indent
This holds the return code of the command most recently executed by
the command language interpreter.

\bigskip
\noindent
{\bf rootnode}\IMPL{y}{y}{n}
\indent
This points to the rootnode.

\bigskip
\noindent
{\bf start}\IMPL{y}{y}{y}
\indent
This is global 1 and is, by convention, the main function of a
program.  It is the first user function to be called when a program is
run by the Command Language Interpreter.

\bigskip
\noindent
{\bf taskid}\IMPL{n}{y}{n}
\indent
Under Cintpos this is the identifier of the currently executing task.
It in not available under Cintsys.

\bigskip
\noindent
{\bf tcb}\IMPL{n}{y}{n}
\indent
Under Cintpos this is a pointer to the currently executing task.

\bigskip
\noindent
{\bf userenv}\IMPL{y}{y}{y}
\indent
This variable is available to the user to hold information that is
preserved from one CLI command to the next. The standard command
language interpreter resets all global variable from {\tt ug} to the
end of the global vector between commands. {\tt userenv} is not in
this region of the global vector and so is preserved. Normally {\tt
userenv} is either zero or points to a user defined structure holding
environmental data.



\section{\label{globalfunctions}Global Functions}

One of the main purposes of the global vector is hold entry points of
functions defined in one module and used in a different module.  This
section describes the function defined in the standard resident
library. Most of these are defined in BCPL in the files: {\tt
sysb/klib.b}, {\tt sysb/blib.b} and {\tt sysb/dlib.b}, one library
({\tt cin/syscin/syslib}) is in hand written Cintcode since it
contains instructions that cannot be generated by the BCPL compiler.
The functions defined in {\tt syslib} are {\tt sys}, {\tt changeco}
and {\tt muldiv}.

The standard library functions are described in alphabetical order.


%GF-A *****************************

\bigskip
\noindent
{\tt abort(\em code\tt)}
\IMPL{y}{y}{n}
\indent\nopagebreak
This causes an exit from the current invocation of the interpreter,
returning {\em code} as the error code.  If {\em code} is zero
execution exits from the Cintcode system. If {\em code} is {\tt-1}
execution resumes using the faster version of the interpreter ({\tt
fasterp}). If {\em code} is {\tt -2} the entire Cintcode memory is
written to file {\tt DUMP.mem} is a compacted form for processing by
CLI commands such as {\tt dumpsys} or {\tt dumpdebug}. If {\em code}
is positive, under normal conditions, the interactive debugger is
entered.

\bigskip
\noindent
{\em res \tt := appendstream(\em scb\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function sets the position of stream {\em scb} to the end so that
anything written to the stream will be appended. The result is {\tt
  FALSE} if {\em scb} is not an inout stream or cannot be positioned
for other reasons. It returns {\tt TRUE} otherwise.


%GF-B *****************************

\bigskip
\noindent
{\em ch \tt:= binrdch()}\IMPL{y}{y}{y}
\indent
This call behaves like {\tt rdch()} but does not skip over carriage
return ({\tt'*c'}) characters.

\bigskip
\noindent
{\em ch \tt:= binwrch(ch)}\IMPL{y}{y}{y}
\indent
This call behaves like {\tt wrch(ch)} but does treat {\tt ch} as a
special character and so does not call {\tt deplete} at the end of
lines and does not insert carriage return ({\tt'*c'}) characters.



%GF-C *****************************

\bigskip
\noindent
{\em res} {\tt:= callco(}{\em cptr}{\tt, }{\em arg}{\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This call suspends the current coroutine and transfers control to the
coroutine pointed to by {\em cptr}. 
It does this by resuming execution of
the function that caused its suspension, which then immediately
returns yielding {\em arg} as result.  When {\tt callco(}{\em
  cptr}{\tt,}{\em arg}{\tt)} next receives control it yields the
result it is given.  The definition of {\tt callco} is in {\tt blib.b}
and is as follows.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        LET callco(cptr, a) = VALOF
        { IF cptr!co_parent DO abort(110)
          cptr!co_parent := currco
          RESULTIS changeco(a, cptr)
        }
\end{verbatim}
\end{samepage}

\smallskip
\noindent
{\tt callco} always leaves the global {\tt currco} is set to point to
the target coroutine. This is done by the Cintcode instruction {\tt
  CHGCO} invoked by {\tt changeco}.

\bigskip
\noindent
{\em res \tt:= callseg(\em name\tt, \em a1\tt, \em a2\tt, \em a3\tt, \em a4\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function loads the compiled program from the file {\em name},
initialises its global variables and calls {\tt start} with the four
arguments {\em a1}{\tt,...,}{\em a4}.  It returns the result of this
call, after unloading the program.
 

\bigskip
\noindent
{\em ch \tt:= capitalch(\em ch\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function converts lowercase letters to uppercase, leaving other
characters unchanged.

\bigskip
\noindent
{\label{changeco}\em res \tt:= changeco(\em val\tt, \em cptr\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function is used in the functions that implement the coroutine
mechanism. In {\tt callco}, {\tt resumeco} and {\tt cowait}, it causes
the current coroutine to become suspended and store {\em cptr} in the
global {\tt currco} before giveing control to the specified coroutine.
Strangely, execution continues just after the call of {\tt changeco}
but with the P pointer pointing to the stack frame of the function
that caused the target coroutine to become suspended.  The call of
{\tt changeco} in each of {\tt callco}, {\tt cowait} and {\tt
  resumeco} is immediately followed by a {\tt RETURN} statement which
causes the corresponding function to return with result {\em val}. The
only other use of {\tt changeco} is in {\tt createco}. This is more
subtle but can be understood by looking at the description of {\tt
  createco} on page~\pageref{createco}.


\bigskip
\noindent
{\em res \tt:= changepri(\em taskid\tt, \em pri\tt)}
\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function attempts to change the priority of the specified
task to {\em pri}. It moves the specified task control block to its
new position in the priority chain. If the specified task is runnable
and of higher priority than the current task, it is given control
leaving the current task suspended in RUN state. The result is non
zero if successful, otherwise it is zero with {\tt result2} set to 101
if {\em taskid} is invalid or to 102 if the change would cause two
tasks to have the same priority.


\bigskip
\noindent
{\em res} {\tt:= clihook(\em arg\tt)\label{clihook}}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function simply calls {\tt start(\em arg\tt)} and returns its
result.  Its purpose is to assist debugging by providing a place to
set a breakpoint in the command language interpreter (CLI) just before
a command in entered.  Occassionally, a user may find it useful to
override the standard definition of clihook with a private version.

\bigskip
\noindent
{\tt codewrch(}{\em code}{\tt)}\IMPL{y}{y}{y}
\indent
This routine uses {\tt wrch} to write the Unicode character {\em
code} as a sequence of bytes in either UTF8 or GB2312 format.  If the
{\tt encoding} field of the current output stream is {\tt UTF8}, the
output is in UTF8 format as described in the following table.

\bigskip
\begin{center}
\begin{tabular}{|l|l|l|}
\hline
Code range & Binary value & UTF8 bytes \\ \hline
\tt0-7F & \footnotesize\tt zzzzzzz & \footnotesize\tt0zzzzzzz\\
\tt80-7FF & \footnotesize\tt yyyyyzzzzzz & \footnotesize\tt110yyyyy 10zzzzzz\\
\tt800-FFFF & \footnotesize\tt xxxxyyyyyyzzzzzz & \footnotesize\tt1110xxxx 10yyyyyy 10zzzzzz\\
\tt1000-1FFFFF & \footnotesize\tt wwwxxxxxxyyyyyyzzzzzz & \footnotesize\tt11110www 10xxxxxx 10yyyyyy 10zzzzzz\\
etc & etc & etc\\
\hline
\end{tabular}
\end{center}

\medskip
\noindent
If the {\tt encoding} field of the current output stream is {\tt
GB2312}, the output is in GB2312 format as described
in the following table.


\bigskip
\begin{center}
\begin{tabular}{|c|c|}
\hline
Decimal range        & GB2312 bytes \\ \hline
\tt0 < dd < 127      & \footnotesize\tt <dd>\\
\tt128 < xxyy < 9494 & \footnotesize\tt <xx+160> <yy+160>\\
\hline
\end{tabular}
\end{center}





\bigskip
\noindent
{\em res} {\tt:= compch(}{\em ch1}{\tt, }{\em ch2}{\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function compares two characters ignoring case.  It yields
{\tt-1} ({\tt+1}) if {\em ch1} is earlier (later) in the collating
sequence than {\em ch2}, and {\tt0} if they are equal.
        
\bigskip
\noindent
{\em res} {\tt:= compstring(}{\em s1}{\tt, }{\em s2}{\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function compares two strings ignoring case.  It yields {\tt-1}
({\tt+1}) if {\em s1} is earlier (later) in the collating sequence
than {\em s2}, and {\tt0} if the strings are equal.


\bigskip
\noindent
{\em res} {\tt:= cowait(}{\em arg}{\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This call suspends the current coroutine and returns control to its
parent by resuming execution of the function that caused its
suspension, yielding {\em arg} as result.  When {\tt cowait(}{\em
arg}{\tt)} next receives control it yields the result it is given.
The definition of {\tt cowait} is in {\tt blib.b} and is as follows.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        LET cowait(a) = VALOF
        { LET parent = currco!co_parent
          currco!co_parent := 0
          RESULTIS changeco(a, parent)
        }
\end{verbatim}
\end{samepage}

\smallskip
\noindent
{\tt cowait} always leaves the global {\tt currco} is set to point to
the resumed coroutine. This is done by the Cintcode instruction {\tt
  CHGCO} invoked by {\tt changeco}.




\bigskip
\noindent
\label{createco}{\em cptr \tt:= createco(\em fn\tt, \em size\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
BCPL uses a stack to hold function arguments, local variables and
anonymous results, and it uses the global vector and static variables
to hold non-local quanitities.  It is sometimes convenient to have
separate runtime stacks so that different parts of the program can run
in pseudo parallelism.  The coroutine mechanism provides this
facility.

Coroutines have distinct stacks but share the same global vector, and
it is natural to represent them by pointers to their stacks.  At the
base of each stack there are six words of system information as shown
in figure~\ref{f3costack}.


\begin{figure}[tbh]
  \centerline{\includegraphics[width=110.9mm]{bfigs/f3costack.png}}
\caption{\label{f3costack}A coroutine stack}
\end{figure}

The resumption point is P pointer belonging to the function that
caused the suspension of the coroutine.  It becomes the value of the P
pointer when the coroutine next resumes execution.  The parent link
points to the coroutine that called this one, or is zero if the
coroutine not active.  The outermost coroutine (or {\em root
coroutine}) is marked by the special value {\tt-1} in its parent link.
As a debugging aid, all coroutines are chained together in a list held
in the global {\tt colist}.  The values {\tt fn} and {\tt sz} hold the
main function of the coroutine and its stack size, and {\tt c} is a
private variable used by the coroutine mechanism.

\begin{figure}[tbh]\centerline{\includegraphics[width=120.7mm]{bfigs/f3changeco.png}}
\caption{\label{f3changeco}The effect of {\tt changeco(a, cptr)}}
\end{figure}

At any time just one coroutine (the {\em current coroutine}) has
control, and all the others are said to be suspended.  The current
coroutine is held in the global variable {\tt currco}, and the
Cintcode P register points to a stack frame within its stack.
Passing control from one coroutine to another involves saving the
resumption point in the current coroutine, and setting new values for
the program counter (PC), the P pointer and {\tt currco}.  This is
done by {\tt changeco(a,cptr)} as shown in figure~\ref{f3changeco}.
The function {\tt changeco} is defined by hand in {\tt syslib} used
by {\tt cintsys} and {\tt cintpos} and its body consists of the
single Cintcode instruction {\tt CHGCO}. As can be seen its effect is
somewhat subtle.  The only uses of {\tt changeco} are in the
definitions of {\tt createco}, {\tt callco}, {\tt cowait} and {\tt
resumeco}, and these are the only functions that cause coroutine
suspension. In the native code version of BCPL {\tt changeco} is
defined in {\tt mlib.s}

\begin{figure}[tbh]
\centerline{\includegraphics[width=143.4mm]{bfigs/f3createco.png}}
\caption{\label{f3createco}The state just after {\tt changeco(0,c)} in 
{\tt createco}}
\end{figure}

The definition of {\tt createco} is in {\tt blib.b} and is as follows.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        LET createco(fn, size) = VALOF
        { LET c = getvec(size+6)
          UNLESS c RESULTIS 0
          FOR i = 6 TO size+6 DO c!i := stackword

          c!0 := c<<B2Wsh // resumption point
          c!1 := currco   // parent link
          c!2 := colist   // colist chain
          c!3 := fn       // the main function
          c!4 := size     // the coroutine size
          c!5 := c        // the new coroutine pointer

          colist := c  // insert into the list of coroutines

          changeco(0, c)

          c := fn(cowait(c)) REPEAT
        }
\end{verbatim}
\end{samepage}

The function {\tt createco} creates a new coroutine by allocating its
stack by the call {\tt gevec(size+6)}. The variable {\tt c} holds a
pointer to the new coroutine stack and, as can been seen, its first
six words are initialised to hold system information, as follows.

\medskip
\begin{tabular}{ll}
  \verb|c!0|  & resumption point\\
  \verb|c!1|  & parent link\\
  \verb|c!2|  & colist chain\\
  \verb|c!3|  & {\em fn} -- the main function\\
  \verb|c!4|  & {\em size} -- the coroutine size\\
  \verb|c!5|  & c -- the new coroutine pointer\\
\end{tabular}

\medskip
\noindent
The coroutine list {\tt colist} is also set to {\tt c}.

The call {\tt changeco(0, c)} causes the P pointer to be set to {\tt
  c!0} which has been initialied to the address of the base of the new
coroutine stack. Execution continues just after the call, namely at
the REPEAT loop in the body of {\tt createco}, but in the coroutine
environment of the newly created coroutine.  The compiled code for
this loop will assume {\tt fn}, {\tt size} and {\tt c} reside in
positions 3, 4 and 5 relative to P, ie in memory locations \verb|c!3|,
\verb|c!4| and \verb|c!5| so execution behaves as (naively)
expected. The first time {\tt cowait(c)} is called in this loop,
execution returns from {\tt createco} with the result {\tt c}
pointing to the newly created coroutine.

When control is next transferred to this new coroutine, the value passed
becomes the result of {\tt cowait} and hence the argument of {\tt fn}.
If {\tt fn(..)} returns normally, its result is assigned to {\tt c}
which is returned to the parent coroutine by the repeated call of {\tt
cowait}.  Thus, if {\tt fn} is simple, a call of the coroutine convert
the value passed, {\tt val} say, into {\tt fn(val)}.  However, in
general, {\tt fn} may contain calls of {\tt callco}, {\tt cowait} or
{\tt resumeco}, and so the situation is not always quite so simple.

To help to fully understand the subtle effect of effect of {\tt
  changeco(0,c)}, look at figure~\ref{f3createco} which shows the
state just after {\tt changeco} transfers control to the newly created
coroutine. At this moment the newly created coroutine immediately
suspends it self by calling {\tt cowait} in the loop:

\smallskip
\noindent
\verb|        c := fn(cowait(c)) REPEAT|

\smallskip
\noindent
at the end of {\tt createco}.



\bigskip
\noindent
{\em devid \tt:= \tt createdev(\em dcb\tt )}%
\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function creates a device using the first available slot
in {\tt devtab}. The device control block {\em dcb} must have already
been initialised and linked to its device driver. If successful it
returns a negative value identifying the device. On failure it returns
zero with {\tt result2} set to 104 if the {\tt devtab} is full, or to
106 if device initialisation failed.

\bigskip
\noindent
{\em res \tt:= \tt createtask(\em seglist\tt, \em stsize\tt, \em pri\tt )}%
\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function creates a task using the first free slot in the
task table. It allocates space for the new task control block (TCB)
and a copy of the specified segment list, and initialises them
both. It inserts the new TCB in priority chain of tasks and returns
the id of the newly created task if successful. It is left in DEAD
state with no stack or global vector and no packets on its work queue.
If there is an error, it returns zero with {\tt result2} set to 102 if
there is already a task with priority {\em pri}, or to 103 if there is
insufficient memory or to 105 if the task table is full. A segment
list is a small vector whose zeroth element holds its upperbound and
whose other elements hold lists of sections of code typically loaded
by {\tt loadseg}.

%GF-D *****************************

\bigskip
\noindent
{\tt datstamp(}{\em datv}{\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This sets {\em datv\tt!0} to the number of days since 1 January 1970,
and {\em datv\tt!1} to the number of milli-seconds since midnight, and
for compatability with the older version of datstamp {\em
datv\tt!2=-1} indicating the new date and time format is being used.


\bigskip
\noindent
{\tt dat\_to\_string(\em datv\tt, \em v\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This call causes the time stamp in {\em datv} to be converted to three
strings {\em v}, {\em v\tt+5} and {\em v\tt+10}. The string at {\em v}
is set to the date in the form {\tt dd-mmm-yyyy}.  The string at {\em
v\tt+5} is set to the the current time in the form hh:mm:ss, and the
string at {\em v\tt+10} is set to the day of the week. The upper bound
of {\em v} should be at least 14 to be safe. The time stamp is
typically obtained by a call of {\tt datstamp(datv)} which sets {\tt
datv!0} to the number of days since 1 January 1970, {\tt datv!1} to
the number of milli-seconds since midnight and {\tt datv!2} to -1
indicting that the new date and time format is being used.

 
\medskip
\begin{samepage}
\noindent
{\tt delay(\em msecs}{\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This call suspends execution for at least {\em msecs} milli-seconds.
Under Cintpos, this is achieved by sending a suitable packet to the
clock device (using {\tt sendpkt}) and waiting for it to be returned.
\end{samepage}

\bigskip
\noindent
{\tt delayuntil(\em days\tt, \em msecs}{\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This call suspends execution until the specified date and time is
reached.  {\em days} specifies the date as the number of days since 1
January 1970 and {\em msecs} is the number of milli-seconds since
midnight. Under Cintpos, the delay is achieved by sending a suitable
packet to the clock device (using {\tt sendpkt}) and waiting for it to
be returned.


\bigskip
\noindent
{\tt deleteco(}{\em cptr}{\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This call takes a coroutine pointer as argument and, after checking
that the corresponding coroutine has no parent, deletes it by
returning its stack to free store.


\bigskip
\noindent
{\em dcb \tt:= \tt deletedev(\em devid\tt )}%
\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function closes down the specified device and deallocates
it device identifier, but it does not return its device control block
(DCB) to free store. It returns any packets still on its work queue to
the requesting tasks with both the {\tt pkt\_res1} and {\tt pkt\_res2}
fields set to {\tt-1}. If successful, it returns the DCB of the
deleted device. On failure, it returns zero with {\tt result2} set to
101 indicating that {\em devid} was invalid. If any of the released
packets cause a higher priority task to become runnable, the control
passes to the highest priority one leaving the current task suspended
in RUN state. The clock device has identifier {\tt-1} and is
permanently resident and cannot be deleted.



\bigskip
\noindent
{\em flag \tt:= deletefile(\em name\tt)}
\IMPL{y}{y}{y}
\indent
This call deletes the named file, returning {\tt TRUE} if successful,
and {\tt FALSE} otherwise.

\bigskip
\noindent
{\em res \tt:= \tt deleteself(\em pkt\tt, \em seg\tt )}%
\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function first calls {\tt qpkt} to return the packet if
{\em pkt} is non zero, then calls {\tt unloadseg(\em seg\t)} if {\em
seg} is non zero, before deleting the current task. This function is
defined in {\tt klib} since it would be unsafe for it to be in a
segment that may be unloaded while it is being executes. It returns a
non zero value if successful but, of course, this value will never be
seen! On failure, it return zero with {\tt result2} set to 108
indicating that the current task is not deletable.

\bigskip
\noindent
{\em res \tt:= \tt deletetask(\em taskid\tt )}%
\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function attempts to delete the specified task which must
have an empty work queue and be either the current task or in DEAD
state. Its task control block (TCB) is unlinked from the priority
chain and removed from {\tt tasktab}. Finally its segment list and the
TCB itself returned to free store. It returns a non zero value if
successful. On failure, it returns zero with {\tt result2} set to 101
if {\em taskid} is invalid, or to 108 if the task is not deletable.


\bigskip
\noindent
{\em res \tt:= dqpkt(\em id\tt, \em pkt\tt)}
\IMPL{n}{y}{n}
\indent
This Cintpos function attempts to dequeue the given packet from the
task or device specified by {\em id}. If not found there, it may have
already been returned to the current task so its work queue is
searched. The result is the id of the task or device whose work queue
contained the packet. If there is an error, the result is zero with
{\tt result2} set to 101 for invalid id or 109 if the packet was not
found. The id field of the packet is set to the id of the task or
device whose work queue contained the packet provided that this is not
the id of the current task.


%GF-E *****************************

\bigskip
\begin{samepage}
\noindent
{\tt endread()}
\IMPL{y}{y}{y}
\indent
This routine closes the currently selected input stream by calling
{\tt endstream(cis)}.
\end{samepage}

\bigskip
\noindent
{\tt endstream(\em scb\tt)}
\IMPL{y}{y}{y}
\indent
This routine closes the stream whose control block is {\em scb}.


\bigskip
\noindent
{\tt endwrite()}
\IMPL{y}{y}{y}
\indent
This routine closes the currently selected output stream by calling
{\tt endstream(cos)}.


%GF-F *****************************

\bigskip
\noindent
{\em scb \tt:= findappend(\em name\tt)}\IMPL{y}{y}{y}
\indent
This function opens an output stream specified by the file name {\em
name} in append mode causing all output to be appended onto the end of
the file.  If the file name is relative and the prefix string is set,
it is prepended to the name before attempting to open the stream.  If
the file does not exist a zero length file of the given name is
created.  If there is an error the result is zero.

\bigskip
\noindent
{$n$ \tt:= findarg(\em keys\tt, \em item\tt)}
\IMPL{y}{y}{y}
\indent
The function {\tt findarg} was primarily designed for use by {\tt
rdargs} but since it is sometimes useful on its own, it is publicly
available.  Its first argument, {\em keys}, is a string of keys of the
form used by {\tt rdargs} and item is a string.  If the result is
positive, it is the argument number of the keyword that matches item,
otherwise the result is \verb|-1|. During matching all letters are
converted to uppercase, but this convention may change in future.
        

\bigskip
\noindent
{\em scb \tt:= findinput(\em name\tt)}\IMPL{y}{y}{y}
\indent
This function opens an input stream.  If {\em name} is the string
{\tt"*"} then it opens the standard input stream which is normally
from the keyboard, otherwise {\em name} is taken to be a device or
file name.  If the file name is relative and the prefix string is set,
it is prepended to the name before attempting to open the stream. If
the stream cannot be opened the result is zero.  See
Section~\ref{filenames} for information about the treatment of
filenames.


\bigskip
\noindent
{\em scb \tt:= findinoutput(\em name\tt)}\IMPL{y}{y}{y}
\indent
This function opens a stream specified by the device or file name {\em
  name} that can be used for both input and output.  If {\em name} is
the string {\tt"*"} then output is normally to the screen and input
comes from the keyboard.  If the file name is relative and the prefix
string is set, it is prepended to the name before attempting to open
the stream. If the stream cannot be opened, the result is zero.  See
Section~\ref{filenames} for information about the treatment of
filenames.


\bigskip
\noindent
{\em scb \tt:= findoutput(\em name\tt)}\IMPL{y}{y}{y}
\indent
This function opens an output stream specified by the device or file
name {\em name}.  If {\em name} is the string {\tt"*"} then it opens
the standard output stream which is normally to the screen.  If the
file name is relative and the prefix string is set, it is prepended to
the name before attempting to open the stream. If the stream cannot be
opened, the result is zero.  See Section~\ref{filenames} for
information about the treatment of filenames.


%GF-G *****************************

\bigskip
\noindent
{\em res} {\tt:= get\_record(\em v\tt, \em recno\tt, \em scb\tt)}
\IMPL{y}{y}{y}
\indent
This attempts to read the record numbered {\em recno} from the file
whose stream control block is {\em scb} into the vector {\em v}.  The
record length must have been set already by a call of {\tt
setrecordlength}. If {get\_record} is successful it returns {\tt
TRUE}, otherwise it returns {\tt FALSE} possibly because the end of
file was reached before the whole record had been read.


\bigskip
\noindent
{\em v} {\tt:= getlogname(}{\em logname}{\tt)}
\IMPL{y}{y}{y}
\indent
This function searches the list of logical variables held in the root node
and returns its value if found, otherwise it returns zero.


\bigskip
\noindent
{\em v} {\tt:= getvec(}{\em upb}{\tt)}
\IMPL{y}{y}{y}
\indent
This function allocates space using a first fit algorithm based on
a list of blocks chained together in memory order.  Word zero of each
block in the chain contains a flag in its least significant bit
indicating whether the block is allocated or free.  The rest of the
word is an even number giving the size of the block in words.  A
pointer to the first block in the chain is held in the rootnode.

{\tt getvec} allocates a vector with upper bound {\em upb} from the
first large enough free block on the block list.  If no such block
exists it returns zero.  A vector previously allocated by {\tt getvec}
can be freed by the above call of {\tt freevec}.  Coalescing of
adjacent free blocks is performed by {\tt getvec}.

An extra word is allocated just before the start of each block to hold
its size, and four or five words are added to the end of each block
and filled with special data that is checked when the block is
returned to free store. This catches many common space allocation
errors.

\bigskip
\noindent
{\em res \tt:= globin(\em segl\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function initialises the global variables defined in the list of
program modules given by its argument {\em segl}.  It returns zero if
the global vector was too small, otherwise it returns {\em segl}.

%GF-H *****************************

\bigskip
\noindent
{\em res \tt:= hold(\em taskid\tt)}
\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function sets the HOLD bit in the task control block of
the specified task. It returns a non zero value if successful.  If
there is an error, it returns zero with {\tt result2} set to 101 if
{\em taskid} was invalid, and 110 if the specified task was already in
HOLD state. If the task holds itself control is given to next lower
priority runnable task.

%GF-I *****************************

\bigskip
\noindent
{\em cptr \tt:= initco(\em fn\tt, \em size%
\tt,\em a%
\tt,\em b%
\tt,\em c%
\tt,\em d%
\tt,\em e%
\tt,\em f%
\tt,\em g%
\tt,\em h%
\tt,\em i%
\tt,\em j%
\tt,\em k%
\tt)}
\IMPL{y}{y}{y}
\indent\nopagebreak
This function provides a convenient method of creating and initialising
coroutines.  It definition is as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET initco(fn, size, a, b, c, d, e, f, g, h, i, j, k) = VALOF
{ LET cptr = createco(fn, size)
  result2 := 0
  IF cptr DO result2 := callco(cptr, @a)
  RESULTIS cptr
}
\end{verbatim}
\end{samepage}

A coroutine with main function {\em fn} and given size is created and,
if successful, it is initialised by {\tt callco(}{\em
cptr}{\tt,~@$a$)}. Thus, {\em fn} should expect a vector containing up
to 11 elements.  Once the newly created coroutine has initialised
itself, it returns control to {\tt initco} by means a call of
{\tt cowait}. The result of {\tt initco} is the newly created
coroutine pointer, or zero on failure. The second result (in {\tt
result2}) is the value returned by the first call of {\tt cowait} in
the newly created coroutine.



\bigskip
\noindent
{\em scb} {\tt:= input()}\IMPL{y}{y}{y}
\indent
This function returns {\tt cis}, the SCB of the currently selected
input stream.


\bigskip
\noindent
\label{instrcount}{\em count \tt:= instrcount(\em fn%
\tt,\em a%
\tt,\em b%
\tt,\em c%
\tt,\em d%
\tt,\em e%
\tt,\em f%
\tt,\em g%
\tt,\em h%
\tt,\em i%
\tt,\em j%
\tt,\em k%
\tt)}
\IMPL{y}{y}{n}
\indent
This function returns the number of Cintcode instructions executed
when evaluating the call:
{\em fn}%
{\tt(}{\em a}%
{\tt,}{\em b}%
{\tt,}{\em c}%
{\tt,}{\em d}%
{\tt,}{\em e}%
{\tt,}{\em f}%
{\tt,}{\em g}%
{\tt,}{\em h}%
{\tt,}{\em i}%
{\tt,}{\em j}%
{\tt,}{\em k}%
{\tt)}.

Counting starts from the first instruction of the body of {\em fn}
and ends when its final {\tt RTN} instruction is executed. Thus when
{\tt f} was defined by {\tt LET f(x) = 2*x+1}, the call {\tt
instrcount(f, 10)} returns 4 since its body executes the four
instructions: \verb|L2; MUL; A1; RTN|. The value returned by 
{\em fn}%
{\tt(}{\em a}%
{\tt,}{\em b}%
{\tt,}{\em c}%
{\tt,}{\em d}%
{\tt,}{\em e}%
{\tt,}{\em f}%
{\tt,}{\em g}%
{\tt,}{\em h}%
{\tt,}{\em i}%
{\tt,}{\em j}%
{\tt,}{\em k}%
{\tt)} is saved by {\tt instrcount} in the global variable {\tt result2}.




\bigskip
\noindent
{\em flag \tt:= intflag()}
\IMPL{y}{y}{n}
\indent\nopagebreak
This function provides a machine dependent test to determine whether
the user is asking to interrupt the normal execution of a program.

%GF-J *****************************
%GF-K *****************************
%GF-L *****************************

\bigskip
\noindent
{\tt $p$ := level()}
\IMPL{y}{y}{y}
\indent
This call returns the current stack frame pointer for use in a
later call of {\tt longjump}.

\bigskip
\noindent
{\em segl} {\tt:= loadseg(\em name\tt)}
\IMPL{y}{y}{n}
\indent\nopagebreak
This function calls {\tt sys(Sys\_loadseg, \em name\tt)} to loads the
specified compiled program into memory. See {\tt Sys\_loadseg} on
page~\pageref{loadseg} for details.


\bigskip
\noindent
{\tt longjump($P$, $L$)}
\IMPL{y}{y}{y}
\label{longjump}
\indent
This call causes execution to resume at label $L$ in the body of a
function or routine that owns the stack frame given by $P$ that must
have been obtained by a previous call of {\tt level}.  Jumps may only
be used to points within the current coroutine. Jumps to labels within
the current function or routine can be performed using the {\tt GOTO}
command, so {\tt level} and {\tt longjump} are only needed for non
local jumps.



%GF-M *****************************

\bigskip
\noindent
{\em res} {\tt:= memoryfree() }
\IMPL{y}{y}{n}
\indent
This function checks that the free store chain is valid, outputting a
error message and calling {\tt abort(999)} if not. If the chain is
valid, it returns the current number of unused words, and sets {\tt
  result2} to the memory size. This function can assist debugging and
helps with the detection of space leaks.

\bigskip
\noindent
{\label{mkobj}\em obj \tt:= mkobj(%
\em upb\tt,%
\em fns\tt,%
\em a\tt,%
\em b\tt,%
\em c\tt,%
\em d\tt,%
\em e\tt,%
\em f\tt,%
\em g\tt,%
\em h\tt,%
\em i\tt,%
\em j\tt,%
\em k\tt)}
\IMPL{y}{y}{y}
\indent
This function creates and initialises an object. It definition is as
follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET mkobj(upb, fns, a, b, c, d, e, f, g, h, i, j, k) = VALOF
{ LET obj = getvec(upb)
  IF obj DO
  { !obj := fns
    InitObj#(obj, @a) // Send the init message to the object
  }
  RESULTIS obj
}
\end{verbatim}
\end{samepage}

As can be seen, it allocates a vector for the fields of the object,
initialises its zeroth element to point to the methods vector and
calls the initialisation method that is expected to be in element {\tt
InitObj} of {\em fns}.  The result is a pointer to the initialised
fields vector.  If it fails, it returns zero.  As can be seen the
initialisation method receives a vector of up to 11 initialisation
arguments.

\bigskip
\noindent
{\em res} {\tt:= muldiv($a$, $b$, $c$) }
\IMPL{y}{y}{y}
\label{muldiv}\indent
The result is the value obtained by dividing $c$ into the double
length product of $a$ and $b$, the remainder of this division is left
in the global variable {\tt result2}.  The result is undefined if it
is too large to fit into a single length word or if $c$ is zero.  The
result is also undefined if any of $a$, $b$ or $c$ is the largest
negative integer.

This version of {\tt muldiv} is defined in the hand written Cintcode
library {\tt syslib} and invokes the {\tt MDIV} Cintcode instruction
which is implemented efficiently. The older version is invoked by {\tt
sys(Sys\_muldiv,a,b,c)} and uses binary long division implemented in
C. Both versions are believed to produce identical results except
possibly when {\tt c=0}.

As an example, the function defined below calculates the cosine of the
angle between two unit vectors in three dimensions using scaled
integers to represent numbers with 6 digits after the decimal point.


\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
MANIFEST { Unit=1000000 } // Scaling factor for numbers of the
                          // form ddd.dddddd

FUN inprod(v, w) = muldiv(v!0, w!0, Unit) +
                   muldiv(v!1, w!1, Unit) +
                   muldiv(v!2, w!2, Unit)
\end{verbatim}
\end{samepage}

Remember that scaled fixed point values can be output conveniently
using {\tt writef} as in:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
writef("%10.6d*n", 123_456789)
\end{verbatim}
}

\noindent
which will output the following:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
123.456789
\end{verbatim}
}

%GF-N *****************************

\bigskip
\noindent
{\tt newline()}
\IMPL{y}{y}{y}
\indent
This simply outputs the newline character (\verb|'*n'|) to the
currently selected output stream.

\bigskip
\noindent
{\tt newpage()}\IMPL{y}{y}{y}
\indent
This simply outputs the newline character (\verb|'*p'|) to the
currently selected output stream.

\bigskip
\noindent
{\em res} {\tt:= note(\em scb\tt, \em posv\tt)}
\IMPL{y}{y}{y}
\indent
If {\em scr} is a file stream, this function sets {\em posv\tt!0} and {\em
  posv\tt!1} to the current block number and position within that block.
For RAM streams, {\em posv\tt!0} and {\em posv\tt!1} are set to zero and
the position within the stream buffer.  The result is {\tt TRUE} if {\em
  scb} is a file or RAM stream, and {\tt FALSE} otherwise.



%GF-O *****************************

\bigskip
\noindent
{\em scb} {\tt:= output()}\IMPL{y}{y}{y}
\indent
This function returns {\tt cos}, the SCB of the currently selected
output stream.


%GF-P *****************************


\bigskip
\noindent
{\em scb \tt:= pathfindinput(\em name\tt, \em pathname\tt)}\IMPL{y}{y}{y}
\indent
This function opens an input stream.  If {\em name} is the string
{\tt"*"} then input comes from standard input which is normally the
keyboard, otherwise {\em name} is taken to be a filename.  If {\tt
name} is a relative file name and {\tt pathname} is non zero, the
directories specified by the shell variable {\em pathname} are
searched. The directories specified by the shell variable are
separated by either semicolons or colons, although under Windows only
semicolons are allowed.  If the prefix string is non null and the
filename, possibly prefixed by a directory name, is relative then the
prefix string is prepended before the file is opened.  If the file
cannot be opened {\tt pathfindinput} returns zero.

\bigskip
\noindent
{\em res} {\tt:= point(\em scb\tt, \em posv\tt)}
\IMPL{y}{y}{y}
\indent
This function sets the position of stream {\em scb} to that specified
in {\em posv} whose elements are {\em scb}\verb|!0| the block number
and {\em scb}\verb|!1| the byte position within the block.  If the new
position is in a different block the contents of the buffer buffer may
have to be written out and data from the new block read in.  {\tt
  point} may therefore fail if the stream was not opened using {\tt
  findinput} or {\tt findinoutput}. It returns {\tt TRUE} if
  successful, even if positioned just after the last block of the
  file, ie {\tt block=lblock+1} and {\tt pos=end=0}.  It returns {\tt
    FALSE}, otherwise, possibly because the stream is not pointable or
  the {\em posv} is out of range.  It is advisable to test the result
  of {\tt point} every time it is used.

 For RAM streams {\em posv\tt!0} should be zero and {\em posv\tt!1}
 should be a position in the buffer (which is entirely held in RAM).


\bigskip
\noindent
{\em res} {\tt:= put\_record(\em v\tt, \em recno\tt, \em scb\tt)}
\IMPL{y}{y}{y}
\indent
This attempts to write a record numbered {\em recno} to the file whose
stream control block is {\em scb} taking data from the vector {\em
v}. The record length must have been set already by a call of {\tt
setrecordlength}. If {put\_record} is successful it returns {\tt
TRUE}, otherwise it returns {\tt FALSE}. If the last record of a file
has number {\em n}, it is permissible to extend the file by writing
record {\em n+1}, but not one with a larger record number.





%GF-Q *****************************

\bigskip
\noindent
{\em res \tt:= qpkt(\em pkt\tt)}\IMPL{n}{y}{n}
\indent
This Cintpos function queues the given packet on the end of the work
queue of the destination task or device (specified by {\tt pkt\_id!\em
pkt}). If this field is positive it refers to a task, if it is {\tt-1}
it refers to the clock device and other negative values refer to other
devices. If the packet is queued successfully this field is updated to
hold the current task's identifier and the result is non zero,
otherwise the result is zero with {\tt result2} set to 101 if the
destination id is invalid, and to 111 if {\tt pkt\_link} was not equal
to {\tt notinuse} ({\tt=-1}). If the destination was a runnable task
of higher priority than the current one, then the current task
immediately becomes suspended in RUN state and control is given to the
destination, otherwise the current task continues to run normally.
Interaction with the resident Cintpos devices is described in
Chapter~\ref{posdevices}.

%GF-R *****************************

\bigskip
\noindent
$n$ {\tt:= randno(}{\em upb}{\tt)}\IMPL{y}{y}{y}
\indent
This function returns a random integer in the range {\tt1} to {\tt
upb}. It uses a seed held in global variable {\tt randseed} which can
be set using {\tt setseed} described below. Its implementation is as
follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET randno(upb) = VALOF
{ randseed := randseed*2147001325 + 715136305
  RETURN ABS(randseed/3) MOD upb + 1
}
\end{verbatim}
\end{samepage}


\bigskip
\noindent
{\em res \tt:= rdargs(\em keys\tt, \em argv\tt, \em upb\tt)}\IMPL{y}{y}{y}
\indent
This implementation of BCPL incorporates a command language
interpreter which is described in Chapter~\ref{CLI}.  Most commands
require arguments and these are easily read using {\tt rdargs}.

The first argument ({\em keys}) specifies the argument format.  The
second and third arguments provide a vector ({\em argv}) with a given
upper bound ({\em upb}) into which the decoded arguments will be
placed.  If {\tt rdargs} is successful, it returns the number of words
used in {\em argv} to represent the decoded command arguments, but on
failure, it returns zero.

The string {\em keys} holds the list of argument keywords separated by
commas ({\tt,}). Alternative keywords for a given argument are
separated by equal signs ({\tt=}). The expected number of arguments is
one more than the number of commas in the key string. If {\tt rdargs}
returns successfully, this number of elements at the start of {\em
  argv} will hold the decoded arguments.

Arguments can have qualifiers of the form {\tt /A}, {\tt /K}, {\tt
  /N}, {\tt /S} and {\tt /P}. The qualifier letters can be in either
upper or lower case. The qualifier {\tt /A} means that the argument
must be given. {\tt/K} means that, if the argument is given, it must
include its keyword. {\tt/N} specifies that the argument must be a
number. {\tt/S} indicates that the argument is a switch parameter set
to {\tt TRUE} by its keyword. {\tt/P} indicates that a prompt will be
given for the argument if it has not already been set. Prompting only
happens if the currently selected input and output streams are both
connected to an interactive terminal. If the prompt is for a switch
argument ({\tt/S}) it expects a yes/no response. Typing {\tt yes} or
{\tt y} is treated as yes, any other response is treated as no. If
{\tt rdargs} returns successfully {\em argv}{\tt!0}, {\em argv}{\tt!1}
etc will hold the arguments settings. A setting of zero means the
argument was not given.  A setting of {\tt-1} means the argument was a
switch set the {\tt TRUE}.  Otherwise, if {\tt/N} was specified the
setting will point to a word in {\em argv} where the decoded integer
is stored. If a {\tt/N} was not specified, the setting will be a BCPL
string with its characters packed into {\em argv}. Note that an
argument should not have both {\tt/N} and {\tt/S} specified.

Command arguments are read from the currently selected input stream
using a decoding mechanism that permits both positional and keyed
arguments to be freely mixed.  A typical use of {\tt rdargs} occurs in
the source of the {\tt input} command as follows:

\begin{center}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
UNLESS rdargs("FROM/A,TO=AS/K,DATA/N/P,N/S", argv, 50) DO
{ writef("Bad arguments for: FROM/A,TO=AS/K,DATA/N/P,N/S*n")
  ...
}
\end{verbatim}
\end{samepage}
\end{center}

In this example, there are four possible arguments and their values
will be placed in the first four elements of {\tt argv}.  The first
argument has keyword {\tt FROM} and must receive a value because of
the qualifier {\tt/A}.  The second has alternative keywords {\tt TO}
and {\tt AS} with qualifier {\tt/K} that insists the argument is
introduced by one of its keywords.  The third argument has the
qualifiers {\tt/N} and {\tt/P} indicating that it expects a number and
that it will be prompted for if not already given, and the last
argument has the qualifier {\tt/S} indicating that it is a switch that
can be set by the presence of its keyword.

Table~\ref{rdargs} shows the values in placed in {\tt argv} and the
result when the call:

\medskip
\centerline{\tt rdargs("FROM/A,TO=AS/K,DATA/N/P,N/S", argv, 50)}

\medskip
\noindent
is given various argument strings.  This example illustrates that
keyword synonyms can be defined using {\tt=} within the key string.
Positional arguments are those not introduced by keywords.  When one
is encountered, it becomes the value of the lowest numbered unset
non-switch argument.

\begin{figure}[tbh]
\begin{center}
\begin{tabular}{|l|c|c|c|c|c|}
\hline
Arguments       &{\tt argv!0} &{\tt argv!1} &{\tt argv!2} &{\tt argv!4} &Result
                        \rule[-3mm]{0mm}{8mm}\\
\hline
{\tt abc TO xyz}      &{\tt "abc"}  &{\tt "xyz"} &{\tt0} &{\tt0}  &\verb|~=0|\\
{\tt to xyz from abc} &{\tt "abc"}  &{\tt "xyz"} &{\tt0} &{\tt0}  &\verb|~=0|\\
{\tt as xyz abc n}    &{\tt "abc"}  &{\tt "xyz"} &{\tt0} &{\tt-1} &\verb|~=0|\\
{\tt abc xyz}         &{\tt-}       &{\tt-}      &{\tt-} &{\tt-}  &\verb|=0|\\
{\tt "from" to "to"}  &{\tt "from"} &{\tt "to"}  &{\tt0} &{\tt0}  &\verb|~=0|\\
{\tt abc data 123 to "to"}  &{\tt "abc"} &{\tt "to"}  &{\tt->123} &{\tt0}  &\verb|~=0|\\
{\tt data 123 to junk}  &{\tt-} &{\tt-}  &{\tt-} &{\tt-}  &\verb|=0|\\
\hline
\end{tabular}
\end{center}
\caption{\label{rdargs}{\tt rdargs("FROM/A,TO=AS/K,DATA/N/P,N/S", argv, 50)}}
\end{figure}

To consolidate your understanding of {\tt rdargs}, try compiling and
running the program: \verb|bcplprogs/tests/tstrdargs.b|.

\bigskip
\noindent
{\em res \tt:= rdargs2(\em keys1\tt, \em keys2\tt, \em argv\tt, \em upb\tt)}\IMPL{y}{y}{y}
\indent
This function behaves just like {\tt rdargs}, specified above, except
it uses key data that is the concatenation of strings \verb|keys1| and
\verb|keys2| thus allowing the key data to have up to than 510
characters.


 
\bigskip
\noindent
{\em ch \tt:= rdch()}\IMPL{y}{y}{y}
\indent
This call reads the next character from the currently selected input
stream.  If the stream is exhausted, it returns the special value {\tt
endstreamch}.  Input from the keyboard is buffered until the ENTER (or
RETURN) key is pressed to allow simple line editing in which the
backspace key may be used to delete the most recent character typed.
See Section~\ref{streams} for more detailed information.

\bigskip
\noindent
{\em kind \tt:= rditem(\em v\tt, \em upb\tt)}\IMPL{y}{y}{y}
\indent
This function is usually called from {\tt rdargs} to read an item from
the currently selected input stream.  After ignoring leading spaces
and tabs, it packs the item into the vector $v$ whose upper bound is
{\em upb} and returns an integer describing the kind of item read.
Table~\ref{rditemtypes} gives the kinds of item that can be read and
corresponding item codes.

\begin{figure}[tbh]
\begin{center}
\begin{tabular}{|l|l|c|}
\hline
Example items         & Kind of item          &Item code
                                  \rule[-3mm]{0mm}{8mm}\\
\hline
{\tt=}                &                       &5\\
\hline
{\tt;}                &                       &4\\
\hline
{\em carriage return} &                       &3\\
\hline
{\tt"from"}           &                       & \\
{\tt"*ntwo words*n"}  & Quoted string         &2\\
\hline
{\tt abc}             &                       & \\
{\tt 123-45*6}        & Unquoted string       &1\\

\hline
{\em end-of-stream}   & Terminator            &0\\
\hline
                      & An error              &-1\\
\hline
\end{tabular}
\end{center}
\caption{\label{rditemtypes}{\tt rditem} results}
\end{figure}

Within quoted strings
\verb|*n| represents the newline character,
\verb|*s| represents a space,
\verb|**| represents an asterisk and
\verb|*"| represents a double quote character.

\bigskip
\noindent
$n$ {\tt:= readflt()}\IMPL{y}{y}{y}
\indent
This reads an optionally signed floating point number from
the currently selected input stream.  Leading spaces, tabs and
newlines are ignored.  If the number is syntactically correct, it
returns its value with {\tt result2} set to zero, otherwise it
returns zero with {\tt result2} set to {\tt-1}.  In either case, it
uses {\tt unrdch} to replace the terminating character.

\bigskip
\noindent
$n$ {\tt:= readn()}\IMPL{y}{y}{y}
\indent
This reads an optionally signed decimal integer from
the currently selected input stream.  Leading spaces, tabs and
newlines are ignored.  If the number is syntactically correct, it
returns its value with {\tt result2} set to zero, otherwise it
returns zero with {\tt result2} set to {\tt-1}.  In either case, it
uses {\tt unrdch} to replace the terminating character.

\bigskip
\noindent
{\em res \tt:= recordnote(\em scb\tt)}\IMPL{y}{y}{y}
\indent
This call returns the number of the record containing the character
pointed to by the file position pointer of stream {\em scb}.  The
record length must have already been set by a call of {\tt
setrecordlength}. The result is {\tt-1} if the stream is not suitable.

\bigskip
\noindent
{\em res \tt:= recordpoint(\em scb\tt, \em recno\tt )}\IMPL{y}{y}{y}
\indent
This call sets the file position pointer of stream {\em scb} to point
to the first byte of the record whose number is {\em recno}.  The
record length must have already been set by a call of {\tt
setrecordlength}. It returns {\tt TRUE} if successful and {\tt FALSE}
otherwise.


\bigskip
\noindent
{\em res \tt:= \tt release(\em taskid\tt )}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function will clear the HOLD bit in the specified task
thus making it potentially runnable. It returns a non zero value if
successful. If the specified task does not exist it returns zero with
101 in {\tt result2}. If the released task has higher priority and is
runnable it gains control leaving the current task suspended in RUN
state. This function is also called {\tt unhold}.


\bigskip
\noindent
{\em flag \tt:= renamefile(\em oldname\tt, \em newname\tt)}\IMPL{y}{y}{y}
\indent
The call renames the file {\em oldname} as file {\em newname},
deleting {\em newname} if necessary, returning {\tt TRUE} if the
renaming was successful, and {\tt FALSE} otherwise.  Both {\em
oldname} and {\em newname} are strings.


\bigskip
\noindent
{\em res \tt:= resumeco(\em cptr\tt, \em arg\tt)}\IMPL{y}{y}{y}
\indent\nopagebreak
The effect of {\tt resumeco} is almost identical to that of {\tt
callco}, differing only in the treatment of the parent.  With {\tt
resumeco} the parent of the calling coroutine becomes the parent of
the called coroutine, leaving the calling coroutine suspended and
without a parent.  Systematic use of {\tt resumeco} reduces the number
of coroutines having parents and hence allows greater freedom in
organising the flow of control between coroutines.
The definition of {\tt resumeco} is in {\tt blib.b} and is as follows.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        LET resumeco(cptr, a) = VALOF
        { LET parent = currco!co_parent
          currco!co_parent := 0
          IF cptr!co_parent DO abort(111)
          cptr!co_parent := parent
          RESULTIS changeco(a, cptr)
        }
\end{verbatim}
\end{samepage}

\smallskip
\noindent
{\tt resumeco} always leaves the global {\tt currco} is set to point
to the resumed coroutine. This is done by the Cintcode instruction
{\tt CHGCO} invoked by {\tt changeco}.


\bigskip
\noindent
{\em res \tt:= rewindstream(\em scb\tt)}\IMPL{y}{y}{y}
\indent\nopagebreak
This function set the position of stream {\tt scb} to its start,
returning {\tt TRUE} if successful, and {\tt FALSE} otherwise.

%GF-S *****************************

\bigskip
\noindent
{\em ch \tt:= sardch()}\IMPL{y}{y}{y}
\indent
This function calls {\tt sys(Sys\_sardch)} to read the next character
from the keyboard as soon as it is available. The character is echoed
to the screen unless the system is running in quiet mode.

\bigskip
\noindent
{\tt sawrch(\em ch\tt)}\IMPL{y}{y}{y}
\indent
This function calls {\tt sys(Sys\_sawrch, \em ch\tt)} to write the
specified character to the screen.

\bigskip
\noindent
{\tt sawritef(\em format\tt,$a$,$b$,$c$,$d$,$e$,$f$,$g$,$h$,$i$,$j$,$k$,%
$l$,$m$,$n$,$o$,$p$,$q$,$r$,$s$,$t$,$u$,$v$,$w$,$x$,$y$,$z$)}\\
\IMPL{y}{y}{y}
\indent
This function is similar to {\tt writef} but performs its output using
{\tt sawrch}.

\bigskip
\noindent
{\tt selectinput(\em scb\tt)}\IMPL{y}{y}{y}
\indent
This call executes {\tt cis := \em scb} to select {\em scb} as the
current input stream.  It aborts (with code 186) if {\em scb} is not
an input stream.


\bigskip
\noindent
{\tt selectoutput(\em scb\tt)}\IMPL{y}{y}{y}
\indent
This routine selects {\em scb} as the currently selected output
stream.  It aborts (with code 187) if {\tt scb} is not an output
stream.

\bigskip
\noindent
{\em res \tt:= \tt setbit(\em bitno\tt, \em bitvec\tt, \em state\tt )}\IMPL{y}{y}{y}
\indent\nopagebreak
This function sets the specified bit in {\em bitvec} to 1 or 0
depending on whether {\em state} is {\tt TRUE} or {\tt FALSE},
respectively. It returns a non-zero value if and only if the previous
setting of the bit was a one.  See {\tt testbit} below.

\bigskip
\noindent
{\em res \tt:= \tt setflags(\em taskid\tt, \em flags\tt )}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function sets the specified flags in the task control
block of the specified task. If successful it returns a non zero value
with {\tt result2} set to the previous setting of the flags field,
otherwise it returns zero with {\tt result2} set to 101 indicating
that {\em taskid} was invalid. For more information about flags see
{\tt testflags} described below.

\bigskip
\noindent
$oldlogname$ {\tt:= setlogname(\em logname\tt, \em logvalue\tt)}\IMPL{y}{y}{y}
\indent
This sets the value of logical variable {\em logname} to the {\em
logvalue}.  By convention {\em logvalue} should be a string. The list
of logical name-value pairs is held in the root node.

\bigskip
\noindent
$prevseed$ {\tt:= setseed(\em newseed\tt)}\IMPL{y}{y}{y}
\indent
The current seed can be set to {\em newseed} by the call {\tt
setseed(}{\em newseed}{\tt)}. This function returns the previous seed
value.


\bigskip
\noindent
{\tt sxpushval(\em sxv\tt, \em val\tt)}\IMPL{y}{y}{y}
\indent
This pushes value {\em val} into the self expanding vector {\em sxv}.
{\em sxv} points to the two word control block of the self expanding
vector. Initially both elements must be zero. When non empty {\em
  sxv\tt!1} will be a vector, {\tt v} say, containing the elements
with {\tt v!0} will be the subscript of the latest element in {\tt
  v}. {\em sxv\tt!0} holds the upper bound of {\tt v}. When the self
expanding vector needs more space, it allocates a new vector {\tt v}
using {\tt newvec} freeing the previous one after copying its elements
into the new one. Clearly pointers to elements of {\tt v} may become
invalid after any call of {\tt sxpushval}. When the self expanding
vector is no longer needed, {\tt freevec(v)} must be called.


\bigskip
\noindent
{\tt srchwk(\em tcb\tt )}%
\IMPL{n}{y}{n}
\indent\nopagebreak
This function is the Cintpos scheduler which is normally only called
from within one of the {\tt klib} library functions or from the
interrupt service routine. Its argument points to the highest priority
task control block that could possibly run. It searches down the
priority chain from this point until it finds the highest priority
runnable task. After setting the globals {\tt tcb} and {\tt taskid}
appropriately, it gives this task control using a call of {\tt
sys(Sys\_rti,...)}.


\bigskip
\noindent
{\em res} {\tt:= stackfree(hwm) }
\IMPL{y}{y}{n}
\indent
If {\tt hwm=TRUE}, this function returns the number of unused stack
words above the high water mark, otherwise it returns the number of
words between the current stack frame pointer and the end of stack. In
either case it sets {\tt result2} to the stack size.

\bigskip
\noindent
{\em code}
{\tt:= start(\em a1\tt, \em a2\tt, \em a3\tt, \em a4\tt)}\IMPL{y}{y}{y}
\indent\nopagebreak
This function is, by convention, the main function of a program.  If
it is called from the command language interpreter (see
section~\ref{CLI}), its first argument is zero and its result should
be the command completion code; however, if it is the main function
of a module run by {\tt callseg}, defined below, then it can take up
to 4 arguments and its result is up to the user.  By convention, a
command completion code of zero indicates successful completion and
larger numbers indicate errors of ever greater severity


\bigskip
\noindent
{\em res \tt:= stepstream(\em scb\tt, \em n)}\IMPL{y}{y}{y}
\indent\nopagebreak
This function advances the position of stream {\em scb} by {\em n}
words, returning {\tt TRUE} if successful, and {\tt FALSE} otherwise.



\bigskip
\noindent
{\label{stop}\tt stop(\em code\tt, \em reason)}\IMPL{y}{y}{y}
\indent\nopagebreak
This function is provided to stop the execution of the current command
running under control of the CLI.  The arguments {\tt code} and {\tt
reason} are placed in the CLI globals {\tt cli\_returncode} and {\tt
cli\_result2} where they can be inspected by commands such as {\tt if}
and {\tt why}.


\bigskip
\noindent
$n$ {\tt:= str2numb(\em str\tt)}\IMPL{y}{y}{y}
\indent
This function converts the string {\em str} into an integer.
Characters other than {\tt0} to {\tt9} and {\tt-} are ignored.  The
result is negative or zero if \verb|str%1='-'|. This function is no
longer recommended, {\tt string\_to\_number} should be used instead.

\bigskip
\noindent
$n$ {\tt:= string\_to\_number(\em str\tt)}\IMPL{y}{y}{y}
\indent
This attempts to set {\tt result2} to the integer represented by the
string {\em str}.  It returns {\tt TRUE} is successful and {\tt FALSE}
otherwise. The following are examples of acceptable strings:
\verb|"'A'"|, \verb|"123"|, \verb|"-99"|, \verb|"+63"|, \verb|"#377"|,
\verb|"-#x7FF"| and \verb|"+#b1011011"|.


\bigskip
\noindent
{\label{sys}\em res \tt:= sys(\em op\tt,...)}\IMPL{y}{y}{y}
\indent
The file {\tt sysc/cintsys.c} contains the main program of the Cintsys
system. It also includes the definition of an important function {\tt
dosys} which provide access to I/O operations and many other operating
system primitives.  The file {\tt sysc/cinterp.c} contains a C
implementation of the Cintcode interpreter. With different compile
time settings this file can generate a faster version by reducing the
number of debugging aids present. Sometimes there is an even faster
version of the interpreter implemented in assembly language, see, for
instance, {\tt sysasm/linux/cintasm.s}.  The BCPL function {\tt sys}
provides an interface between BCPL and {\tt dosys}.

The file {\tt sysc/cintpos.c} contains the main program of the Cintpos
system. It has much is common with {\tt sysc/cintsys.c} including the
function {\tt dosys}.

The {\tt sys} function is defined by hand in {\tt cin/syscin/syslib}
and just invokes the {\tt SYS} Cintcode instruction. When {\tt SYS} is
encountered by the interpreter, it normally just calls {\tt dosys}
passing the BCPL P and G pointers as arguments. But certain {\tt sys}
operations such as {\tt sys(Sys\_quit,code)} are processed directly by the
interpreter.

As might be expected there are many {\tt sys} operations concerned
with interrupts that are only available under Cintpos.

%GF-SYSA *****************************

%GF-SYSB *****************************

\bigskip
\noindent
{\em res \tt:= sys(Sys\_buttons)}\IMPL{y}{y}{y}
\indent
On non standard machines such as the GP2X gaming machine there are
buttons that can be pressed. This call returns a bit pattern
indicating which buttons are currently pressed.


%GF-SYSC *****************************

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, \em fno\tt, \em a1\tt, \em a2 \tt...)}%
\IMPL{y}{y}{y}
\indent
This makes the call {\tt cfuncs(args, g)} where {\tt cfuncs} is a C function
defined in {\tt sysc/cfuncs.c}. The argument {\tt args} points to
memory locations holding {\em fno}, {\em a1}, {\em a2}, etc., and {\tt
g} points to the base of the global vector.

The following table summarises the {\tt callc} operations currently
available (when running under Linux).

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_name2ipaddr, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
The name or dotted decimals of a host is given in {\em a1}
and the result is its IP address or -1 if there is an error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_name2port, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
The name or decimals of a port is given in {\em a1}
and the result is its IP address or -1 if there is an error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_newsocket)}%
\IMPL{y}{y}{y}
\indent
The result is the file descriptor of a new socket or -1 if there
is an error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_reuseaddr, \em a1\tt, \em a2\tt)}%
\IMPL{y}{y}{y}
\indent
The file descriptor of a socket is given in {\em a1}. Id {\em a2\tt=1}
the specified socket may be reused. If there is an error the result is
-1.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_setsndbufsz, \em a1\tt, \em a2\tt)}%
\IMPL{y}{y}{y}
\indent
This sets the send buffer size of socket {\em a1} to {\em a2} bytes.
If there is an error the result is -1.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_setrcvbufsz, \em a1\tt, \em a2\tt)}%
\IMPL{y}{y}{y}
\indent
This sets the receive buffer size of socket {\em a1} to {\em a2} bytes.
If there is an error the result is -1.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_bind, \em a1\tt, \em a2\tt, \em a3\tt)}%
\IMPL{y}{y}{y}
\indent
This bind socket {\em a1} to remote IP address {\em a2} and remote
port {\em a3}.  If there is an error the result is -1.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_tcpconnect, \em a1\tt, \em a2\tt, \em a3\tt)}%
\IMPL{y}{y}{y}
\indent
This make a TCP/IP connection through socket {\em a1} to remote IP
address {\em a2} and remote port {\em a3}.  If there is an error the
result is -1.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_tcplisten, \em a1\tt, \em a2\tt)}%
\IMPL{y}{y}{y}
\indent
This causes socket {\em a1} to wait for a TCP/IP connection to be
requested by a remote host.  The maximum number of connections waiting
to be accepted is given in {\em a2}.  If there is an error the result
is -1.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_tcpaccept, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This accepts a TCP/IP connection through socket {\em a1}.
The result is the socket number to be used for this connection
or -1 if there is an error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_tcpclose, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This closes socket {\em a1}.  The result is -1 if there is an error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_fd\_zero, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This clear every bit in the bit vector {\em a1}.  The result is -1 if
there is an error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_fd\_set, \em a1\tt, \em a2\tt)}%
\IMPL{y}{y}{y}
\indent
This sets bit {\em a1} in the bit vector {\em a2}.  The result is -1
if there is an error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_fd\_isset, \em a1\tt, \em a2\tt)}%
\IMPL{y}{y}{y}
\indent
This inspects bit {\em a1} in the bit vector {\em a2}.  The result is 1
if the bit was set and 0 otherwise.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_callc, c\_fd\_select, 
\em a1\tt, \em a2\tt, \em a3\tt, \em a4\tt, \em a5\tt)}%
\IMPL{y}{y}{y}
\indent
This inspects bit {\em a1} in the bit vector {\em a2}.  The result is 1
if the bit was set and 0 otherwise.

The number of the bits to test is in {\em a1}.  The bit vector
identifying read sockets of interest is in {\em a2}, The bit vector
identifying write sockets of interest is in {\em a3}, The bit vector
identifying other sockets of interest is in {\em a4}.  A pointer to
two words holding the timeout in seconds and microseconds is in {\em
a5}.  The result is the number of sockets that can now be read or
written to, or 0 if the timeout period has elapsed before any sockets
are ready. A result of -1 indicate an error.



\bigskip
\noindent
{\em res \tt:= sys(Sys\_callnative, \em f\tt, \em a1\tt, \em a2\tt, \em a3\tt)}%
\IMPL{y}{y}{y}
\indent
This function is used to enter a subroutine in native machine code.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_close, \em fp\tt)}\IMPL{y}{y}{y}
\indent
This closes the file whose file pointer is {\em fp}. It return 0 if
successful.



\bigskip
\noindent
{\em res \tt:= sys(Sys\_cputime)}\IMPL{y}{y}{y}
\indent
This returns the CPU time in milliseconds since the Cintcode
system was entered.

%GF-SYSD *****************************

\bigskip
\noindent
{\em res \tt:= sys(Sys\_datstamp, \em datv\tt)}\IMPL{y}{y}{y}
\indent
This sets {\em datv\tt!0} to the number of days since 1 January 1970,
and {\em datv\tt!1} to the number of milli-seconds since midnight, and
for compatability with the older version of datstamp {\em
datv\tt!2=-1} indicating the new date and time format is being used.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_delay, \em msecs\tt)}\IMPL{y}{y}{y}
\indent
In both Cintsys and Cintpos this call suspends Cintcode execution
until the time period has elapsed. It is normally better to use
the library functions {\tt delay(msecs)} or {\tt delayuntil(days, msecs)}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_deletefile, \em name\tt)}\IMPL{y}{y}{y}
\indent
This deletes the file whose name is given by {\tt name}.  See
page~\pageref{filenames} for information about the treatment of file
names.



\bigskip
\noindent
{\em res \tt:= sys(Sys\_devcom, \em com\tt, \em arg\tt)}\IMPL{n}{y}{n}
\indent
This is used in Cintpos to send commands from the interpreter thread to
Cintpos device threads.

\bigskip
\noindent
{\em res} {\tt:= sys(Sys\_dumpmem, }{\em context}{\tt)}\IMPL{y}{y}{y}
\indent
This call will dump the whole of Cintcode memory to the file {\tt
DUMP.mem} in a compacted form that is typically inspected by either
the commands {\tt dumpsys} or {\tt dumpdebug}. By convention,
{\tt context = 1} if SIGINT has been received,
{\tt context = 2} if SIGSEGV has been received,
{\tt context = 3} if the dump was caused by BOOT detecting a fault,
{\tt context = 4} if the dump by the user call {\tt sys(Sys\_quit, -2)},
{\tt context = 5} if the dump by a non zero return code from the interpreter,
{\tt context = 6} if the dump by the {\tt D} command in the interactive debugger.


%GF-SYSE *****************************
%GF-SYSF *****************************

\bigskip
\noindent
{\em res \tt:= sys(Sys\_filemodtime, \em name\tt, \em datv)}\IMPL{y}{y}{y}
\indent
This sets the elements of the time stamp vector {\em datv} to
represent the date and time of the last modification of the file given
by {\em name} returning {\tt TRUE} if successful.  The first element
{\em datv\tt!0} holds the number of days since 1 January 1970, {\em
datv\tt!1} is the number of milli-seconds since midnight and {\em
datv\tt!2=-1} indicating that the new date format is being used.  If
the file does not exist the call returns {\tt FALSE} and setting the
three elements of {\em datv} to 0, 0 and -1, respectively.


\bigskip
\noindent
{\em res} {\tt:= sys(Sys\_filesize, }{\em fd}{\tt)}\IMPL{y}{y}{y}
\indent
This call return the size in bytes of the currently opened disk file
whose file descriptor is {\em fd}. The file descriptor is typically
obtained by the expression {\tt scb!scb\_fd}.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, \em op \tt,... )}\IMPL{y}{y}{y}
\label{sysflt}
\indent
This call provides all the floating point operations available to
BCPL.  The required operation is specified by {\em op} normally using
a manifest constant (declared in {\tt libhdr}) such as {\tt fl\_mk},
{\tt fl\_add} or {\tt fl\_sin}. All such operations are described
below.  BCPL floating point numbers must fit in BCPL words and so are
typically only 32 bits long causing their precision and range to be
somewhat limited. On 64-bit implementations of BCPL, floating point
numbers are much more precise.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_avail)}\IMPL{y}{y}{y}
\indent
This call attempts returns {\tt-1} if all the {\tt Sys\_flt}
operations are available. It otherwise return zero.


\bigskip
\noindent
{\label{sysfltmk}\em res \tt:= sys(Sys\_flt, fl\_mk, \em a\tt, \em e\tt)}
\IMPL{y}{y}{y}
\indent
This call attempts to return a floating point approximimation to the number
$a\times 10^e$ where {\em a} and {\em e} are signed integers.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_unmk, \em a\tt)}\IMPL{y}{y}{y}
\indent
This call decomposes the floating point number {\em a} returning the
signed integer mantissa and leaving the decimal exponent in {\tt
result2}. For example, {\tt sys(Sys\_flt, fl\_unmk, 1234.5678)} might
return {\tt 12345678} leaving {\tt-4} in {\tt result2}. However, the
result may vary depending on the BCPL word length and the floating
point representation used.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_float, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_fix, \em a\tt)}\IMPL{y}{y}{y}
\indent
The first call returns a floating point approximation of the integer
{\em a}, and the second attempts to return the closest integer to the
floating point number {\em a}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_abs, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_pos, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_neg, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_mul, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_div, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_add, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_sub, \em a\tt, \em b\tt)}\IMPL{y}{y}{y}
\indent
The first three calls return, respectively, the absolute value of {\em
a}, the value of {\em a} and the negated value of {\em a} where {\em
a} is a floating point number. The last four calls perform floating
point multiplication, division, addition and subtraction on their
arguments.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_eq, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_ne, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_ls, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_gr, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_le, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_ge, \em a\tt, \em b\tt)}\IMPL{y}{y}{y}
\indent
These six calls return {\tt TRUE} if the corresponding floating point
comparisons are satisfied. Otherwise the result is {\tt FALSE}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_acos, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_asin, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_atan, \em a\tt)}\IMPL{y}{y}{y}
\indent
These calls return floating point approximations to the arc cosine,
arc sine and arc tangent of {em a}. The argument {\em a} is in radians
and for {\tt acos} the result is between $0$ and $\pi$. For {\tt asin}
and {\tt atan} it is between $-\pi/2$ and $\pi/2$.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_atan2, \em y\tt, \em x\tt)}\IMPL{y}{y}{y}
\indent
This call return the angle in radians between $x$-axis and the line
from the origin to the point with cartesian coordinates $(x, y)$. The
result lies between $-\pi$ and $\pi$.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_cos, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_sin, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_tan, \em a\tt)}\IMPL{y}{y}{y}
\indent
These calls return the cosine, sine and tangent of {\em a}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_cosh, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_sinh, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_tanh, \em a\tt)}\IMPL{y}{y}{y}
\indent
These calls return the hyperbolic cosine, sine and tangent of {\em a}.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_exp, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_log, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_log10, \em a\tt)}\IMPL{y}{y}{y}
\indent
The first call returns an approximation to $e^a$ where $e$ is the base
of natural logarithms. The second call return the natural logarithm of
$a$, and the third call returns log to the base 10 of $a$.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_frexp, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_ldexp, \em f\tt, \em n\tt)}\IMPL{y}{y}{y}
\indent
The first call splits a floating-point number ($a$) into a fraction
($f$) and exponent ($n$) such that $a$ is approximately equal to
$f\times2^n$. If possible the absolute value of $f$ will be between
0.5(inclusive) and 1.0(exclusive). The call returns $f$ and stores $n$
in {\tt result2} as an integer.  The second call is the inverse of
{\tt frexp} returning an approximation to $f\times2^n$.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_modf, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_mod, \em x\tt, \em y\tt)}\IMPL{y}{y}{y}
\indent
The first call returns the fractional part ($f$) of $a$ storing the
integer part ($i$) as a floating-point number in {\tt result2}. The
sign of both $f$ and $i$ is the same as the sign of $a$ and $a$ will
equal $i+f$.

The second call returns $f$ such that $f$ has the same sign as $x$,
the absolute value of $f$ is less than the absolute value of $y$, and
there exists and integer $k$ such that $k\times y+f$ equals $x$.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_pow, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_sqrt, \em a\tt)}\IMPL{y}{y}{y}
\indent
The first call returns an approximation to $a^b$, and the second call
attempts to return the non negative square root of $a$.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_ceil, \em a\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_floor, \em a\tt)}\IMPL{y}{y}{y}
\indent
The first call returns the smallest floating-point number not less than
$a$ whose value is an exact integer and the second call returns the
largest floating-point number not greater than $a$ whose value is an
exact integer.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_F2N, \em s\tt, \em x\tt)}\IMPL{y}{y}{y}
\indent
This returns the integer part of $s\times x$. This is the scaled fixed
point representation of $x$ when $s$ is the scaled value representing
1.0. For example:

\smallskip
{\small
\begin{verbatim}
        sys(Sys_flt, fl_F2N, 1_000, -1.234) =>    -1234
\end{verbatim}
}

\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_N2F, \em s\tt, \em n\tt)}\IMPL{y}{y}{y}
\indent
This returns the floating point value corresponding to $n/s$. This is
the floating point number representing the fixed point scaled value
$n$ when the scaled number $s$ represents 1.0. For example:

\smallskip
{\small
\begin{verbatim}
        sys(Sys_flt, fl_N2F, 1_000, 1_234) = 1.234
\end{verbatim}
}


\bigskip
\noindent
{\em res \tt:= sys(Sys\_flt, fl\_radius2, \em a\tt, \em b\tt)}\\
{\em res \tt:= sys(Sys\_flt, fl\_radius3, \em a\tt, \em b, \em c\tt)}\IMPL{y}{y}{y}
\indent
The first call returns the square root of $a^2+b^2$ and the second
 returns the square root of $a^2+b^2+c^2$. For example:


\smallskip
{\small
\begin{verbatim}
        sys(Sys_flt, fl_radius2, 3.0, 4.0)      =>    5.000
        sys(Sys_flt, fl_radius3, 1.0, 2.0, 2.0) =>    3.000
\end{verbatim}
}

\bigskip
\noindent
{\tt sys(Sys\_freevec, \em ptr\tt)}\IMPL{y}{y}{y}
\indent
If {\em ptr} is zero it does nothing, otherwise it returns to free
store the space pointed to by {\em ptr} which must have previously
been allocated by {\tt sys(Sys\_getvec,...)}. It checks that the block
is not already free and attempt to check that it has not been
corrupted.

%GF-SYSG *****************************

\bigskip
\noindent
{\em res} {\tt:= sys(Sys\_getpid)}\IMPL{y}{y}{y}
\indent
This function returns the process id of the currently executing
process.

\bigskip
\noindent
{\em str} {\tt:= sys(Sys\_getprefix)}\IMPL{y}{y}{y}
\indent
This returns a pointer to prefix string which is in space allocated
when Cintsys or Cintpos was started. See {\tt
sys(Sys\_setprefix,...)} on page~\pageref{setprefix}.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_getsysval, \em addr\tt)}\IMPL{y}{y}{y}
\indent
This function return the contents of the machine memory location
whose word address is {\em addr} which may be outside the normal
range of the Cintcode memory.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_gettrval, \em count\tt)}\IMPL{y}{y}{n}
\indent
This returns a value from the low level trace buffer. See {\tt
Sys\_trpush} for more details.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_getvec, \em upb\tt)}\IMPL{y}{y}{y}
\indent
This allocates a vector whose lower bound is 0 and whose upper bound
is {\em upb}. It returns zero if the request cannot be satisfied. A
word is allocated just before the start of the vector to hold its
size, and several (typically 4 or 5) words are allocated just past the
end of the vector and filled with redundant data that is checked when
the space is returned to free store.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_globin, \em seg\tt)}\IMPL{y}{y}{n}
\indent
This initializes the global variables defined in the loaded module
pointed to by {\em seg}. It returns zero is there is an error.



\bigskip
\noindent
{\em res \tt:= sys(Sys\_graphics,...)}\IMPL{y}{y}{y}
\indent
This is currently only useful on the Windows CE version of the BCPL
Cintcode system. It performs operations on the graphics window. The
graphics window is a fixed size array of 8-bit pixels which can be
written to and whose visibility can be switched on and off.

%GF-SYSH *****************************
%GF-SYSI *****************************

\bigskip
\noindent
{\em res \tt:= sys(Sys\_inc, \em addr\tt, \em amount\tt)}\IMPL{y}{y}{y}
\indent
This function adds {\em amount} atomically to the specified memory
location and returns it new value.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_incdcount, \em n\tt)}\IMPL{y}{y}{y}
\indent
This function increments the specified counter held in the vector
pointed to by the field {\tt rtn\_dcountv} in the rootnode. This
operation is also available to the interpreter code written in C.

\bigskip
\noindent
{\label{sysinterpret}\em res \tt:= sys(Sys\_interpret, \em regs\tt)}\IMPL{y}{y}{n}
\indent
This function enters the Cintcode interpreter recursively with the
Cintcode registers set to values specified in the vector {\em
  regs}. On return the result is a return code indicating why the
interpreter returned, and the elements of {\em regs} hold the final
state of the Cintcode registers. These registers are described in the
chapter on the design of Cintcode starting on page~\pageref{cintcode}
and the correspondence between the elements of {\em regs} and the
Cintcode registers is given on page~\pageref{syssetcount}.  The return
codes are given on page~\pageref{builtinreturncodes}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_intflag)}\IMPL{y}{y}{y}
\indent
This returns {\tt TRUE} if the user has pressed a particular
combination of keys to interrupt the program that is currently
running.  On many systems this mechanism not implemented and just
returns {\tt FALSE}.


%GF-SYSJ *****************************
%GF-SYSK *****************************
%GF-SYSL *****************************

\bigskip
\noindent
{\label{loadseg}\em res \tt:= sys(Sys\_loadseg, \em name\tt)}\IMPL{y}{y}{n}
\indent
This attempts to load a Cintcode module from file {\em name} looking
first in the current directory. If a valid module is not found there
and {\em name} is a relative file name, it searches through the
directories specified by the environment variable whose name is in the
{\tt rtn\_pathvar} element of the rootnode. This name is normally {\tt
BCPLPATH} under Cintsys and {\tt POSPATH} under Cintpos. See
Section~\ref{envvars} for more information about environment
variables.

If loading is successful, {\tt loadseg} returns the list of loaded
program sections, otherwise it returns zero.  Before the loaded code
can be used, its globals must be initialised using {\tt globin}.

Cintcode modules generated by the BCPL compiler are typically text
files containing the compiled code encoded in hexadecimal. The
compiled form of the {\tt logout} command:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        SECTION "logout"
        GET "libhdr"
        LET start() BE abort(0)
\end{verbatim}
\end{samepage}
\leftline{is}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
000003E8 0000000E 
0000000E 0000FDDF 474F4C0B 2054554F 20202020 
0000DFDF 6174730B 20207472 20202020 7B1C2310 
00000000 00000001 00000024 0000001C 
\end{verbatim}
\end{samepage}

The first two words ({\tt000003E8 0000000E}) indicate the presence of
a ``hunk'' of code of size 14({\tt000000E}) words which then follow.
The first word of the hunk ({\tt000000E}) is again its length. The
next four words ({\tt0000FDDF 474F4C0B 2054554F 20202020}) contain the
{\tt SECTION} name {\tt "logout"}.  These are followed by the four
words {\tt 0000DFDF 6174730B 20207472 20202020} which hold the name of
the function {\tt "start"}.  The body of {\tt start} is compiled
into one word ({\tt7B1C2310}) which correspond to the Cintcode
instructions:

\bigskip
\begin{tabular}{ll}
{\tt L0}      & Load A with 0\\
{\tt K3G 28}  & Call the function in global 28, incrementing the stack by 3\\
{\tt RTN}     & Return from {\tt start} -- never reached\\
\end{tabular}

\bigskip
\noindent
The remaining 4 words contain global initialisation data that is read
backwards during global initialisation invoked by {\tt
sys(Sys\_globin,...)}.  {\tt 0000001C} (=28) is the highest global
variable referenced by this section.  The pair {\tt 00000001 00000024}
specifies that the entry point at position 36 is the initial value of
global~1, and the next entry ({\tt 00000000}) marks the end of the
global initialisation data.

The manifest constants {\tt t\_hunk}, {\tt t\_reloc}, {\tt t\_end},
{\tt t\_hunk64}, {\tt t\_reloc64}, {\tt t\_end64}, {\tt t\_bhunk}, and
{\tt t\_bhunk64} are declared in {\tt libhdr} for the convenience of
programs that generate or read Cintsys and Cintpos object modules.
The example above shows {\tt t\_hunk} loading {\em n} 32-bit words
encoded in hex bytes. Although the BCPL compiler used in both Cintsys
and Cintpos generates position independent code and has no need to
modify the loaded words of a hunk, other languages may need to perform
relocation. This can be done using {\tt t\_reloc} which is followed by
a 32-bit word {\em n} encoded in hex followed by a further {\em n}
words which each give the position of a word in the most recently
loaded hunk that needs to be modified by the addition of the base
address of the hunk. The code {\tt t\_bhunk} is similar to {\tt
t\_hunk} only the data words (not the length field) are provided in
binary rather than hex characters. Such hunks are thus about half the
size of character based ones.  The code {\tt t\_end} marks the end of
an object module, but end-of-file has the same effect. Those codes
containing the characters {\tt 64} provide equivalent facilities for
64-bit versions of BCPL. Neither {\tt t\_reloc} nor {\tt t\_reloc64}
are currently available in Cintsys or Cintpos.

\bigskip
\noindent
{\tt sys(Sys\_lockirq)}\IMPL{y}{y}{y}
\indent
Under cintpos, this call disables interrupts.


%GF-SYSM *****************************

\bigskip
\noindent
{\tt sys(Sys\_memmovebytes, $dest$, $src$. $n$)}\IMPL{y}{y}{y}
\indent
This copies $n$ bytes from BCPL byte address $src$ to BCPL byte
address $dest$.  The source and destination regions may overlap. This
function behaves as if the source region is first copied to a non
overlapping place before copying it to the destination.

\bigskip
\noindent
{\tt sys(Sys\_memmoveword, $dest$, $src$. $n$)}\IMPL{y}{y}{y}
\indent
This copies $n$ words from BCPL word address $src$ to BCPL word
address $dest$.  The source and destination regions may overlap. This
function behaves as if the source region is first copied to a non
overlapping place before copying it to the destination.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_muldiv, $a$, $b$, $c$)}\IMPL{y}{y}{y}
\indent
This invoke the C implementation of {\tt muldiv}. It returns the
result of dividing $c$ into the double length product of $a$ and
$b$. It sets {\tt result2} to the remainder. This function is little
used since a more efficient {\tt muldiv} function is now defined in
{\tt syslib} invoking the Cintcode instruction {\tt MDIV}, see
section~\ref{muldiv}.


%GF-SYSN *****************************
%GF-SYSO *****************************

\bigskip
\noindent
{\em fp \tt:= sys(Sys\_openappend, \em name\tt)}\IMPL{y}{y}{y}
\indent
This function opens an output stream specified by the file name {\em
name} in append mode causing all output to be appended onto the end of
the file. If the file does not exist a zero length file of the given
name is created. If successful it returns the file pointer to the
given file, otherwise it returns zero.


\bigskip
\noindent
{\em fp \tt:= sys(Sys\_openread, \em name\tt, \em envname\tt)}\IMPL{y}{y}{y}
\indent
This opens for reading the file whose name is given by the string {\em
name}.  It returns {\tt0} if the file cannot be opened, otherwise it
returns the file pointer for the opened file. See
page~\pageref{filenames} for information about the treatment of file
names. If {\em name} is a relative filename, the file is first searched
for in the current directory, otherwise, if {\em envname} is non null,
the directories specified by the environment variable {\em envname}
are searched.

\bigskip
\noindent
{\label{openreadwrite}\em res 
\tt:= sys(Sys\_openreadwrite, \em name\tt)}\IMPL{y}{y}{y}
\indent
This opens for reading and writing the file whose name is given by the
string {\em name}.  It returns {\tt0} if the file cannot be opened,
otherwise it returns the file pointer for the opened file. See
Section~\ref{filenames} for information about the treatment of file
names and Section~\ref{randomaccess} for information about random
access files.

\bigskip
\noindent
{\em fp \tt:= sys(Sys\_openwrite, \em name\tt)}\IMPL{y}{y}{y}
\indent
This opens for writing the file whose name is given by the string {\em
name}.  It returns {\tt0} if the file cannot be opened, otherwise it
returns the file pointer for the opened file. See page~\pageref{filenames}
for information about the treatment of file names.





%GF-SYSP *****************************

\bigskip
\noindent
{\em res \tt:= sys(Sys\_platform)}\IMPL{y}{y}{n}
\indent
This returns a machine dependent value indicating under which
architecture Cintsys or Cintpos is running.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_pollsardch)}\IMPL{y}{y}{y}
\indent
This returns the next character from standard input if it is
immediately available, otherwise it returns {\tt pollingch} (=-3). If
the input stream is exhausted it returns {\tt endstreamch}
(=-1). The character is not echoed to the standard output stream.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_putsysval, \em addr\tt, \em val\tt)}\IMPL{y}{y}{n}
\indent

This function sets atomically the contents of the machine memory
location whose word address is {\em addr} to {\tt val} returning its
previous setting. The address may point to system work space outside
the normal Cintcode memory.


%GF-SYSQ *****************************

\bigskip
\noindent
{\label{sysquit}\tt sys(Sys\_quit, \em code\tt)}\IMPL{y}{y}{n}
\indent
This saves the Cintcode registers in the vector of registers given to
the interpreter when it was invoked and returns with the result {\tt
code} to the (C) program that called this invocation of the
interpreter. This is normally used to exit from the Cintcode system,
but can also be used to return from recursive invocations of the
interpreter (see {\tt sys(Sys\_interpret,regs)} above).  A {\em code}
of zero denotes successful completion and, if invoked at the outermost
level, causes the BCPL Cintcode System to terminate.




%GF-SYSR *****************************

\bigskip
\noindent
$n$ {\tt:= sys(Sys\_read, \em fp\tt, \em buf\tt, \em len\tt)}\IMPL{y}{y}{y}
\indent
This reads upto {\em len} bytes from the file specified by the file
pointer {\em fp} into the byte buffer {\em buf}.  The file pointer
{\em fp} must have been created by a call of {\tt
  sys(Sys\_openread,...)} or {\tt sys(Sys\_openreadwrite,...)}.  The
number of bytes actually read is returned as the result.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_renamefile, \em old\tt, \em new\tt)}\IMPL{y}{y}{y}
\indent
This renames file {\em old} to {\em new}. It return 0 if successful.

\bigskip
\noindent
{\bf\tt sys(Sys\_rti, \em regs\tt)}\IMPL{n}{y}{n}
\indent\nopagebreak
Under Cintpos, this returns from an interrupt by setting the Cintcode
registers to the values specified by {\em regs}.


%GF-SYSS *****************************

\bigskip
\noindent
{\em ch \tt:= sys(Sys\_sardch)}\IMPL{y}{y}{y}
\indent
This returns the next character from standard input (normally the
keyboard). Unlessrunning in quietmode the character is echoed to
standard output (normally the screen). If the {\tt-c} or {\tt--}
command options are given when {\tt cintsys} or {\tt cintpos} is
invoked, standard input is prefixed with text from the command
line. For details, see Section~\ref{comlineargs} on
page~\pageref{comlineargs}.



\bigskip
\noindent
{\bf\tt sys(Sys\_saveregs, \em regs\tt)}\IMPL{n}{y}{n}
\indent\nopagebreak
Under Cintpos, this saves the current Cintcode registers in {\em
regs}.

\bigskip
\noindent
{\tt sys(Sys\_sawrch, \em ch\tt)}\IMPL{y}{y}{y}
\indent
This sends character repesented by the least significant 8 bit of {\em
ch} to the standard output (normally the screen).  If {\em ch=10}, the
characters carriage return followed by linefeed are transmitted.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_seek, \em fd\tt, \em pos\tt)}\IMPL{y}{y}{y}
\indent
This will set the file position pointer of the opened file whose
descriptor is {\em fd} to {\em pos}.  The file descriptor is normally
in the {\tt scb\_fd} field of the stream control block for that file.
The value of {\em pos} must be between zero and the current number of
bytes in the file.  See Section~\ref{randomaccess} for more
information about random access files.

\bigskip
\noindent
{\label{syssetcount}\em oldcount \tt:= sys(Sys\_setcount,
 \em newcount\tt)}\IMPL{y}{y}{n}
\indent
One of the Cintcode registers is called {\tt count} which is inspected
just before the interpreter processes the next instruction. If {\tt
count>0} it is decremented and the instruction processed. If {\tt
count=0} the interpreter returns to the calling (C) program with error
code {\tt3}.

The Cintcode System normally has two resident interpreters.  One is
called {\tt cinterp} implemented in C and the other is called {\tt
fasterp} which is sometimes implemented in assembly language. {\tt
fasterp} is faster than {\tt cinterp} since it provides fewer
debugging aids, does not count instruction executions and does not
implement the profiling feature.  Setting {\tt count} to a negative
value causes this faster interpreter to be invoked and setting {\tt
count} to a positive value causes the slower interpreter to be used.
Normally the CLI command {\tt interpreter} is used to make this
switch, see Section~\ref{interpreter}.

With some debugging versions of {\tt fasterp}, setting {\tt count} to
{\tt-2} causes it to execute just one instruction before returning
with error code {\tt 10}. This feature assists the debugging of a new
versions of {\tt fasterp} and is particularly useful when {\tt
fasterp} is implemented in assembly language.

\begin{center}
\begin{tabular}{|l|ll|}\hline
{\em regs}{\tt!0} & A register     &-- work register\\
{\em regs}{\tt!1} & B register     &-- work register\\
{\em regs}{\tt!2} & C register     &-- work register\\
{\em regs}{\tt!3} & P register     &-- the stack frame pointer \\
{\em regs}{\tt!4} & G register     &-- the base of the global vector\\
{\em regs}{\tt!5} & ST register    &-- the status register (unused)\\
{\em regs}{\tt!6} & PC register    &-- the program counter\\
{\em regs}{\tt!7} & Count register &-- see below\\
{\em regs}{\tt!8} & MW register    &-- Used only on 64-bit systems,
                                       see below\\
\hline
\end{tabular}
\end{center}

Both interpreter {\tt cinterp} and {\tt fasterp} returns when a fault
such as division by zero occurs or when a call of
\verb|sys(Sys_quit,...)| is made. Before returning, the interpreter
save the Cintcode registers in {\tt regs}.  The returned result is
either the second argument of \verb|sys(Sys_quit,...)| or one of the
builtin return codes in the following table:
\label{builtinreturncodes}

\bigskip
\begin{center}
\begin{tabular}{|c|p{100mm}|}\hline
   \verb|-1|  &Re-enter the interpreter with a new value in the the count register\\
    0  &Normal successful completion (by convention)\\
    1  &Non existent Cintcode instruction\\
    2  &{\tt BRK} instruction encountered\\
    3  &Count has reached zero\\
    4  &PC set to a negative value\\
    5  &Division by zero\\
   10  &Single step interrupt from the fast interpreter (debugging)\\
   11  &The value of the watched location in the Cincode memory
        has changed in the course of executing the previous 
        instruction \\
   12  &Indirect address out of range\\
   13  &SIGINT received\\
\hline
\end{tabular}
\end{center}

\bigskip
\noindent
{\em res \tt:= sys(Sys\_setprefix, \em prefix\tt)}\IMPL{y}{y}{y}
\label{setprefix}\indent
This is primarily a function for the Windows CE version of the BCPL
Cintcode System for which there is no current working directory
mechanism. The prefix string is held in space that was allocated when
the system started. It sets the prefix that is prepended to all future
relative file names. See Section~\ref{filenames} and the CLI {\tt
prefix} command described on page~\pageref{prefix}.


\bigskip
\noindent
\label{syssetraster}{\em res \tt:= sys(Sys\_setraster, $n$, \em arg\tt)}%
\IMPL{y}{y}{n}
\indent
There is a variant of {\tt cintsys} called {\tt rastsys} that provides
a way to generate data for time-memory images, and {\tt cintpos}
has a similar variant called {\tt rastpos}. These systems can also
generate bit streams that can be converted in sound related to the
execution of programs. The {\tt setraster} operation controls the
rastering feature as follows.  If $n${\tt=3}, it returns {\tt0} if
rastering is available and {\tt-1} otherwise.  If $n${\tt=2}, the
memory granularity is set to {\em arg} bytes per pixel, the default
being 12.  If $n${\tt=1}, the number of Cintcode instructions executed
per raster line is set to {\em arg}, the default being 1000.  If $n$
is zero and {\em arg} is non-zero, rastering is activated sending
its output to the file with name {\em arg} (the rastering data file).
Raster information is normally collected for the duration of the next
CLI command.  If $n$ and {\em arg} are both zero, the rastering data
file is closed. If $n=4$ and {\em arg=1}, the system generated a bit
stream file based on the fifth bit of the address of every access to
the Cintcode memory. This file can later be converted to sound using
the command {\tt rast2wav}. The generated sound is somewhat similar to
that generated by the Edsac 2 computer in Cambridge in the early
1960s.

When not representing bit stream data, the raster file contains text
using run length encoding to represent raster lines. Typical output is
as follows:

\bigskip
\begin{tabular}{ll}
{\tt K1000 S12}     & 1000 instruction per raster line, 12 bytes per pixel\\
{\tt W10B3W1345B1N} & 10 white, 3 black, 1345 white, 1 black, newline\\
{\tt W13B3W12B2N}   & etc\\
{\tt ...}           & \\
\end{tabular}
\bigskip

See the CLI commands {\tt raster} and {\tt rast2ps} on
page~\pageref{raster} for more information on how to use the rastering
facility. See also the command {\tt bits2ps}.


\bigskip
\noindent
{\bf\em res \tt := sys(Sys\_settrcount, \em count\tt)}\IMPL{y}{y}{n}
\indent
This sets the private variable {\tt trcount} used by the low level
tracing mechanism to the specified value returning it previous
setting.  Setting it to a negative value disables the tracing
mechanism. See {\tt Sys\_trpush} for more details.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, \em fno\tt, \em a1\tt, \em a2 \tt...)}%
\IMPL{y}{y}{y}
\indent
This calls {\tt sound(args, g)} where {\tt sound} is a C function
defined in {\tt sysc/sound.c}. The argument {\tt args} points to
memory locations holding {\em fno}, {\em a1}, {\em a2}, etc., and {\tt
g} points to the base of the global vector.  Note that it may be
necessary to run {\tt alsamixer} to enable the sound device and adjust
its volume setting.
The available sound functions have mnemonic names declared in {\tt g/sound.h}
and are described below.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_test)}%
\IMPL{y}{y}{y}
\indent
This returns {\tt TRUE} is the {\tt Sys\_sound} functions are
available on the current system.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_waveInOpen, \em a1\tt, \em a2 \tt,
                                  \em a3 \tt, \em a4 \tt)}%
\IMPL{y}{y}{y}
\indent
This opens a sound wave device for input.  {\em a1} is typically {\tt
"/dev/dsp"}, {\tt"/dev/dsp1"} or a small integer, {\em a2} is the
sample format, eg 16 for S16\_LE, 8 for U8.  {\em a3} is the number of
channels, typically 1 or 2 and {\em a4} is the number of samples per
second, typically 44100.  The result is the file (or device)
descriptor of the opened device or -1 if error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_waveInPause, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This will pause sound wave sampling from device {\em a1}.  Recently
read samples can still be read (to flush the buffered data).

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_waveInRestart, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
Restart sound wave sampling.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_waveInRead, \em a1\tt, \em a2 \tt, \em a3 \tt)}%
\IMPL{y}{y}{y}
\indent
Read samples from a sound wave input device {\em a1}, returning
immediately.  {\em a2} is the buffer in which to receive the samples
and {\em a3} is the number of bytes to read.  The result is the number
of bytes actually transferred into the buffer.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_waveInClose, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This closes sound wave input device {\em a1}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_waveOutOpen, \em a1\tt, \em a2 \tt, \em a3 \tt)}%
\IMPL{y}{y}{y}
\indent
This opens a sound wave device for output.  {\em a1} is typically {\tt
"/dev/dsp"}, {\tt"/dev/dsp1"} or a small integer, {\em a2} is the
sample format, eg 16 for S16\_LE, 8 for U8.  {\em a3} is the number of
channels, typically 1 or 2 and {\em a4} is the number of samples per
second, typically 44100.  The result is the file (or device)
descriptor of the opened device or -1 if error.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_waveOutWrite,
                   \em a1\tt, \em a2 \tt, \em a3 \tt)}%
\IMPL{y}{y}{y}
\indent
Write samples from a sound wave output device {\em a1}.  {\em a2} is
the buffer holding the samples and {\em a3} is the number of bytes to
be written.  The result is the number of bytes actually transferred
from the buffer.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_waveOutClose, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This closes sound wave output device {\em a1}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiInOpen, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This opens MIDI device for input specified by {\em a1} which is
typically {\tt"/dev/midi"}, {\tt"/dev/dmmidi1"} or a small integer.
The result is the file (or device) descriptor of the opened device or
-1 if error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiInRead, \em a1\tt, \em a2 \tt, \em a3 \tt)}%
\IMPL{y}{y}{y}
\indent
This reads bytes from MIDI input device {\em a1} into buffer {\em a2}.
{\em a3} is the number of MIDI bytes to read. The result is the actual
number of bytes transferred or -1 if there was an error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiInClose, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This close MIDI input device {\em a1}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiOutOpen, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This opens a MIDI device for output. {\em a1} is typically
{\tt"/dev/midi"}, {\tt"/dev/dmmidi1"} or a small integer. The result
is the file (or device) descriptor of the opened device or -1 if
error.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiOutWrite1, \em a1\tt, \em a2)}%
\IMPL{y}{y}{y}
\indent
This writes a one byte MIDI message ({\em a2}) to MIDI device {\em a1}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiOutWrite2,
                   \em a1\tt, \em a2 \tt, \em a3 \tt)}%
\IMPL{y}{y}{y}
\indent
This writes a two byte MIDI message ({\em a2 a3}) to MIDI device {\em a1}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiOutWrite3,
                   \em a1\tt, \em a2 \tt, \em a3 \tt, \em a4 \tt)}%
\IMPL{y}{y}{y}
\indent
This writes a three byte MIDI message ({\em a2 a3 a3}) to MIDI device {\em a1}.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiOutWrite, \em a1\tt, \em a2 \tt...)}%
\IMPL{y}{y}{y}
\indent
This write {\em a3} MIDI bytes from buffer {\em a2} to MIDI output device {\em a1}.
The result is the number of bytes actually sent.

\bigskip
\noindent
{\em res \tt:= sys(Sys\_sound, snd\_midiOutClose, \em a1\tt)}%
\IMPL{y}{y}{y}
\indent
This closes MIDI output device {\em a1}.


\begin{samepage}
\bigskip
\noindent
{\bf\tt sys(Sys\_setst, \em val\tt)}\IMPL{n}{y}{n}
\indent
Under Cintpos, this sets the Cintcode ST register to {\em
val}. Interrupts are enabled only when ST is zero. By convention, ST=1
while execution is within {\tt klib}, ST=2 when executing within the
interrupt routine, and ST=3 during the initial bootstrapping process.
\end{samepage}


\bigskip
\noindent
{\em res \tt:= sys(Sys\_shellcom, \em comstr\tt)}\IMPL{y}{y}{y}
\indent
This causes the command {\em comstr} to be executed by the command
language shell of the operating system under which Cintsys or Cintpos
is running.

%GF-SYST *****************************

\bigskip
\noindent
{\bf\tt sys(Sys\_tally, \em val\tt)}\IMPL{y}{y}{n}
\indent
This call provides a profiling facility that uses a globally
accessible tally vector to hold frequency counts of Cintcode
instructions executed.  When {\em val} is {\tt TRUE} the tally vector
is cleared and tallying is enabled.  When {\em val} is {\tt FALSE}
tallying is disabled.  When tallying is active, the $i^{th}$ element
of the tally vector is incremented every time the instruction at
location $i$ of the Cintcode memory is executed.  The size of the
tally vector can be specified by the {\tt-t} command line argument
(see Section~\ref{comlineargs}) when the interpreter is entered. The
default size being typically 80000 words.  The tally vector is held in
{\tt rootnode!rtn\_tallyv} with the upper bound stored in its zeroth
element. It can thus be inspected by any program.

Statistics of program execution is normally gathered and analysed
using the CLI command {\tt stats} (see Section~\ref{stats}).

\bigskip
\noindent
{\em pos \tt:= sys(Sys\_tell, \em fd}{\tt)}\IMPL{y}{y}{y}
\indent
This returns the current file position pointer of the opened file
whose descriptor is {\em fd}. The file descriptor is normally in the
{\tt scb\_fd} field of the stream control block for that file.  See
Section~\ref{randomaccess} for more information about random access
files.

\bigskip
\noindent
{\bf\tt sys(Sys\_tracing, \em val\tt)}\IMPL{y}{y}{n}
\indent
This sets the Cintcode tracing mode to {\em val}. When the tracing
mode is {\tt TRUE}, the Cintcode interpreter outputs a one line trace
of every Cintcode instruction executed.

\bigskip
\noindent
{\bf\tt sys(Sys\_trpush, \em val\tt)}\IMPL{y}{y}{n}
\indent
There is a low level circular trace buffer that can hold 4096 values,
and a private variable {\tt trcount} that holds the number of values
currently pushed into this buffer. If {\tt trcount<0}, low level
tracing is disabled, but otherwise {\tt trpush} pushes {\tt val} into
the buffer at position {\tt trcount MOD 4096} and increments {\tt
trcount}.  The call {\tt sys(Sys\_settrcount, \em count\tt)} sets {\tt
trcount} to the specified value (possibly disabling tracing) and
returns its previous setting.  The call {\tt sys(Sys\_gettrval, \em
count\tt)} gets the value in the trace buffer at position {\tt trcount
MOD 4096}. Normally this function is only called when tracing is
disabled. Under both Cintsys and Cintpos, {\tt trpush} can also be
called from the parts of the system implemented in C.

This tracing mechanism is available both to the BCPL user and parts of
the system such as {\tt cintpos.c}, {\tt cinterp.c} and {\tt
devices.c}.  Under Cintpos these low level tracing functions use a
mutex to control access to {\tt trcount} and the circular buffer. It
is thus thread safe and so can be used to help debug subtle timing
problems in the system software.  For an example of the use of this
tracing mechanism see the command {\tt com/testtr.b}.



%GF-SYSU *****************************

\bigskip
\noindent
{\em res \tt:= sys(Sys\_unloadseg, \em seg\tt)}\IMPL{y}{y}{y}
\indent
This unloads the the loaded module given by {\em seg}. If {\em
seg} is zero it does nothing. Unloading a module just returns the
space it occupied to freestore.


\bigskip
\noindent
{\tt sys(Sys\_unlockirq)}\IMPL{n}{y}{n}
\indent
Under cintpos, this call enables interrupts.


\bigskip
\noindent
{\em res \tt:= sys(Sys\_usleep, \em usecs\tt)}\IMPL{y}{y}{y}
\indent
Under cintsys, this call causes the system to sleep for {\tt usecs}
micro-seconds. Under cintpos, it causes the current task to sleep for
{\tt usecs} micro-seconds.

%GF-SYSV *****************************
%GF-SYSW *****************************

\bigskip
\noindent
{\tt sys(Sys\_waitirq, \em msecs\tt)}\IMPL{n}{y}{n}
\indent
This call is typically only made from the body of the Cintpos Idle
task.  It suspends the interpreter until either some Cintpos device
issues an interrupt request or the specified timeout occurs. It is
typically implemented by waiting with a timeout on a host operating
system condition variable. When a device thread wishes to interrupt
the interpreter it send a signal via the appropriate condition
variable. Unfortunately some operating systems may take hundreds of
milliseconds to reschedule the interpreter thread. A possible but
selfish solution is for the Idle task to execute a busy loop instead
of calling {\tt waitirq}.

\bigskip
\noindent
{\bf\tt sys(Sys\_watch, \em addr\tt)}\IMPL{y}{y}{n}
\indent
This sets the address of a location of Cintcode memory to be inspected
every time the interpreter executes and instruction.  When the watched
value changes it returns with result 12.  The watch feature is
disabled if {\em addr} is zero or if {\tt fasterp} is being used.

\bigskip
\noindent
$n$ {\tt:= sys(Sys\_write, \em fp\tt, \em buf\tt, \em len\tt)}\IMPL{y}{y}{y} 
\indent
This writes {\em len} bytes to the file specified by the file pointer
{\em fp} from the byte buffer {\em buf}.  The file pointer must have
been created by a call of {\tt sys(Sys\_openwrite,...)} or {\tt
  sys(Sys\_openreadwrite,...)}.  The result is the number of bytes
transferred, or zero if there was an error.

%GF-SYSX *****************************
%GF-SYSY *****************************
%GF-SYSZ *****************************

%GF-T *****************************

\bigskip
\noindent
{\em pkt \tt:= \tt taskwait()}\IMPL{n}{y}{n}
\indent\nopagebreak
If there is a packet in the task's queue it is dequeued and returned
as the result.  If there was no packet on the work queue this task is
suspended in WAIT state and control given to a lower priority task.

\bigskip
\noindent
{\em res \tt:= \tt testbit(\em bitno\tt, \em bitvec\tt)}\IMPL{y}{y}{y}
\indent\nopagebreak
This function returns a non zero value if and only if the specified
bit in {\em bitvec} is a one.  The bits are numbered from zero
starting at the least significant bit of {\tt bitvec!0}.  {\tt
  bitvec!0} holds bits 0 to {\tt bitsperword-1}, {\tt bitvec!1} holds
bits {\tt bitsperword} to {\tt 2*bitsperword-1}, etc.

\bigskip
\noindent
{\em res \tt:= \tt testflags(\em flags\tt)}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos function tests and clears specified flags in the task
control block of the current task. Flags are bits in the {\tt
tcb\_flags} field of the task control block, and they are normally
called {\tt A}, {\tt B}, etc corresponding to consecutive bits from
the least significant end of the field.  A flag is set if the
corresponding bit is a one. The argument {\em flags} is a bit pattern
identifying which flags are being inspected.  The result is {\tt
FALSE} if none of the specified flags were set, and {\tt TRUE} if at
least one was, in which case {\tt result2} is set to a bit pattern
representing the flags that were set and have now been cleared.

%GF-U *****************************

\bigskip
\noindent
{\tt unloadseg(\em segl\tt)}\IMPL{y}{y}{y}
\indent\nopagebreak
This routine unloads the list of loaded program modules given by {\em
segl}.

\bigskip
\noindent
{\em res \tt:= unrdch()}\IMPL{y}{y}{y}
\indent
This attempts to step the current input stream back by one character
position.  It returns {\tt TRUE} if successful, and {\tt FALSE}
otherwise.  A call of {\tt unrdch} will always succeeds the first time
after a call of {\tt rdch}.  It is useful in functions such as {\tt
readn} where single character lookahead is necessary.
See Section~\ref{streams} for more detailed information.


%GF-V *****************************
%GF-W *****************************

\bigskip
\noindent
{\tt wrch(\em ch\tt)}\IMPL{y}{y}{y}
\indent
This routine writes the character {\em ch} to the currently selected
output stream.  If output is to the screen, {\em ch} is transmitted
immediately. It aborts (with code 189) if there is a write failure.


\bigskip
\noindent
{\tt writed($n$, $d$)}\IMPL{y}{y}{y}
{\tt writeu($n$, $d$)}\IMPL{y}{y}{y}
{\tt writen($n$)}\IMPL{y}{y}{y}
\indent
These routines output the integer $n$ in decimal to the currently
selected output stream.  For {\tt writed} and {\tt writeu}, the output
is padded with leading spaces to fill a field width of $d$
characters.  If {\tt writen} is used or if $d$ is too small, the
number is written without padding.  If {\tt writeu} is used, $n$
is regarded as an unsigned integer.


\bigskip
\noindent
{\tt writehex($n$, $d$)}\IMPL{y}{y}{y}
{\tt writeoct($n$, $d$)}\IMPL{y}{y}{y}
{\tt writebin($n$, $d$)}\IMPL{y}{y}{y}
\indent
These routines output, repectively, the least significant $d$
hexadecimal, octal or binary digits of the integer $n$ to the
currently selected output stream.

\bigskip
\noindent
{\tt writes(\em str\tt)}\IMPL{y}{y}{y}
{\tt writet(\em str\tt, \em d\tt)}\IMPL{y}{y}{y}
\indent
These routines output the string {\em str} to the currently selected output
stream.  If {\tt writet} is used, trailing spaces are added to fill a field
width of {\tt d} characters.

\bigskip
\noindent
{\tt writef(\em format\tt,$a$,$b$,$c$,$d$,$e$,$f$,$g$,$h$,$i$,$j$,$k$,%
$l$,$m$,$n$,$o$,$p$,$q$,$r$,$s$,$t$,$u$,$v$,$w$,$x$,$y$,$z$)}\\
\IMPL{y}{y}{y}
\indent
The first argument ({\em format}) is a string that is copied character
by character to the currently selected output stream until a
substitution item such as \verb|%s| or \verb|%i5| is encountered when
a value (usually the next argument) is output in the specified format.
The substitution items are given in table~\ref{writefformats}.

\begin{figure}[!tbp]
\begin{center}
\begin{tabular}{|l|p{120mm}|}
\hline
Item         &Substitution \rule[-3mm]{0mm}{8mm}\\ \hline

{\tt\%s}     &Write the next argument as a string using {\tt writes}.\\

{\tt\%$n$t  \%t$n$}  &Write the next argument as a left justified string in a
field width of $n$ characters using {\tt writet}.\\

{\tt\%c}     &Write the next argument as a character using {\tt wrch}.\\

{\tt\%\#}    & Write the next argument as a in UTF-8 or GB2312
             character using {\tt codewrch}.\\

{\tt\%$n$b \%b$n$}  & Write the next argument as a binary number in a field
width of $n$ characters using {\tt writebin}.\\

{\tt\%$n$o \%o$n$}  & Write the next argument as an octal number in a field
width of $n$ characters using {\tt writeoct}.\\

{\tt\%$n$x \%x$n$}  & Write the next argument as a hexadecimal number in a
field width of n characters using {\tt writehex}.\\

{\tt\%$n$i \%i$n$}  & Write the next argument as a decimal number in a field
width of $n$ characters using {\tt writed}.\\

{\tt\%n}     & Write the next argument as a decimal number in its
natural field width using {\tt writen}.\\

{\tt\%$n$u \%u$n$}  & Write the next argument as an unsigned decimal
number in a field width of $n$ characters using {\tt writeu}.\\

{\tt\%$n$.$m$d} & Write the next argument as a scaled decimal number in
                  a field with of $n$ with $m$ digits after the decimal point.\\

{\tt\%+}     &Skip over the next argument.\\
{\tt\%-}     &Step back to the previous argument.\\

{\tt\%\%}    &Write the character {\tt\%}.\\

{\tt\%p{\em c}} & Plural formation. Write character {\em c} if the next
                  argument is not 1.\\

{\tt\%p\verb|\|{\em a}\verb|\|{\em b}\verb|\|} & Plural formation.
                  Write text {\em a} if the next
                  argument is 1, otherwise write text {\tt b}.\\

{\tt\%f}     &Take the next argument as a {\tt writef} format string
              and call {\tt writef} recursively to process it passing
              it the remaining arguments. The argument pointer is
              advanced by the appropriate amount.\\

{\tt\%$n$.$m$f} & Write the next argument as a floating point number in
                  a field with of $n$ with $m$ digits after the decimal point.
                  The output is generated using {\tt writeflt}.\\

{\tt\%$n$.$m$e} & Write the next argument as a floating point number in exponential
                  form in a field with of $n$ with $m$ digits after the
                  decimal point. The output is generated using {\tt writee}.\\

{\tt\%m}     & The next argument is taken as a message number and processes
               as for {\tt\%f} above using the message format string obtained
               by the call {\tt get\_text(messno, str, upb)} where {\tt str} is a
               vector local to {\tt writef} to hold the message string. This provides
               an easy way to generate messages in different languages. 
               {\tt get\_text} is a global function typically defined by the user.
               The default version always yields the message string
               {\tt"<mess:\%-\%n>"}.\\
\hline
\end{tabular}

\end{center}
\caption{\label{writefformats}{\tt writef} substitution items}
\end{figure}

When a field width (denoted by $n$ in the table) is required, it is
specified by a single character, with 0 to 9 being represented by the
corresponding digit and 10 to 35 represented by the letters {\tt A} to
{\tt Z}.  Format characters are case insensitive but field width
characters are not. A recent entension allows the field width to be
specified as a decimal integer immediately following the percent, as
in \verb|%12i| meaning \verb|%iB|.

Some examples of the 
\verb|%|$n${\tt.}$m${\tt d} substitution item are given below.
\medskip

\begin{tabular}{lcr}
\verb|writef("%9.2d", 1234567)| &writes& {\tt 12345.67}\\
\verb|writef("%9.2d", -1234567)| &writes& {\tt -12345.67}\\
\verb|writef("%9.0d", 1234567)| &writes& {\tt 1234567}\\
\verb|writef("%9d", 1234567)| &writes& {\tt 1234567}\\
\end{tabular}
\medskip

As an example of how the {\tt\%p} substitution item
can be used, the following code:

\begin{center}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
FOR count = 0 TO 2 DO
  writef("There %p\ is\are\ %-%n thing%-%ps.*n", count)
\end{verbatim}
\end{samepage}
\end{center}

\noindent
outputs:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
There are 0 things.
There is  1 thing.
There are 2 things.
\end{verbatim}
\end{samepage}

The implementation of {\tt writef} (in {\tt sysb/blib.b}) is a good
example of how a variadic function can be defined.

\bigskip
\noindent
{\tt writeflt(\em x\tt, \em w\tt, \em p\tt)}\IMPL{y}{y}{y}
\indent
This routine outputs the floating point number {\em x} to the currently
selected output stream in a field of width $w$ with $p$ digits after
the decimal point.

\bigskip
\noindent
{\tt writee(\em x\tt, \em w\tt, \em p\tt)}\IMPL{y}{y}{y}
\indent
This routine outputs the floating point number {\em x} to the currently
selected output stream in exponential form in a field of width $w$ with
$p$ digits after the decimal point.



%GF-X *****************************
%GF-Y *****************************
%GF-Z *****************************

\subsection{\label{streams}Streams}

BCPL uses streams as a convenient method of obtaining device
independent input and output.  All the information needed to process a
stream is held in a vector called a stream control block (SCB) whose
fields have already been summarized in Section~\ref{scbfields}.

The element {\tt buf} is either zero or holds the stream's byte buffer
which must have been allocated using {\tt getvec} and must be freed
using {\tt freevec} when the stream is closed.  The elements {\tt pos}
and {\tt end} hold positions within the byte buffer, {\tt file} holds
a file pointer for file streams or {\tt-1} for streams connected to
the console.  The element {\tt id} indicates whether the stream is for
input, output or both and {\tt work} is private work space for the
action function {\tt rdfn}, {\tt wrfn} which are called, repectively,
when the byte buffer becomes empty on reading or full on output.  The
function {\tt endfn} is called to close the stream.

Input is read from the currently selected input stream whose SCB is
held in the global variable {\tt cis}.  For an input stream, {\tt pos}
holds the position of the next character to be read, and {\tt end}
points to just past the last available character in the buffer.
Characters are read using {\tt rdch} whose definition is given in
figure~\ref{f3rdch}.  If a character is available in the buffer it is
returned after incrementing {\tt pos}. Exceptionally, the character
carriage return (CR) is ignored since on some systems, such as
Windows, lines are terminated with carriage return and linefeed while
on others, such as Linux, only linefeed is used. If the buffer is
exhausted, {\tt replenish} is called to refill it, returning {\tt
TRUE} if one or more character are transferred. If replenish fails it
returns {\tt FALSE} with the reason why in {\tt result2}. Possible
reasons are: -1 indicating end of file, -2 indicating a timeout has
occurred and -3 meaning input is in polling mode and no character is
currently available. By setting the {\tt timeoutact} field of the SCB
to -1, a timeout is treated as end of file.

\begin{figure}[tbh]
\begin{center}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND rdch() = VALOF
{ LET pos = cis!scb_pos // Position of next byte, if any
  UNLESS cis DO abort(186)
  IF pos<cis!scb_end DO { LET ch = cis!scb_buf%pos
                          cis!scb_pos := pos+1
                          IF ch='*c' LOOP // Ignore CR
                          RESULTIS ch
                        }

  // If replenish returns FALSE, it failed to read any characters
  // and the reason why is placed in result2 as follows
  //    result2 = -1    end of file
  //    result2 = -2    timeout
  //    result2 = -3    polling mode with no characters available.
  //    result2 = code  error code
  UNTIL replenish(cis) DO
  { IF result2=-2 DO
    { LET act = cis!scb_timeoutact    // Look at the timeout action
      IF act=-2 RESULTIS timeoutch    // Timed out
      IF act=-1 RESULTIS endstreamch  // End of file reached
      LOOP  // Try replenishing again
    }
    RESULTIS result2<0 -> result2, endstreamch
  }
} REPEAT
\end{verbatim}
\end{samepage}
\end{center}
\caption{\label{f3rdch}The definition of {\tt rdch}}
\end{figure}

Whenever possible, the buffer contains the previously read character.
This is to allow for a clean and simple implementation of {\tt unrdch}
whose purpose is to step input back by one character position.  Its
definition is given in figure~\ref{f3unrdch}.

\begin{figure}[tbh]
\begin{center}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET unrdch() = VALOF
{ LET pos = cis!scb_pos
  IF pos<=scb_bufstart RESULTIS FALSE // Cannot UNRDCH past origin.
  cis!scb_pos := pos-1
  RESULTIS TRUE
}
\end{verbatim}
\end{samepage}
\end{center}
\caption{\label{f3unrdch}The definition of {\tt unrdch}}
\end{figure}

Output is sent to the currently selected output stream whose SCB is
held in the global variable {\tt cos}. The SCB field {\tt pos} of an
output stream holds the position in the buffer of the next character
to be written, and {\tt end} holds the position just past the end of
the buffer.  Characters are written using the function {\tt wrch}
whose definition is given in figure~\ref{wrch}.  The character {\tt
ch} is copied into the byte buffer and {\tt pos} incremented.  If the
buffer is full, it is emptied by calling the element {\tt wrfn}.
If writing fails it return {\tt FALSE}, causing {\tt wrch} to abort.

\begin{figure}[tbh]
\begin{center}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND wrch(ch) = VALOF
{ LET pos = cos!scb_pos

  IF pos >= cos!scb_bufend DO
  { // The buffer is full
    UNLESS deplete(cos) RESULTIS FALSE
    UNLESS cos!scb_buf  RESULTIS TRUE // Must be writing to NIL:
    pos := cos!scb_pos
  }

  // Pack the character and advance pos.
  cos!scb_buf%pos := ch
  pos := pos+1
  cos!scb_pos := pos
  // Advance end of valid data pointer, if necessary
  IF cos!scb_end < pos DO cos!scb_end := pos
  cos!scb_write := TRUE // Set flag to indicate the buffer has changed.

  UNLESS ch<'*s' & cos!scb_type<0 RESULTIS TRUE // Normal return

  // The stream is interactive and ch is a control character.

  IF ch='*n' DO  wrch('*c')  // Fiddle for Cygwin

  // Call deplete at the end of each interactive line.
  IF ch='*n' | ch='*p' RESULTIS deplete(cos)
  RESULTIS TRUE
}
\end{verbatim}
\end{samepage}
\end{center}
\caption{\label{wrch}The definition of {\tt wrch}}
\end{figure}


\subsection{\label{filenames}The Filing System}

BCPL uses the filing system of the host operating system and so some
details such as the maximum length of file names are machine
dependent.  Previously, BCPL used to follow the syntax of target
machine files names, but recently BCPL attempts to be more machine
independent by mainly adopting the Linux style of names and converting
them to target machine form at runtime. The target machine format is
set by a configuration parameter set when the system was installed.
The formats currently available are for Unix, Windows and VMS.

Within BCPL file names slashs (\verb|/|) and back slashes (\verb|\|)
are regarded as separators between the components of file names. File
names may start with a colon prefix consisting of letters and digits
followed by a colon, as in {\tt TCP:shep.cl.cam.ac.uk:9000} or {\tt
G:test.b}. Such prefixes allow access to special features such as URLs
used in TCP/IP communication or to other filing systems.  These are
often dependent on the host operating system.

A file name starting \verb|'/'| or \verb|'\'| or containing a colon
is treated as an absolute name; all others are relative names and are
interpreted relative to the current directory. A file name consisting
of a single asterisk ({\tt*}) is special and represents standard input
(normally the keyboard) or standard output (normally the screen)
depending on context. Within a file name, the components dot ({\tt.})
and double dot ({\tt..}) represent the current and parent directories,
respectively. As an example, the file name
{\tt../bcplprogs/demos/queens.b} is valid and automatically converted
when used to \verb|..\bcplprogs\demos\queens.b| under Windows or to
\verb|[-.bcplprogs.demos]queens.b| under VMS.

Some operating systems such as Windows CE2.0 have no concept of a
current working directory. For such systems there is a feature that
allows users to specify a character string to be automatically
prepended to any relative (non absolute) file name before it is used.
The prefix string is stored in static Cintcode space allocated when
Cintsys or Cintpos starts up.  It can be inspected and changed using
the calls: {\tt sys(Sys\_getprefix)} and {\tt sys(Sys\_setprefix, \em
prefix}{\tt)}, or the CLI command {\tt prefix} described on
page~\pageref{prefix}. The prefix string is only used with relative
file names not already prefixed with directories given by path
variables such as {\tt BCPLPATH} or {\tt POSPATH}.


\section{\label{randomaccess}Random Access}

Disk files can be regarded as potentially huge vectors of bytes with
the first byte being at position zero of the file. An opened stream to
or from a file has a file position pointer that holds the position
relative to the start of where the next byte will be transferred. For
any such stream this position can be read using {\tt note(scb, posv)}
or updated using {\tt point(scb, posv)}. For read-write streams it is
possible to read or write data at any position in the file.

Disk files can also be regarded as potentially huge collections of
fixed length records. The user must specify the record size by calling
{\tt setrecordlength}. The records of a file are given consecutive
numbers starting with zero, and can be read or written using {\tt
  get\_record} and {\tt put\_record}. The record number of the next
record to be transferred can be obtained by calling {\tt recordnote}
and can be set using {\tt recordpoint}.

\section{\label{ramstreams}RAM streams}

A special form of random access stream is a RAM stream which can be
created by the call {\tt findinoutput("RAM:")}. RAM streams hold all
the data in main memory in the stream buffer. As data is written to a
RAM stream, its buffer is automatically enlarged as needed. The data
can be read back by calling {\tt rewindstream} followed by calls of
{\tt rdch}. Alternatively it can be accessed from the buffer held in
{\tt scb!scb\_buf}. The number of valid bytes in the buffer is {\tt
  scb!scb\_end}. When a RAM stream is closed its buffer and scb are
returned to free store.


\section{\label{envvars}Environment Variables}

Most operating systems allow the user to set environment variables
whose names consist of letters and digits and whose values are
arbitrary character strings. Both Cintsys and Cintpos use such
variables to specify directories to be searched when looking up files
in certain contexts. These directories are separated by semicolons or
colons, but when running under Windows only semicolons are allowed.

In the standard Cintsys system the environment variable {\tt BCPLROOT}
holds the file name of the root directory of the system. {\tt
BCPLPATH} holds a list of directories that are searched when
attempting to load the Cintcode compiled form of a BCPL program.  {\tt
BCPLHDRS} holds the directories to be searched when the BCPL compiler
is processing a {\tt GET} directive and {\tt BCPLSCRIPTS} specified
the directories to be searched when the {\tt c} command is looking for
a command-command script.

In the standard Cintpos system these variables are called {\tt
POSROOT}, {\tt POSPATH}, {\tt POSHDRS} and {\tt POSSCRIPTS}. It is
sometimes convenient to use other names, for instance, {\tt
NBCPLROOT}, {\tt NBCPLPATH}, {\tt NBCPLHDRS} and {\tt NBCPLSCRIPTS}
might be used when developing a new version of Cintsys. To make this
possible the system allocates static space to hold the names and
provides the command {\tt setroot} described on page~\pageref{setroot}
to allow the user to change them. These names may be up to 63
characters long are accessible to commands such as {\tt bcpl}, {\tt c}
and {\tt setroot} via the rootnode fields {\tt rtn\_rootvar}, {\tt
rtn\_pathvar}, {\tt rtn\_hdrsvar} and {\tt rtn\_scriptsvar}.

When Cintsys (or Cintpos) starts up it requires a valid setting of
{\tt rtn\_pathvar} in order to locate Cintcode modules such as {\tt
BOOT} and {\tt BLIB}. The default setting of this field is {\tt
BCPLPATH} (or {\tt POSPATH}) but can be changed using the {\tt-cin}
argument at startup as in

\bigskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
cintsys -cin NBCPLPATH
\end{verbatim}
}

\bigskip
\noindent
After loading the resident system control is passed to {\tt BOOT}
which updates the variable names appropriately for the system being
run. It is unlikely that the user will want change them using {\tt
setroot} although it might be useful to use {\tt setroot} to see what
names are currently being used.

If the value of an environment variable represents a list of
directories, they should be given using Linux style slash ({\tt/})
separators and the directories separated by semicolons (rather than
the Linux style colons). This allows colon prefixes such as {\tt G:}
to be used in, for instance, Windows version of the system. For
compatibility with older systems, colons may be used as an alternative
to semicolons when not running under Windows.

When Cintpos starts up the process is similar except the setting
of {\tt rtn\_pathvar} is {\tt POSPATH} unless explicitly changed using
{\tt-cin}.

When installing {\tt cintsys} or {\tt cintpos} for the first time it
is common to fail to set the environment variables correctly. To help
repair such mistakes, use the {\tt-f} option when calling {\tt
cintsys} or {\tt cintpos}. This will output a trace of every time any
file is looked up using an environment variable. Even more information
is generated if the {\tt-v} argument is also given (or even
{\tt-vv}). Until the system is working correctly it is recommended that
it is started using

\bigskip
\noindent
{\tt cintsys -f}

\bigskip
\noindent
or

\bigskip
\noindent
{\tt cintpos -f -v}


\section{Coroutine examples}

This section contains examples that use the coroutine mechanism.

\subsection{A square wave generator}

The following function is the main function of a coroutine that
generates square wave samples.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim}
LET squarefn(args) = VALOF
{ LET freq, amplitude, rate = args!0, args!1, args!2
  LET x = 0
  cowait(@freq) // Return a pointer -> [freq, amplitude, rate]

  { // freq is a scaled fixed point value with
    // three digits after the decimal point.
    LET currfreq = freq            // These only change at the
    LET curramplitude = amplitude  // start of a complete cycle.
    LET q4 = rate*1000
    LET q2 = q4/2
    UNTIL x > q2 DO { cowait(+curramplitude) // First half cycle
                      x := x + currfreq
                    }
    UNTIL x > q4 DO { cowait(-curramplitude) // Second half cycle
                      x := x + currfreq
                    }
    x := x - q4
  } REPEAT
}
\end{verbatim}
\end{samepage}

\noindent
The following call creates a coroutine that initially generates a
square wave with frequency 440Hz and amplitude 5000 at a rate of 44100
samples per second.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim}
sqco    := initco(squarefn, 300, 440_000, 5_000, 44_100)
sqparmv := result2    // sqparmv -> [freq, amplitude, rate]
\end{verbatim}
\end{samepage}

\noindent
One second's worth of samples can now be obtained by:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim}
FOR i = 1 TO 44100 DO
{ LET sample = callco(sqco)
  ...
}
\end{verbatim}
\end{samepage}

\noindent
The frequency and amplitude can be changed by assignments
such as:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim}
sqparmv!0 := newfrequency
sqparmv!1 := newamplitude
\end{verbatim}
\end{samepage}

\noindent
Note that the new frequency and amplitude take effect at the start of
the next complete cycle.

Other examples of the use of {\tt initco} can be found below.

\subsection{Hamming's Problem}

A following problem permits a neat solution involving coroutines.

\begin{center}
\parbox{100mm}
{\small
Generate the sequence {\tt 1,2,3,4,5,6,8,9,10,12,\ldots} of
all numbers divisible by no primes other than 2, 3, or 5".  
}
\end{center}

\noindent
This problem is attributed to R.W.Hamming. The solution given here
shows how data can flow round a network of coroutines.  It is
illustrated in figure~\ref{f3hamming} in which each box represents a
coroutine and the edges represent {\tt callco/cowait} connections.
The end of a connection corresponding to {\tt callco} is marked by
{\tt c}, and an end corresponding to {\tt cowait} is marked by {\tt
  w}.  The arrows on the connections show the direction in which data
moves.  Notice that, in {\tt tee1}, {\tt callco} is sometimes used for
input and sometimes for output.

            
\begin{figure}[tbh!]
\centerline{\includegraphics[width=117.2mm]{bfigs/f3hamming.png}}
\caption{\label{f3hamming}Coroutine data flow}
\end{figure}
                   
The coroutine {\tt BUF1} controls a queue of integers.  Non-zero
values can be inserted into the queue using {\tt callco(BUF1,val)},
and values can be extracted using {\tt callco(BUF1,0)}.  The
coroutines {\tt BUF2} and {\tt BUF3} are similar.  The coroutine {\tt
  TEE1} is connected to {\tt BUF1} and {\tt BUF2} and is designed so
that {\tt callco(TEE1)} executed in coroutine {\tt X2} will yield a
value that {\tt TEE1} extracted from {\tt BUF1}, after sending a copy
to {\tt BUF2}.  {\tt TEE2} similarly takes values from {\tt BUF2}
passing them to {\tt BUF3} and {\tt X3}.  Values passing through {\tt
  X2}, {\tt X3} and {\tt X5} are multiplied by {\tt2}, {\tt3} and
{\tt5}, respectively.  {\tt MER1} merges two monotonically increasing
streams of numbers produced by {\tt X2} and {\tt X3}.  The resulting
monotonic stream is then merged by {\tt MER2} with the stream produced
by {\tt X5}.  The stream produced by {\tt MER2} is the required
Hamming sequence, each value of which is printed by {\tt MAIN} and
then inserted into {\tt BUF1}.

The BCPL code for this solution is as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim}
GET "libhdr"

LET buf(args) BE    // Body of BUF1, BUF2 and BUF3
{ LET p, q, val = 0, 0, 0
  LET v = VEC 200

  { val := cowait(val)
    TEST val=0 THEN { IF p=q DO writef("Buffer empty*n")
                      val := v!(q MOD 201)
                      q := q+1
                    }
               ELSE { IF p=q+201 DO writef("Buffer full*n")
                      v!(p MOD 201) := val
                      p := p+1
                    }
  } REPEAT
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET tee(args) BE    // Body of TEE1 and TEE2
{ LET in, out = args!0, args!1
  cowait()          // End of initialisation.

  { LET val = callco(in, 0)
    callco(out, val)
    cowait(val)
  } REPEAT
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND mul(args) BE    // Body of X2, X3 and X5
{ LET k, in = args!0, args!1
  cowait()          // End of initialisation.
   
  cowait(k * callco(in, 0)) REPEAT
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET merge(args) BE  // Body of MER1 and MER2
{ LET inx, iny = args!0, args!1
  LET x, y, min = 0, 0, 0
  cowait()          // End of initialisation

  { IF x=min DO x := callco(inx, 0)
    IF y=min DO y := callco(iny, 0)
    min := x<y -> x, y
    cowait(min)
  } REPEAT
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET start() = VALOF
{ LET BUF1 = initco(buf,   500)
  LET BUF2 = initco(buf,   500)
  LET BUF3 = initco(buf,   500)
  LET TEE1 = initco(tee,   100, BUF1, BUF2)
  LET TEE2 = initco(tee,   100, BUF2, BUF3)
  LET X2   = initco(mul,   100,    2, TEE1)
  LET X3   = initco(mul,   100,    3, TEE2)
  LET X5   = initco(mul,   100,    5, BUF3)
  LET MER1 = initco(merge, 100,   X2,   X3)
  LET MER2 = initco(merge, 100, MER1,   X5)

  LET val = 1   
  FOR i = 1 TO 100 DO { writef(" %i6", val)
                        IF i MOD 10 = 0 DO newline()
                        callco(BUF1, val)
                        val := callco(MER2)
                      }

  deleteco(BUF1); deleteco(BUF2); deleteco(BUF3)
  deleteco(TEE1); deleteco(TEE2)
  deleteco(X2); deleteco(X3); deleteco(X5)
  deleteco(MER1); deleteco(MER2)
  RESULTIS 0
}
\end{verbatim}
\end{samepage}

\subsection{\label{cosim}A Discrete Event Simulator}

This is a benchmark test for a discrete event simulator using
coroutines. It simulates a network of $n$ nodes which each receive,
queue, process and transmit messages to other nodes.  The nodes are
uniformly spaced on a straight line and the network delay is assumed
to be proportional to the linear distance between the source and the
destination.  When a message arrives at a node it is queued if the
node was busy, otherwise it is processed immediately.  After
processing the message for random time, it is sent to another randomly
chosen node.  After dispatching the message, the node dequeues its
next message and processes it if there is one, otherwise
the node becomes suspended.  Initially every node is processing a
message and every queue is empty. There are $n$ coroutines to simulate
the progress of each message and the discrete event priority queue is
implemented using the heapsort heap structure. The simulation stops at
a specified simulated time. The result is the number of messages that
have been processed. A machine independent random number generator is
used so the resulting value should be independent of implementation
language and machine being used.

The program is given below. When it is run using the default settings,
it executes 435,363,350 Cintcode instructions and has 2,510,520
coroutine changes.

\bigskip
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
SECTION "cosim"

GET "libhdr"

GLOBAL {
  priq:ug    // The vector holding the priority queue
  priqupb    // The upper bound
  priqn      // Number of items in the priority queue
  wkqv       // The vector of work queues
  count      // count of messages processed
  nodes      // The number of nodes
  ptmax      // The maximum processing time
  stopco     // The stop coroutine
  cov        // Vector of message coroutines
  ranv       // A vector used by the random number generator
  rani; ranj // subscripts of ranv
  simtime    // Simulated time
  stoptime   // Time to stop the simulation
  tracing

// Functions
  rnd;  initrnd;  closernd;  prq;  insertevent;  upheap
  downheap;  getevent;  waitfor;  prwaitq;  qitem;  dqitem
  stopcofn;  messcofn
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
// ################### Random number generator #######################

// The following random number generator is based on one given
// in Knuth: The art of programming, vol 2, p 26.
LET rnd(n) = VALOF
{ LET val = (ranv!rani + ranv!ranj) & #x_FFF_FFFF
  ranv!rani := val
  rani := (rani + 1) MOD 55
  ranj := (ranj + 1) MOD 55
  RESULTIS val MOD n
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND initrnd(seed) = VALOF
{ LET a, b = #x_234_5678+seed, #x_536_2781
  ranv := getvec(54)
  UNLESS ranv RESULTIS FALSE
  FOR i = 0 TO 54 DO
  { LET t = (a+b) & #x_FFF_FFFF
    a := b
    b := t
    ranv!i := t
  }
  rani, ranj := 55-55, 55-24  // ie: 0, 31
  RESULTIS TRUE
}

AND closernd() BE IF ranv DO freevec(ranv)
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
// ################### Priority Queue functions ######################

AND prq() BE
{ FOR i = 1 TO priqn DO writef(" %i4", priq!i!0)
  newline()
}

AND insertevent(event) BE
{ priqn := priqn+1        // Increment number of events
  upheap(event, priqn)
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND upheap(event, i) BE
{ LET eventtime = event!0
//writef("upheap: eventtime=%n i=%n*n", eventtime, i)

  { LET p = i/2          // Parent of i
    UNLESS p & eventtime < priq!p!0 DO
    { priq!i := event
      RETURN
    }
    priq!i := priq!p     // Demote the parent
    i := p
  } REPEAT
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND downheap(event, i) BE
{ LET j, min = 2*i, ? // j is left child, if present
  IF j > priqn DO
  { upheap(event, i)
    RETURN
  }
  min := priq!j!0
  // Look at other child, if it exists
  IF j<priqn & min>priq!(j+1)!0 DO j := j+1
  // promote earlier child
  priq!i := priq!j
  i := j
} REPEAT
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND getevent() = VALOF
{ LET event = priq!1      // Get the earliest event
  LET last  = priq!priqn  // Get the event at the end of the heap
  UNLESS priqn>0 RESULTIS 0 // No events in the priority queue
  priqn := priqn-1        // Decrement the heap size
  downheap(last, 1)       // Re-insert last event
  RESULTIS event
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND waitfor(ticks) BE
{ // Make an event item into the priority queue
  LET eventtime, co = simtime+ticks, currco
  insertevent(@eventtime) // Insert into the priority queue
  cowait()                // Wait for the specified number of ticks
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
// ###################### Queueing functions #########################

AND prwaitq(node) BE
{ LET p = wkqv!node
  IF -1 <= p <= 0 DO { writef("wkq for node %n: %n*n", node, p); RETURN }
  writef("wkq for node %n:", node)
  WHILE p DO
  { writef(" %n", p!1)
    p := !p
  }
  newline()
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND qitem(node) BE
// The message has reached this node
// It currently not busy, mark it as busy and return to process
// the message, other append it to the end of the work queue
// for this node.
{ // Make a queue item
  LET link, co = 0, currco
  LET p = wkqv!node
  UNLESS p DO
  { // The node was not busy
    wkqv!node := -1  // Mark node as busy
    IF tracing DO
      writef("%i8: node %i4: node not busy*n", simtime, node)
    RETURN
  }
  // Append item to the end of this queue
  IF tracing DO
    writef("%i8: node %i4: busy so appending message to end of work queue*n",
            simtime, node)
  TEST p=-1
  THEN wkqv!node := @link     // Form a unit list
  ELSE { WHILE !p DO p := !p  // Find the end of the wkq
         !p := @link          // Append to end of wkq
       }
  cowait() // Wait to be activated (by dqitem)
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND dqitem(node) BE
// A message has just been processed by this node and is ready to process
// the next, if any.
{ LET item = wkqv!node // Current item (~=0)
  UNLESS item DO abort(999)
  TEST item=-1
  THEN wkqv!node := 0                  // The node is no longer busy
  ELSE { LET next = item!0
         AND co   = item!1
         wkqv!node := next -> next, -1 // De-queue the item
         callco(co)                    // Process the next message
       }
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
// ######################## Coroutine Bodies ##########################

AND stopcofn(arg) = VALOF
{ waitfor(stoptime)
  IF tracing DO
    writef("%i8: Stop time reached*n", simtime)
  RESULTIS 0
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim}
AND messcofn(node) = VALOF
{ qitem(node)   // Put the message on the work queue for this node

  { // Start processing the first message
    LET prtime   = rnd(ptmax)     // a random processing time
    LET dest     = rnd(nodes) + 1 // a random destination node
    LET netdelay = ABS(node-dest) // the network delay

    IF tracing DO
      writef("%i8: node %i4: processing message until %n*n",
              simtime, node, simtime+prtime)
    waitfor(prtime)
    count := count + 1 // One more message processed
    IF tracing DO
      writef("%i8: node %i4: message processed*n",
              simtime, node, dest, simtime+netdelay)
    dqitem(node) // De-queue current item and activate the next, if any
    IF tracing DO
      writef("%i8: node %i4: sending message to node %n to arrive at %n*n",
              simtime, node, dest, simtime+netdelay)

    waitfor(netdelay)
    node := dest      // The message has arrived at the destination node
    IF tracing DO
      writef("%i8: node %i4: message reached this node*n",
              simtime, node)
    qitem(node)   // Queue the message if necessary
    // The node can now process the first message on its work queue
  } REPEAT
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
// ######################### Main Program ############################

LET start() = VALOF
{ LET seed = 0
  LET argv = VEC 50

  UNLESS rdargs("-n/n,-s/n,-p/n,-r/n,-t/s", argv, 50) DO
  { writef("Bad arguments for cosim*n")
    RESULTIS 0
  }

  nodes, stoptime, ptmax := 500, 1_000_000, 1000
  IF argv!0  DO nodes    := !(argv!0) // -n/n
  IF argv!1  DO stoptime := !(argv!1) // -s/n
  IF argv!2  DO ptmax    := !(argv!2) // -p/n
  IF argv!3  DO seed     := !(argv!3) // -r/n
  tracing := argv!4                   // -t/s
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
  writef("*nCosim entered*n*n")
  writef("Network nodes:       %n*n", nodes)
  writef("Stop time:           %n*n", stoptime)
  writef("Max processing time: %n*n", ptmax)
  writef("Random number seed:  %n*n", seed)
  newline()

  UNLESS initrnd(seed) DO
  { writef("Can't initialise the random number generator*n")
    RESULTIS 0
  }
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
  stopco := 0
  wkqv, priq, cov := getvec(nodes), getvec(nodes+1), getvec(nodes)
  UNLESS wkqv & priq & cov DO  
  { writef("Can't allocate space for the node work queues*n")
    GOTO ret
  }

  FOR i = 1 TO nodes DO wkqv!i, cov!i := 0, 0
  priqn := 0  // Number of events in the priority queue
  count := 0  // Count of message processed
  simtime := 0 // Simulated time

  IF tracing DO writef("%i8: Starting simulation*n", simtime)

  // Create and start the stop coroutine
  stopco := createco(stopcofn, 200)
  IF stopco DO callco(stopco)
  // Create and start the message coroutines
  FOR i = 1 TO nodes DO
  { LET co = createco(messcofn, 200)
    IF co DO callco(co, i)
    cov!i := co
  }
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
  // Run the event loop

  { LET event = getevent()      // Get the earliest event
    UNLESS event BREAK
    simtime := event!0          // Set the simulated time
    IF simtime > stoptime BREAK
    callco(event!1)
  } REPEAT

  IF tracing DO writef("*nSimulation stopped*n*n")
  writef("Messages processed: %n*n", count)
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
ret:
  FOR i = nodes TO 1 BY -1 IF cov!i DO deleteco(cov!i)
  IF cov    DO freevec(cov)
  IF wkqv   DO freevec(wkqv)
  IF priq   DO freevec(priq)
  IF stopco DO deleteco(stopco)
  closernd()
  RESULTIS 0

fail:
  writef("Unable to initialise the simulator*n")
  GOTO ret
}
\end{verbatim}
\end{samepage}

\section{The BMP Graphics Library}

The graphics library provides facilities for drawing pictures and
outputing them to file. This library is designed to generate {\tt.bmp}
files representing potentially large images using 8-bit or 24-bit
coloured pixels. It is designed to create files representing 2 dimensional
rectangular images using the {\tt.bmp} file format. It should not be
confused with the SDL and GL libraries (described later) used to
generate images on the display screen suitable for interactive
graphics typically used in computer games.

This library is initialised by a call of {\tt opengraphics} which
specifies the size of the image to be drawn and whether 8 or 24 bit
pixels are to be used. It also sets up a palette of 256 colours if 8
bit pixels are to be used. The graphics header file is in {\tt
  g/graphics.h}. It declares the constants {\tt mode8bit}, {\tt
  mode8bitalt} and {\tt mode24bit} for use in the call of {\tt
  opengraphics}. It also declares several variables starting at
position {\tt g\_grbase} which is declared with value 450 in {\tt
  libhdr.h} but can be redefined, if necessary, before inserting {\tt
  graphics.h}. The graphics global variables are as follows.

\bigskip
\noindent
{\bf xsize}, {\bf ysize}\\
\indent
These hold the the number of pixels in each row and column of the canvas.

\bigskip
\noindent
{\bf bmpmode}\\
\indent
This is set by {\tt opengraphics} to {\tt mode8bit}, {\tt mode8bitalt}
or {\tt mode24bit}.

\bigskip
\noindent
{\bf bpp}\\
\indent
This holds the the number of bytes (1 or 3) per pixel in {\tt canvas}.

\bigskip
\noindent
{\bf rowlen}\\
\indent
This holds {\tt bpp*xsize}, the number of bytes in {\tt canvas} to represent a row.

\bigskip
\noindent
{\bf canvassize}\\
\indent
This holds the number of bytes ({\tt rowlen*ysize}) in {\tt canvas}.

\bigskip
\noindent
{\bf canvasupb}\\
\indent
This holds the UPB of {\tt canvas} in words.

\bigskip
\noindent
{\bf canvas}\\
\indent
This holds the vector, allocated by {\tt getvec(canvasupb)}, of pixel
bytes to represent the image. Each pixel is either an 8-bit byte
identifying a colour in the palette or 3 bytes giving the blue, green
and red components of the colour directly.

\bigskip
\noindent
{\bf palettev}\\
\indent
If 8-bit pixels are being used, this holds the palette vector of 256
colours.  The colours are specified by values of the form {\tt
  \#Xrrggbb} in the least significant 24 bits of each element of {\tt
    palettev}.  {\tt palettev} is set to zero when 24 bit pixels are
  being used.

\bigskip
\noindent
{\bf col\_white},
{\bf col\_majenta},
{\bf col\_blue},
{\bf col\_cyan},
{\bf col\_green},
{\bf col\_yellow},
{\bf col\_red},
{\bf col\_black}\\
\indent
These variables hold either various 8 or 24 bit colour values.

\bigskip
\noindent
{\bf currx},
{\bf curry},
{\bf currcolour}\\
\indent
These variables hold the current pixel location and the current 8 or
24 bit colour.  This library uses the convention that the bottom
leftmost pixel has coordinate {\tt(0,0)}. The direction of the x axis
is to the right and the direction of the y axis is up. The primary use
of {\tt currx} and {\tt curry} is their use in {\tt drawto}, {\tt
  drawby} and {\tt drawch} to make drawing sequences of lines and
characters more convenient.

\subsection{The Graphics Functions}

The BMP global functions are defined in {\tt g/graphics.b}. They are
as follows.  Except for {\tt opengraphics}, {\tt closegraphics} and
{\tt wrgraph} they are the same as those in the SDL library.

\bigskip
\noindent
{\tt opengraphics(\em xsize\tt, \em ysize\tt, \em mode\tt)}\\
\indent\nopagebreak
This function sets {\tt bmpmode} to {\em mode} and allocates the vector
{\tt canvas}. If 8 bit pixels are specified by {\em mode} it allocates
{\tt palettev} and fills it with one of two sets of palette colours.
It also initialised all the other graphics variables. The canvas is
initially filled with white pixels (like a blank sheet of paper).


\bigskip
\noindent
{\tt closegraphics()}\\
\indent\nopagebreak
This function closes the graphics library returning {\tt canvas} to
freestore and if {\tt palettev} was allocated it is also returned.

\bigskip
\noindent
{\tt drawpoint(\em x\tt , \em y\tt)}\\
\indent\nopagebreak
This function places a pixel with colour specified by {\tt currcolour}
at position $(x,y)$ on the canvas.

\bigskip
\noindent
{\tt drawpoint33(\em x\tt , \em y\tt)}\\
\indent\nopagebreak
This function places a 3x3 square of pixels with the colour specified
by {\tt currcolour} centred at position $(x,y)$ on the canvas.

\bigskip
\noindent
{\tt drawch(\em ch\tt)}\\
\indent\nopagebreak
This function draws a 8x12 array of pixels representing the given
character.  Its colour is specified by {\tt currcolour} on a white
background. The bottom leftmost pixel of the character is at ({\tt
  currx},{\tt curry}). If $ch$ is {\tt'*n'}, {\tt currx} is set to 10
and {\tt curry} is decremented by 14, otherwise {\tt currx} is
incremented by 9.

\bigskip
\noindent
{\tt drawstr(\em x\tt, \em y\tt,\em str\tt)}\\
\indent\nopagebreak
This function calls {\tt drawch} for each character in the given
string starting at position $(x,y)$,

\bigskip
\noindent
{\tt moveto(\em x\tt, \em y\tt)}\\
\indent\nopagebreak
This function sets {\tt currx} and {\tt curry} to $x$ and $y$,
respectively.

\bigskip
\noindent
{\tt moveby(\em dx\tt, \em dy\tt)}\\
\indent\nopagebreak
This function increments {\tt currx} and {\tt curry} by $dx$ and $dy$,
respectively.

\bigskip
\noindent
{\tt drawto(\em x\tt, \em y\tt)}\\
\indent\nopagebreak
This function draws a straight line of colour {\tt currcolour} from
({\tt currx}, {\tt curry}) to $(x,y)$.
It leaves ({\tt currx} and {\tt curry}) to $x$ and $y$.

\bigskip
\noindent
{\tt drawby(\em dx\tt, \em dy\tt)}\\
\indent\nopagebreak
This function draws a straight line of colour {\tt currcolour} from ({\tt
  currx}, {\tt curry}) to ({\tt currx}+{\em dx}, {\tt curry}+{\em dy}).
It then increments {\tt currx} and {\tt curry} by $dx$ and $dy$,
respectively.

\bigskip
\noindent
{\tt drawrect(\em x\tt, \em y\tt, \em w\tt, \em h\tt)}\\
\indent\nopagebreak
This function draws the outline of the rectangle of width $w$ and
height $h$ with the bottom left corner at $(x,y)$ using {\tt
  currcolour}.

\bigskip
\noindent
{\tt drawrndrect(\em x\tt, \em y\tt, \em w\tt, \em h\tt, \em radius\tt)}\\
\indent\nopagebreak
This function draws the outline of the rectangle of width $w$ and
height $h$ with its bottom left corner at $(x,y)$ with rounded corners
of given radius. Its colour is specified by {\tt currcolour}.  If {\em
  radius} is less than or equal to zero the corners are square, and if
{\em radius} is greater than half the shorter side length it is
reduced to this value. {\tt currx} and {\tt curry} are set to $x1$ and
$y1$, respectively.

\bigskip
\noindent
{\tt fillrect(\em x\tt, \em y\tt, \em w\tt, \em h\tt)}\\
\indent\nopagebreak
This function draws a rectangle of width $w$ and height $h$ with its
bottom left corner at $(x,y)$. It is filled with the colour specified
by {\tt currcolour}.

\bigskip
\noindent
{\tt fillrndrect(\em x\tt, \em y\tt, \em w\tt, \em h\tt, \em radius\tt)}\\
\indent\nopagebreak
This function draws the rectangle of width $w$ and height $h$ with
rounded corners of given radius. The bottom left corner is at $(x,y)$.
It colour is specified by {\tt currcolour}. If {\em radius} is less
than or equal to zero the corners are square, and if {\em radius} is
greater than half the shorter side length it is reduced to this value.


\bigskip
\noindent
{\tt drawcircle(\em x\tt, \em y\tt, \em radius\tt)}\\
\indent\nopagebreak
This function draws a circle centred at $(x,y)$ with given radius. Its
colour is specified by {\tt currcolour}.

\bigskip
\noindent
{\tt fillcircle(\em x\tt, \em y\tt, \em radius\tt)}\\
\indent\nopagebreak
This function draws a filled circle centred at $(x,y)$ with given
radius. Its colour is specified by {\tt currcolour}.

\bigskip
\noindent
{\tt drawellipse(\em x\tt, \em y\tt, \em rx\tt, \em ry\tt)}\\
\indent\nopagebreak
This function draws an ellipse centred at $(x,y)$ with given
{\tt x} and {\tt y} radii. Its colour is specified by {\tt currcolour}.

\bigskip
\noindent
{\tt fillellipse(\em x\tt, \em y\tt, \em rx\tt, \em ry\tt)}\\
\indent\nopagebreak
This function draws a filled ellipse centred at $(x,y)$ with given
{\tt x} and {\tt y} radii. Its colour is specified by {\tt currcolour}.

\bigskip
\noindent
{\tt wrgraph(\em filename\tt)}\\
\indent\nopagebreak
This function writes the image held in {\tt canvas} to the given file
in {\tt .bmp} format. The image is (currently) scaled to 300 DPI which
corresponds to 11811 pixels per metre. At this scale the size of an A4
page is 2490x3510 pixels.

There are two programs to illustrate how this graphics library can be
used. They are {\tt bcplprogs/tests/grtst.b} and {\tt
  bcplprogs/tests/grpalette.b}. If you are using BCPL under Linux you
can compile and run them as follows.

\bigskip
{\small
\begin{verbatim}
cd ~/distribution/BCPL/bcplprogs/test
cintsys
c b grtst
grtst
ctrl-c
gimp grtst.bmp
ctrl-c
cintsys
c b grpalette
grpalette b8
ctrl-c
gimp palette.bmp
ctrl-c
cintsys
grpalette b24
ctrl-c
gimp palette.bmp
\end{verbatim}
}

\smallskip
The image displayed by the last call of {\tt gimp} is shown in
figure~\ref{palette} illustrating some of the colours available
when using 24 bit pixels.

\smallskip

\begin{figure}[tbh!]
\centerline{\includegraphics[width=130.0mm]{bfigs/palette.png}}
\caption{\label{palette}The image created by {\tt grpalette b24}}
\end{figure}
                   



\section{The SDL Graphics Library}

The SDL Graphics Library implemented in C is available for many
platforms including Linux, Windows and OSX and BCPL has an interface
with this library allowing the user to create a window on the screen
and repeatedly draw simple images allowing simple interactive games to
be implemented. It also provides access to the keyboard, the mouse and
joysticks. In due course this interface will allow the generation of
sound.

To include these features it is necessary to install the SDL libraries
on you machine and then build {\tt cintsys} using a Makefile such as
{\tt MakefileSDL} or {\tt MakefileRaspiSDL}.

The SDL operations are invoked by calls of the form {\tt
  sys(Sys\_sdl,...)}.  There is a header file ({\tt g/sdl.h})
declaring the various constants and globals available, and {\tt
  g/sdl.b} contains the definitions of several functions providing the
interface. The constant {\tt g\_sdlbase} is set in {\tt libhdr.h} to be
the first global used in the SDL library. It can be overridden by
re-defining {\tt g\_sdlbase} before GETting {\tt sdl.h}.

A program using the SDL library should start with the following lines.

\medskip
\begin{verbatim}
GET "libhdr"
MANIFEST { g_sdlbase=nnn  } // Only used if the default setting of 450 in
                            // libhdr is not suitable.
GET "sdl.h"
GET "sdl.b"                 // Insert the library source code
.
GET "libhdr"
MANIFEST { g_sdlbase=nnn  } // Only used if the default setting of 450 in
                            // libhdr is not suitable.
GET "sdl.h"
\end{verbatim}

\medskip
\noindent
There are several programs that use SDL described in Chapter 4 of {\tt
  bcpl4raspi.pdf} available from my home page.


\subsection{{\tt sdl.h} details}

The BCPL SDL functions make use of functions provided by the SDL
library implemented in C. These sometimes use machine addresses
pointing to structures such as those representing windows and
surfaces. Such addresses are stored in BCPL in a pair of words as
described in the description of {\tt scb\_fd} on page~\pageref{scbfd}.

The global variables {\tt screen}, {\tt screen1}, {\tt currsurf}, {\tt
  currsurf1}, {\tt format}, {\tt format1}, {\tt joystick} and {\tt
  joystick1} hold address pairs for The SDL window, the currently
selected surface, the format structure for that window and a joystick.

A call of {\tt mkscreen} sets the variables {\tt screenxsize} and {\tt
  screenysize} to the number of pixels in the width and height of the
created window. It alse sets {\tt fscreenxsize} and {\tt fscreenysize}
to the floating point versions of these variables.  The variable {\tt
  fscreencentrex} and {\tt fscreencentrey} are the floating point
coordinates of the center of the screen.

The width and height of the currently seclected surface is held in
{\tt currxsize} and  {\tt currysize}.

The vectors {\tt leftxv}, {\tt leftzv}, {\tt rightxv} and {\tt
  rightzv} are used by the functions such as {\tt drawtriangle} and
{\tt drawtriangle3d} defined in {\tt g/sdl.b} that draw filled
objects. The variables {\tt miny} and {\tt maxy} are also used by these
functions.

The vector {\tt depthv} and variables {\tt miny} and {\tt maxy} are
used by functions in {\tt g/sdl.b} and should not be touched by the
user. The 3D drawing functions use {\tt depthv} to implement the
hiding of pixels that are further from the eye than other pixel at the
same position on the screen. The upperbound of {\tt depthv} is {\tt
  depthvupb} (={\tt screenxsize*screenysize-1}). The elements of {\tt
  depthv} are scaled integers with {\tt zfac} units of depth
corresponding to a distance of one pixel.  The variab;e {\tt zfac} is
actually a floating point number since the 3D drawing functions
typiclally take floating point pixel coordinates. If {\tt zfac} is too
small the the line of intersection of two nearly parallel plane can
become inaccurate.  The maximum allowable scaled depth is held in {\tt
  maxdepth} ({\tt =-1\_000\_000\_000}).

Whenever anything is drawn it is given the colour held in the variable
{\tt currclour}. The variables {\tt currx} and {\tt curry} give the
starting position of 2D lines and characters. They are updated after
each line or characte is drawn. This allows long sequences of 2D lines
or charaters to be drawn conveniently.

There is a similar mechanism for drawing 3D lines using the variables
{\tt currx3d}, {\tt curry3d} and {\tt currsz3d}. These hold the
integer {\tt x} and {\tt y} pixel coordindates of the next 3D line to
be drawn with {\tt currsx3d} being its scaled integer depth.

The variables {\tt mousex} and {\tt mousey} hold the current pointer
position 0n the screen, and {\tt mousebuttons} is a bitpattern
indicating which mouse buttons are currently pressed.

Some or all of the variables {\tt eventtype}, {\tt eventa1}, {\tt
  eventa2}, {\tt eventa3}, {\tt eventa4} and {\tt eventa5} are set by
the function {\tt pollevents} as described below.

\begin{verbatim}

sdle\_active
sdle\_keydown
sdle\_keyup
sdle\_mousemotion
sdle\_mousebuttondown
sdle\_mousebuttonup
sdle\_joyaxismotion
sdle\_joyballmotion
sdle\_joyhatmotion
sdle\_joybuttondown
sdle\_joybuttonup
sdle\_quit
sdle\_syswmeven
sdle\_videoresize
sdle\_userevent

sdle\_arrowup
sdle\_arrowdown
sdle\_arrowright
sdle\_arrowleft

sdl\_init_everything

sdl\_SWSURFACE   // Surface is in system memory
sdl\_HWSURFACE   // Surface is in video memory

sdl\_ANYFORMAT	 // Allow any video depth/pixel-format
sdl\_HWPALETTE	 // Surface has exclusive palette
sdl\_DOUBLEBUF	 // Set up double-buffered video mode
sdl\_FULLSCREEN	 // Surface is a full screen display
sdl\_OPENGL      // Create an OpenGL rendering context
sdl\_OPENGLBLIT	 // Create an OpenGL context for blitting
sdl\_RESIZABLE	 // This video mode may be resized
sdl\_NOFRAME	 // No window caption or edge frame
\end{verbatim}



\subsection{Functions defined in {\tt sdl.b}}

This section describes all the functions defined in {\tt g/sdl.b}
in alphabetical order.


\bigskip
\noindent
{\tt alloc2dvecs()}\\
\indent
this function is only used in {\tt drawtriangle}. It allocates and initialises
the vectors {\tt leftxv} and {\tt rightxv}.



\bigskip
\noindent
{\tt alloc3dvecs()}\\
\indent
this function is only used in {\tt drawtriangle2d}. It allocates and initialises
the vectors {\tt leftxv}, {\tt lefttszv},  {\tt rightxv} and  {\tt rightszv}.
.




\bigskip
\noindent
{\tt blitsurf(srcptr, dstptr, x, y)}\\
\indent
This copies the source surface into the specified position of the destination
surface.



\bigskip
\noindent
{\tt bltsurfrect(srcptr, srcrect, dstptr, x, y)}\\
\indent
Copy the specified rectangle from the source surface to
the specified position in the destination surface.





\bigskip
\noindent
{\em rc } {\tt:=  closesdl()}\\
\indent
This closes down the SDL library returning all allocated space to
freestore.



\bigskip             % Not in sdl.b
\noindent
{\tt crossprod(v1, v2, v3)}\\
\indent
This computes the cross product of {\tt v1} and {\tt v2} which are
both vectors with three floating point elements. The result is thus a
vector orthogonal to {\tt v1} and {\tt v2} whose length is the sine of
the angle between the vectors multiplied by the product of their
lengths. The vectors {\tt v1}, {\tt v1} and {\tt v1} are in right
handed orientation.


\bigskip
\noindent
{\tt  drawby(dx, dy)}\\
\indent
This is just calls {\tt drawto(currx+dx, curry+dy)}.


\bigskip
\noindent
{\tt  drawby3d(FLT dx, FLT dy, FLT dz)}\\
\indent
This is just calls {\tt drawto3d(currx+dx, curry+dy, currz+dz)}.


\bigskip
\noindent
{\tt drawch(ch)}\\
\indent
Draw a 12x8 character at the position specified b y and {\tt curry}
and increment {\tt curry} by 9. If {\tt ch} was \verb|'*n'| set {\tt
  currx} to 10 and decrement {\tt curry} by 11.



\bigskip
\noindent
{\tt drawcircle(x0,y0, radius)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawf(x, y, form, a, b, c,..., t)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawfillcircle(x, y, radius)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawfillrect(x0,y0, x1,y1)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawfillrndrect(x0, y0, x1, y1, radius)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt  drawpoint(x, y)}\\
\indent
This draws a point at location {\tt (x,y)} on the currently selected surface.
It colour is te one set by the most recent call of {\tt setcolour}.

\bigskip
\noindent
{\tt  drawpoint3d(FLT x, FLT y, FLT z)}\\
\indent
This draws a point at location {\tt (x,y)} on the currently selected
surface. If the {\tt z} value at that position is greater than {\tt z}
the pixel is not updated.


\bigskip
\noindent
{\tt drawpoint3di(x, y, sz)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawquad(x1,y1, x2,y2, x3,y3, x4,y4)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawquad3d(FLT x1, FLT y1, FLT z1,
               FLT x2, FLT y2, FLT z2,
	       FLT x3, FLT y3, FLT z3,
	       FLT x4, FLT y4, FLT z4)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawrect()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawrndrect()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawstr()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawto()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawto3d()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawto3d()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawto3di()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawtriangle()}\\
\indent
{\em Not yet described}

 

\bigskip
\noindent
{\tt drawtriangle3d(FLT x1, FLT y1, FLT z1,
                    FLT x2, FLT y2, FLT z2,
		    FLT x3, FLT y3, FLT z3)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt drawwrch(ch)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt fillsurf(col)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt freesurface(surfptr)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt getevent()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt getmousestate()}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt hidecursor()}\\
\indent
{\em Not yet described}




\bigskip
\noindent
{\em rc } {\tt:= initsdl()}\\
\indent
This initialises the SDL library and sets the global variables used by
{\tt sdl.b}. It must be called before any other SDL operations can be
performed. It returns {\tt TRUE} if successful.

\bigskip             % Not in sdl.b
\noindent
$res$ {\tt:= inprod(v1, v2)}\\
\indent
This returns the inner product of {\tt v1} and {\tt v2} which are both
vectors with three floating point elements. The result is thus the
cosine of the angle between the vectors multiplied by the product of
their lengths.


\bigskip
\noindent
{\em colour } {\tt:=  maprgb(r,g,b)}\\
\indent
This return a value representing the colour specified by its {\tt r},
{\tt r} and {\tt r} components. It uses the colour represention chosen
during the call of {\tt mkscreen}.


\bigskip
\noindent
{\em rc } {\tt:=  mkscreen(title, xsize, ysize)}\\
\indent
This creates a window of specified size with the given title. It returns
{\tt TRUE} if sucessful.



\bigskip
\noindent
{\tt mksurface(w, h, surfptr)}\\
\indent
{\em Not yet described}



\bigskip
\noindent
{\tt  moveby(dx, dy)}\\
\indent
This is just calls {\tt moveto(currx+dx, curry+dy)}.


\bigskip
\noindent
{\tt  moveby3d(FLT dx, FLT dy, FLT dz)}\\
\indent
This is just calls {\tt moveto3d(currx+dx, curry+dy, currz+dz)}.


\bigskip
\noindent
{\tt  moveto(x, y)}\\
\indent
This selects position {\tt (x,y)} in the currently selected surface
used by subsequent calls of {\tt drawch}, {\tt drawto} and {\tt
  drawby}. Its depth coordinate is given the value zero.

\bigskip
\noindent
{\tt  moveto3d(FLT x, FLT y, FLT z)}\\
\indent
This selects position {\tt (x,y,z)} in the currently selected surface
used by subsequent calls of {\tt drawch}, {\tt drawto} and {\tt
  drawby}. By convention smaller values of z are deeper into the
screen.


\bigskip
\noindent
{\tt sdldelay(msecs)}
\indent
This causes a real time delay of the specified number of milliseconds.



\bigskip
\noindent
{\tt sdlmsecs()}\\
\indent
This return the number of real time milliseconds since the current
command was entered.




\bigskip
\noindent
{\tt  selectsurface(surfptr, xsize, ysize)}\\
\indent
This selects a surface for use in subsequent drawing commands.  The
arguments {\tt xsize} and {\tt ysize} specify the size of the surface
in pixels. The pair of BCPL word used to represent the machine address
of the surface is pointed to by {\tt surfptr}. See {\tt scb\_fd} on
page~\pageref{sdlfd} for more details.


\bigskip
\noindent
{\em rc } {\tt:=  setcaption(title)}\\
\indent
This resets the title of the window created by {\tt mkscreen}. It
returns {\tt TRUE} if successful.


\bigskip
\noindent
{\tt  setcolour(col)}\\
\indent
This sets the colour to be used in subsequent drawing commands. The
colour should be one returned by a call of {\tt maprgb}.


\bigskip
\noindent
{\tt  setcolourkey(col)}\\
\indent
This sets the colour that has the special property that when an
attempt is made to to draw a pixel with this colour the pixel is
left with its previous colour. This mechanism is used, for example,
when displaying the moving coloured circles by the program {\tt
  bcplprogs/raspi/bucket.b}.



\bigskip
\noindent
{\tt setlims(x0,y0, x1,y2)}
\indent
This function is used by {\tt drawtriangle} which draws a filled 2D
triangle. It updates entries in {\tt leftxv} and {\tt rightxv} for
each value of {\tt y} between {\tt y0} and {\tt y1}.


\bigskip
\noindent
{\tt setlims3d(x0,y0,sz0, x1,y2,sz1)}
\indent
This function is used by {\tt drawtriangle3d} when drawing a filled 3D
triangle. It updates entries in {\tt leftxv}, {\tt leftszv}, {\tt
  rightxv} and {\tt rightszv} for each value of {\tt y} between {\tt
  y0} and {\tt y1}. The arguments are all integers with the {\tt z}
components being scaled to cause {\tt zfac} units to correspond to a
distance of one pixel.


\bigskip
\noindent
{\tt showcursor()}\\
\indent
This causes the cursor to be displayed.


\bigskip                % Not in sdl.b
\noindent
{\tt standardize(v)}\\
\indent
This divides the three floating point elements of the vector {\tt v}
by length of the vector leaving the elements of {\tt v} set to the
direction cosines of the given vector.



\bigskip
\noindent
{\tt updatescreen()}\\
\indent
This causes the surface that is currently being drawn to be copied the
display screen.

\bigskip
\noindent
{\tt write\_ch\_slice(x, y, ch, line)}\\
\indent
This function is used by {\tt drawch} to plot a row pixels of
a 8x12 character.





The pixels to be drawn on the screen by the next call of {\tt
  updatescreen} are held in a vector pointed to by the global variable
{\tt screen}. In order to implement hidden surface removal there is a
second vector {\t depthv} holding the {\tt z} coordinates of pixels in
{\tt screen}. This vector is only used by the 3D drawing
functions. The depth values were held as scaled integers with {\tt
  zfac} units corresponding to a distance of one pixel.

This eliminated
some of the problems caused by using integers to represent depth which
was particularly noticable when two nearly parallel 3D plane
interected. Unfortunately floating point numbers caused other problems
mainly due to their lack of precision so integers are again going to
be used but 64 units of an element of {\tt depthv} will now represent
a distance of one pixel. Even though these units are used in {\tt depthv},
all the 3D drawing functions will use the convention that one unit in {\tt
  x}, {\tt x} and {\tt x} will represent a distance of one pixel. The
fractional values in {\tt depthv} only occur when drawing 3D lines and
triangles. The vertices of lines and triangles always occur on pixel
boundaries.


    
\subsection{{\tt sys(Sys\_sdl,...)} calls}
  
\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_avail}\\
\indent
This return {\tt TRUE} if the SDL facilities are available.

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_init)}\\
\indent
This ...


\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_setvideomode, width, height, bbp, flags)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_quit)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_locksurface, surfptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_unlocksurface, surfptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_getsurfaceinfo, surfptr, ptr)}\\
          %and a pointer to [flag, format, w, h, pitch, pixels]

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_getfmtinfo. fmtptr)}\\
            %, and a pointer to [palette, bitspp, bytespp,
%                   // rloss, rshift, gloss, gshift, bloss, bshift, aloss, ashift,
%                   // colorkey, alpha])}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_geterror, str)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_updaterect, surfptr, left, top, right, bottom)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_loadbmp, filename of a .bmp image)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_blitsurface. src, srcrect, dest, destrect)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_setcolourkey, surfptr, flags, colorkey)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_freesurface, surfptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_setalpha, surfptr, flags, alpha)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_imgload, filename)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_delay, msecs)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_flip, surfptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_displayformat, surfptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_waitevent, pointer)}\\
%to [type, args, ... ] to hold details of the next event
%                   // return 0 if no events available

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_pollevent, pointer)}\\
%to [type, args, ... ] to hold details of the next event
%                   // return 0 if no events available)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_getmousestate, pointer)}\\
%to [x, y] returns bit pattern of buttons currently pres%sed)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_loadwav, file, spec, buff, len)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_freewav, buffer)}\\


\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_wm\_setcaption, string)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_videoinfo, v)}\\
%=> [ flags, blit_fill, video_mem, vfmt])}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_maprgb. formatptr, r, g, b)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawline,)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawhline, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawvline,)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawcircle, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawrect, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawpixel, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawellipse, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawfillellipse, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawround. )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawfillround, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawfillcircle, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_drawfillrect, )}\\


\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_fillrect, )}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_fillsurf, )}\\



\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_numjoysticks)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joystickopen, index, jpyptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joystickclose, index)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joystickname, index)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joysticknumaxes, joyptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joysticknumbuttons, joyptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joysticknumballs, joyptr)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joysticknumhats, joyptr)}\\




\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joystickeventstate, aeg\_}\\
%//49  sdl_enable=1 or sdl_ignore=0)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_getticks)}\\


\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_showcursor)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_hidecursor)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_mksurface)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_setcolourkey)}\\


\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joystickgetbutton)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joystickgetaxis)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joystickgetball)}\\

\bigskip
\noindent
$rc$ {\tt:= sys(Sys\_sdl, sdl\_joystickgethat)}\\


%sdl\_ignore           = 0
%sdl\_enable           = 1  // eg enable joystick events




%\bigskip
%\noindent
%$n$ {\tt:= sys(Sys\_write, \em fp\tt, \em buf\tt, \em len\tt)}\\
%\indent
%This ...










\section{The GL Graphics Library}

{\em This library is still under development}

OpenGL is a sophisticated graphics library allowing 3D images to be
drawn on the screen efficiently using the full power of the graphics
hardware available on most machines. On most desktop and laptop
machines the full OpenGL library is available, but on handheld devices
only a simplified version called OpenGL ES is available. The BCPL
interface is designed to work with whichever version of OpenGL is
available. This library essentially provides a subset of the OpenGL ES
features. Note that the GL interface on the Raspberry Pi uses OpenGL
ES.

To include these features in {\tt cintsys} it is necessary to install
the OpenGL libraries on you machine and then build {\tt cintsys} using a
Makefile such as {\tt MakefileGL}, {\tt MakefileRaspiGL} or {\tt
  MakefileVCGL}.

The GL library uses the {\tt sys(Sys\_gl,...)} functions.  There is
a header file ({\tt g/gl.h}) declaring the various constants and globals
available in the GL library, and {\tt g/gl.b} contains the
definitions of several functions providing the interface to OpenGL. The
constant {\tt g\_glbase} is set in {\tt libhdr} to be the first
global used in the GL library. It can be overridden by re-defining
{\tt g\_glbase} after GETting {\tt libhdr}.

A program wishing to use the OpenGL library should start with the
following lines.

\medskip
\begin{verbatim}
GET "libhdr"
MANIFEST { g_glbase=nnn  }  // Only used if the default setting of 450 in
                            // libhdr is not suitable.
GET "gl.h" 
GET "gl.b"                  // Insert the library source code
.
GET "libhdr"
MANIFEST { g_glbase=nnn  }  // Only used if the default setting of 450 in
                            // libhdr is not suitable.
GET "gl.h"
\end{verbatim}

\medskip
\noindent
This library will be described in Chapter 5 of {\tt
  bcpl4raspi.pdf} available from my home page.



\section{The Sound Library}

{\em This library is under development}

The sound library uses the {\tt sys(Sys\_sound,...)} functions to
provide facilities for reading, writing and analysing sound data.
There is a sound header file ({\tt g/sound.h}) declaring various
constants and globals available in the sound library. The sound
library itself is in {\tt g/sound.b} and can be inserted into a
program by the following statements.

\medskip
\begin{verbatim}
GET "libhdr"
MANIFEST { g_sndbase=nnn  } // Only used if the default setting of 400 in
                            // libhdr is not suitable.
GET "sound.h"
GET "sound.b"               // Insert the library source code
\end{verbatim}

\medskip
\noindent
The manifest constant {\tt g\_sndbase} specifies the position of the
first global variable to be used by the sound library.

\subsection{The Sound Constants}

 {\em The sound library is not yet available.}

\subsection{The Sound Global Variables}

 {\em The sound library is not yet available.}

\subsection{The Sound Functions}

 {\em The sound library is not yet available.}

\section{The EXT Library}

This library is designed to allow users to construct their own
extension library involving code in C and assembly language. Its
structure is similar to that of the SDL and GL libraries.

It uses the {\tt sys(Sys\_ext,...)} functions to interface with C code
defined in {\tt sysc/extfn.c}, and has two header files {\tt ext.h}
and {\tt ext.b} providing the BCPL interface.  Programs using the EXT
library should start with the following statements.

\medskip
\begin{verbatim}
GET "libhdr"
MANIFEST { g_extbase=nnn  } // Only used if the default setting of 900 in
                            // libhdr is not suitable.
GET "ext.h"
GET "ext.b"                 // Insert the library source code
\end{verbatim}


\cleardoublepage

\chapter{\label{CLI}The Command Language}

The Command Language Interpreter (CLI) is a simple interactive
interface between the user and the system.  It loads and executes
previously compiled programs that are held either in the current
directory or one of the directories specified by the shell environment
variable (typically {\tt BCPLPATH} or {\tt POSPATH}) whose name is in
{\tt rootnode!rtn\_path}.  These commands are described in
Section~\ref{commands} and their source code can be found in the {\tt
com} directory.  The command language is a combination of the features
provided by the CLI and the collection of commands that can be
invoked. Under Cintpos, a similar CLI program provides command
language interpreters in several contexts such as those created by the
commands: {\tt run}, {\tt newcli}, {\tt tcpcli} and {\tt mbxcli}.
Details of the implementation of both CLIs are given at the end of
this chapter from page~\pageref{cliimplementation}.

Commands can set a return code in the global {\tt returncode} with
zero meaning successful termination and other values indicating the
severity of the fault. Commands that set a non zero return code are
expected to leave a reason code in {\tt result2}. The CLI copies the
return code and reason code of the previous command into the CLI
variables {\tt cli\_returncode} and {\tt cli\_result2}, respectively.
These can be inspected by commands such as {\tt if} and {\tt why} and
also used by the CLI to terminate a command-command if the failure was
severe enough. For details, see the command {\tt failat} on
page~\pageref{failat} below.


\section{Bootstrapping Cintsys}

When Cintsys is started, control is passed to the interpreter which,
after a few initial checks, allocates vectors for the memory of the
Cintcode abstract machine and the tally vector available for
statistics gathering.  The Cintcode memory is initialised suitably for
sub-allocation by {\tt getvec}, which is then used to allocate space
for the root node, the initial stack and the initial global vector.
The initial state shown in figure~\ref{f11initstack} is completed by
loading the object modules {\tt SYSLIB}, {\tt BLIB} and {\tt BOOT},
and initialising the root node, the stack and global vector.
Interpretation of Cintcode instructions now begins with the Cintcode
register {\tt PC}, {\tt P} and {\tt G} set as shown in the figure, and
{\tt Count} set to {\tt-1}.  The other registers are cleared.  The
first Cintcode instruction to be executed is the first instruction of
the body of the function {\tt start} defined in {\tt sysb/boot.b}.
Since no return link has been stored into the stack, this call of {\tt
start} must not attempt to return in the normal way; however, its
execution can still be terminated using {\tt sys(Sys\_quit,0)}.

The global vector and stack shown in figure~\ref{f11initstack} are
used by {\tt start} and form the running environment both during
initialization and while running the debugger.  The CLI, on the other
hand, is provided with a new stack and a separate global vector, thus
allowing the debugger to use its own globals freely without
interfering with the command language interpreter or running commands.
The global vector of 1000 words is allocated for the {\tt CLI} and
this is shared by the {\tt CLI} program and its running commands. The
stack, on the other hand, is used exclusively by the command language
interpreter since it creates a coroutine for each command it runs.

                                                            
\begin{figure}[tbh!]
\centerline{\includegraphics[width=131.0mm]{bfigs/f11initstack.png}}
\caption{\label{f11initstack}The initial state}
\end{figure}

Control is passed to the {\tt CLI} by means of the call {\tt
  sys(Sys\_interpret,regs)} which recursively enters the intepreter
from an initial Cintcode state specified by the vector {\tt regs} in
which that {\tt P} and {\tt G} are set to point to the bases of a new
stack and a new global vector for {\tt CLI}, respectively, PC is the
location of the first instruction of {\tt startcli}, and {\tt count}
is set to {\tt-1}.  This call of {\tt sys(Sys\_interpret,regs)} is
embedded in the loop shown below that occurs at the end of the body of
{\tt start}.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        { LET res = sys(Sys_interpret, regs)  // Call the interpreter
          IF res=0 DO sys(Sys_quit, 0)
          debug res               // Enter the debugger
        } REPEAT
\end{verbatim}
\end{samepage}


At the moment {\tt sys(Sys\_interpret,regs)} is first called, only
{\tt globsize}, {\tt sys} and {\tt rootnode} have been set in CLI's
global vector and so the body of {\tt startroot} must be coded with
care to avoid calling global functions before their entry points have
be placed in the global vector.  Thus, for instance, instead of
calling {\tt globin} to initialise the globals defined in {\tt BLIB},
{\tt SYSLIB} and {\tt DLIB}, the following code is used:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
      sys(Sys_globin, rootnode!rtn_blib)
\end{verbatim}
\end{samepage}

If a fault occurs during the execution of {\tt CLI} or a command that
it is running, the call of {\tt sys(Sys\_interpret,regs)} will return
with the fault code and {\tt regs} will hold the dumped Cintcode
registers.  A result of zero, signifying successful completion, causes
execution of Cintsys to terminate; however, if a non zero result is
returned, the debugger in entered by means of the call {\tt
debug(res)}.  Note that the Cintcode registers are available to the
debugger since {\tt regs} is a global variable.  When {\tt debug}
returns, the {\tt REPEAT}-loop ensures that the command language
interpreter is re-entered.  The debugger is briefly described in the
Chapter~\ref{debugging}.

On entry to {\tt startroot}, the coroutine environment is initialised
by setting {\tt currco} and {\tt colist} to point to the base of the
current stack which is then setup as the root coroutine.  The
remaining globals are the initialised and the standard input and
output streams opened before loading the {\tt CLI} program by means of
the following statement:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
      rootnode!rtn_cli := globin(loadseg("syscin/cli"))
\end{verbatim}
\end{samepage}

\noindent
The command language interpreter is now entered by the call {\tt
start()}.

\subsection{Quiet mode execution}

Normal execution expects standard input and output to be from the
keyboard and to the screen. This allows the user to interact with the
system by typing CLI commands. When started in this mode the system
outputs an initial message before entering the CLI to read and execute
user commands from the keyboard. It generates CLI prompts and echoes
keyboard input to the screen.

It is sometimes useful run BCPL programs non interactively in what is
called quiet mode. This is done by entering cintsys (or cintpos) with
the {\tt-q} option. This enters the BCPL system without generating the
initial message, it disables CLI prompts and does not echo keyboard
input. In this mode all standard output is explicitly written by the
program, except for possible error messages and debugging output.  As
an example, the program {\tt com/add2.b} which outputs the sum of
two integers read from standard input, can be run from a Linux shell
by either of the following two commands:
\smallskip
\begin{verbatim}
        echo "111 222" | cintsys -q -- add2
        cintsys -q -c add2 111 222
\end{verbatim}
\smallskip
Boh commands just output the result 333.

\section{Bootstrapping Cintpos}

Bootstrapping Cintpos is somewhat more complicated than bootstrapping
Cintsys since there are more resident modules of code, and the Cintpos
system structures and resident tasks must be set up.  Bootstrapping
starts when the {\tt cintpos} program is entered. It first decodes the
command arguments, possibly changing the Cintcode memory or tally
vector sizes. It then allocates these vectors, initialising every word
of the Cintcode memory with the value {\tt\#xDEADCODE}. It also
allocates a vector to hold counts of how many blocks of each requested
size have been allocated {\tt getvec} but not yet freed. It then
allocates and initialises the stack and global vector to be used by
{\tt BOOT}. The rootnode is then initialised, including the setting of
the fields: {\tt rtn\_boot} (holding the module {\tt boot}), {\tt
rtn\_klib} (holding the module {\tt klib}), {\tt rtn\_blib} (holding
the modules {\tt blib}, {\tt syslib} and {\tt dlib}) and {\tt
rtn\_sys} (holding the entry point to the function {\tt sys}).

The initial values of the Cintcode registers are now placed in the
register set {\tt bootregs}. The Cintcode interpreter is entered to
start execution from this initial state. If the interpreter returns a
non zero result, a message containing this value is written to the
standard output stream, and, if the {\tt rtn\_dumpflag} field of the
root node is {\tt TRUE}, the entire Cintcode memory is dumped to the
file {\tt DUMP.mem} in compacted form suitable for inspection by
commands such as {\tt dumpsys} or {\tt dumpdebug}.

\subsection{The Cintpos BOOT module}

The function {\tt start} in {\tt boot} is the very first BCPL compiled
code to be entered when Cintpos starts. On entry, the Cintcode
registers {\tt A}, {\tt B} and {\tt C} are zero, {\tt P} and {\tt G}
point to BOOT's stack and global vector, and {\tt ST} is set to 2,
indicating that we are in {\tt boot} and that interrupts are disabled.
The global vector has already been initialised to hold all the entry
points in {\tt boot}, {\tt klib}, {\tt blib}, {\tt syslib} and {\tt
dlib}, but the stack currently is filled entirely with the value
{\tt stackword=\#xABCD1234} except for its zeroth word which was set
by {\tt cintpos} to hold the stacksize. To improve the behaviour of
the standalone debugger, this stack is turned into a root coroutine
stack of the specified size, initialising the globals {\tt currco} and
{\tt colist} appropriately.

All console input and output within BOOT and the standalone debugger
is done using the standalone version of {\tt rdch} and {\tt wrch}, so
these globals are updated appropriately. BOOT next initialises the
variables used by the standalone debugger. These include the vectors
{\tt bpt\_addr}, {\tt bpt\_instr} and {\tt bpt\_dbgvars} which
respectively hold breakpoint addresses, breakpoint instructions that
have been overwritten by the {\tt BRK} instruction, and the vector of
the 10 standalone debugger variables {\tt V0} to {\tt V9}. These three
vectors are placed in the rootnode to make them accessible both to the
DEBUG task and to {\tt dumpdebug} when it is inspecting a system dump.

BOOT now creates and initialises a global vector and a stack to be
used during the further initialisation of the Cintpos system. The all
elements of the global vector are given values of the form {\tt
globword}(={\tt\#x8F8F0000})+$n$, except for the globals {\tt
globsize}, {\tt sys}, {\tt rootnode}, {\tt currco} and {\tt colist},
the last two being set to zero. Every element of the stack is set to
{\tt stackword} (={\tt\#xABCD1234}). The register set {\tt klibregs}
is initialised, giving zero to {\tt A}, {\tt B} and {\tt C}, the stack
and global vector pointers to {\tt P} and {\tt G}, the value one to
{\tt ST} to indicate execution is in KLIB and interrupts are disabled,
and the entry point {\tt startroot} in {\tt PC}. This register set is
then handed to a recursive call of the interpreter.  This inner call
is the one than performs the rest of the initialisation and enters the
normal execution of Cintpos.  In due course the interpreter will
return with a completion code which controls what BOOT should do next.

A completion code of zero signifies successfully completion and BOOT
causes the termination of {\tt cintpos}. A return code of -1 is
special, causing BOOT to re-enter the interpreter immediately. Its
purpose is to allow a running program to change which interpreter is
used. There are typically two interpreters: a slow one in which all
debugging aids are turned on, and a fast one in which most aids are
turned off. The call {\tt sys(Sys\_interpret,~regs)} selects the fast
interpreter if the {\tt count} register in {\tt regs} is -1, otherwise
it selects the slow interpreter. The return code -2 allows a running
program to invoke the {\tt dumpmem} mechanism to write the file
DUMP.mem representing the current state of the entire Cintcode
memory. All other completion codes causes BOOT to invoke the standalone
debugger.

BOOT cunningly places a private version of the {\tt sys} function in
its global vector so that, even if a breakpoint is set in the public
version of {\tt sys}, BOOT and in particular the standalone debugger
can continue to work as normal. When BOOT invokes the interpreter for
the first time execution begins at the start of {\tt startroot} which
is described in the next section.

\subsection{\tt startroot}

This function creates the Cintpos running environment and loads all
the resident system tasks. Finally it enters the Cintpos scheduler
which, in turn, gives control to the Idle task which sends a packet to
the root CLI task. After some initialisation, this issues the first
CLI prompt inviting the user to type in a command. Knowledge of the
underlying structures used by Cintpos is key to understanding how
Cintpos works. They are described in this section in the order in
which {\tt startroot} creates them.

{\tt startroot} is entered by the recursive call of {\tt interpret}
from BOOT with a new stack and a different global vector from that
used by BOOT. If the interpreter subsequently detects a fault it
returns to BOOT's running environment giving control to the
interactive debugger allowing the user to inspect the stack and global
vector that were current at the time the fault.

Althought {\tt startroot} has three formal parameters { \tt fn}, {\tt
size} and {\tt c}, it was entered in a non standard way and these have
not been given values. However, the base of {\tt startroot}'s stack is
at @fn-3. This points to the zeroth element holding the stack size
with all other elements are already set by BOOT to {\tt stackword}
(\verb|#xABCD1234|). This stack is turned into a coroutine stack by
updating its bottom six elements appropriately.  Care is taken to
ensure that the code that performs this initialisation is not itself
using the stack locations that it is updating. This is one of the
reasons why {\tt startroot} was given three parameters.

The function {\tt rootcode} is now called to create the Cintpos
resident structures. At this moment the base of the global vector is
at \verb|@globsize| (=Global 0), all its elements are filled with
words of the form {\tt globword+\em n} (=\verb|#8F8F0000|{\tt+\em n}),
except for {\tt globsize} which holds the upper bound of the global
vector, {\tt sys} which holds the entry point of the {\tt sys}
function, {\tt rootnode} which points to the rootnode, and {\tt
currco} and {\tt colist} which both point to the newly created
coroutine stack. The other globals are now initialised by two calls
of \verb|sys(Sys_globin,...)|.

Cintpos has two vectors {\tt tasktab} and {\tt devtab} that provide
access to all Cintpos tasks and devices. These are allocated and
cleared, and pointers to them are placed in the rootnode.

The resident Cintpos devices are now created. These have device
identifiers {\tt-1}, {\tt-2} and {\tt-3} corresponding to the clock,
the keyboard and the screen. Most Cintsys devices are implemented
using separate threads of the underlying operating system. Such
devices have device control blocks (DCBs) held their entries in {\tt
devtab}. A DCB has fields used for communication between its device
thread and the interpreter. One of these is the work queue of packets
sent by client tasks but not yet processed by the device. It has been
found that interaction with some device threads is too slow to be
satisfactory and so have been replaced by an implementation based on
polling by the interpreter. This currently applies to the clock and
screen devices. As far as the user is concerned, these devices still
have the same indentifiers and still work as before but are faster.
An entry in {\tt devtab} points to a DCB. Devices not using the
polling mechanism use threads of the host operating system, other
devices are handled entirely by the interpreter thread.  The only
resident devices currently using a separate threads are the keyboard
and TCP devices. Device threads are created using the kernel function
{\tt createdev} defined in {\tt sysb/klib.b}, and the C code for the
resident device threads can be found in {\tt sysc/devices.c}.

The Cintcode abstract machine can receive interrupts. The mechanism is
as follows. If a device wishes to interrupt the interpreter it sets
the variable {\tt irq} to {\tt TRUE}, and just before the interpreter
starts to execute an instruction, if the Cintpos {\tt ST} register is
zero (indicating that interrupts are enabled), it saves the current
Cintpos registers and enters the interrupt service routine using the
register set in {\tt isrregs}. The interrupt service routine has its
own stack but shares the same global vector a the Cintpos kernel. It
always starts execution at the start of the function {\tt irqrtn} with
Cintcode register {\tt ST} set to 3 to indicate that an interrupt is
being serviced. The interrupt sevice routine may return control to the
interrupted task or it may enter the scheduler if another task
deserves to gain control.

Before creating the resident tasks, {\tt startroot} initialises a few
more rootnode fields. These are {\tt rtn\_tcblist} and {\tt
rtn\_crntask} both set to zero since there are currently no Cintpos
tasks, {\tt rtn\_blklist} set to the start of the memory block list
used by {\tt getvec} and {\tt freevec}, {\tt rtn\_clkintson} set to
{\tt FALSE} to globally disable interrupts, {\tt rtn\_clwkq} set to
zero representing an empty list of packets for the clock device, and
{\tt rtn\_info} set to a cleared table of 50 elements.

The resident tasks are now created using suitable calls of {\tt
createtask}. Each time {\tt createtask} is called it allocates a task
control block (TCB) giving it the next available task identifier and
updating the appropriate entry in {\tt tasktab} to point to it. Such
tasks are initially given a state of \verb|#b1100| indicating that
they are DEAD, not HELD and have no packets in the work queue.  The
first task to be created is a special one called Idle whose body is in
{\tt cin/syscin/idle} and although {\tt createtask} will have chosen
identifier one for it, this must be replaced by zero and it entry in
{\tt tasktab} removed. It is given a startup packet and an initial
state of \verb|#b1101| indicating it is DEAD, not HELD but has a
packet and so can be given control by the scheduler when it is run.

Six more resident tasks are now created, all have state \verb|#b1100|.
They are the root command language interpreter that initially waits
for commands from the keyboard, and interactive debugging task, the
console handler providing communication between the keyboard and
tasks, the file handler providing access to disk files, the mailbox
handler that provides a mechanism that lets tasks send and receive
short messages via named mailboxes and the TCP handler providing
TCP/IP communication.

Just after Cintpos starts up the {\tt status} command will output the
following.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
Task  1: Root_Cli         running CLI         Loaded command: status     
Task  2: Debug_Task       waiting DEBUG      
Task  3: Console_Handler  waiting COHAND     
Task  4: File_Handler     waiting FH0        
Task  5: MBX_Handler      waiting MBXHAND    
Task  6: TCP_Handler      waiting TCPHAND    
\end{verbatim}
\end{samepage}

Once the kernel structure and all the resident tasks have been set up,
the system can be started by entering the scheduler which is a
function called {\tt srchwk} defined in {\tt sysb/klib.b}. It take one
argument which is a pointer to the highest priority TCB that could
possibly run. It searches through the chain of TCBs that are linked in
decreasing priority order looking at only the status field of
each. This field is sufficient to tell whether the corresponding task
can run or not. It has 4 bits {\tt IWHP}. The {\tt I} bit is a 1 if
the task has been interrupted in which case its Cintcode registers will
be packed elsewhere in the TCB. The {\tt W} bit is a 1 if the task is
suspended in {\tt taskwait} waiting for a packet to arrive from
another task or a device. The {\tt H} bit is 1 if the task is in HOLD
state indicating that it cannot run even if it otherwise would be
ready to do so, and the {\tt P} bit is a 1 if the tasks's work queue
is not empty. A task cannot be both interrupted and waiting for a
packet and the setting of both the {\tt I} and {\tt W} bits have a
special meaning, namely that the task is in DEAD state having no
runtime stack or global vector. There are thus 16 posible states a
task can have of which only six indicate that it is runnable, they
are as follows.

\begin{description}

\item{\verb|#b0000|}\\
This task is runnable but has no packet on its work queue. It is
either the current task or it gave up control voluntarily by for
instance sending a packet to a higher priority task. When it next
gains control it will immediately return from the function that caused
it to give up control.

\item{\verb|#b0001|}\\
This is just like the case above except there is a packet on its work
queue.

\item{\verb|#b0101|}\\
This indicates that the task is waiting for a packet and that one has
arrived. It is thus runnable and when given control the first packet
on its work queue will be dequeued and returned as the result of the
{\tt taskwait} call that caused its suspension.

\item{\verb|#b1000|}\\
This indicates the task is in interrupted state with an empty work queue.
It is thus runnable and when given control it will resume execution using
the Cintcode register values saved in the TCB when it was interrupted.


\item{\verb|#b1001|}\\
This indicates the task is in interrupted state with a non empty work queue.
It is thus runnable and when given control it will resume execution using
the Cintcode register values save in the TCB when it was interrupted.

\item{\verb|#b1101|}\\
This is a task in DEAD state (with no stack or global vector) but it
now has a startup packet on its work queue. It is thus runnable and
when given control will be initialised with a new stack and global
vector and its main function {\tt start} in global variable 1 will be
called with the startup packet as its first argument. This packet will
have been dequeued.


\end{description}




\section{\label{commands}Commands}

This section describes the Command Language Interpreter commands whose
source code can be found in either {\tt cintcode/com} or {\tt
cintpos/com}.  The {\tt rdargs} argument format string for each
command is given.

\bigskip
\noindent
{\bf abort \tt NUMBER}\IMPL{y}{y}{y}
\indent\nopagebreak
The command: {\tt abort} $n$ calls the {\tt BLIB} function {\tt abort}
with argument $n$. If $n$ is zero, this causes a successful return
from the BCPL system. If $n$ is non zero, the interactive debugger is
entered with fault code $n$. The default value for $n$ is {\tt99}.
The interactive debugger is described in section~\ref{debugging}.

\bigskip
\noindent
{\bf adjclock \tt OFFSET}\IMPL{y}{y}{y}
\indent\nopagebreak
The syntax of the {\tt OFFSET} argument is [-][$h$][:$m$], that is: an
optional minus sign, followed by an optional number of hours, possibly
followed by :$m$ to specify a number of minutes. The offset is
converted into a signed integer representing the number of minutes to
be added to the time of day as supplied by the system. If {\tt
adjclock} is not given an argument, it just outputs the current
offset.

\bigskip
\noindent
{\bf alarm \tt AT/A,MESSAGE}\IMPL{n}{y}{n}
\indent\nopagebreak
This command is only available under Cintpos. Its first parameter has
the format: {\tt [+][[hours:]minutes:]seconds}.  If {\tt+} is present
the time is relative to now. The command suspends itself until the
specified time, then outputs the time followed by the message.
Typical usage is as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        run alarm +3:30 "Your time is up!"
\end{verbatim}
\end{samepage}

\noindent
After three and a half minute a message such as the following will
appear.


\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        *** Alarm: time is 15:13:14 - Your time is up!
\end{verbatim}
\end{samepage}

\bigskip
\noindent
{\bf append \tt FROM,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command appends the {\tt FROM} file on to the end of the {\tt TO}
file.  If the {\tt TO} file does not initially exist, an empty one is
created.


\bigskip
\noindent
{\bf bbcbcpl \tt FROM/A,TO/K,REPORT/K,NONAMES/S,MAX/S,SECTLEN/S}\\
\IMPL{y}{y}{y}
\indent
This invokes a reconstruction of the BCPL compiler for the BBC
Microcomputer marketed by my brother's company RCP in the early
1970s. The {\tt FROM} argument specifies the BCPL source file. The {\tt
  TO} argument specifies the desination file for the compiled 16-bit
Cintcode. The {\tt REPORT} argument specifies a file to hold error
messages. The {\tt NONAMES} argument causes the compiler not to embed
function names in the compiled code. The {\tt MAX} argument has no
effect in this version of the compiler and {\tt SECTLEN} controls
whether the length of a section of compiled code includes it length in
its first word.

This reconstruction was created to possibly help reconstruct the BBC
Domesday Project that ran on the BBC Microcomputer using a Philips
12" laser disc. Related commands are {\tt mapcode} and {\tt
  prbbcocode}. For more information, see {\tt bcplprogs/bbcmicro/} in
  the standard BCPL distribution.


\bigskip
\noindent
{\bf bbcbcpl32 \tt FROM/A,TO/K,REPORT/K,NONAMES/S,MAX/S,SECTLEN/S}\\
\IMPL{y}{y}{y}
\indent
This command is similar to {\tt bbcbcpl} but generates 32-bit Cintcode
suitable for the current BCPL Cintcode system. The BBC BCPL programs
may need minor changes needed because the BCPL word length has
increased from 16 to 32 bits.

This command is now obsolete since using bbc2bcpl is a more satisfactory
way to run BBC BCPL on the modern BCPL Cintcode system.

bbcbcpl32 will soon be deleted.

\bigskip
\noindent
{\bf bbc2bcpl \tt FROM/A,TO/K,HARD/S,EQCASES/S,T64/S,-h/S}
\IMPL{y}{y}{y}
\indent

This command convert the BBC BCPL program given by {\tt FROM} to a
destination file given by {\tt TO}. The result can be compiled and run
under the modern BCPL Cintcode system. {\tt HARD} causes the program
to abort on every detected error, {\tt EQCASES} toggles whether the
case of letters in reserved word and identifiers are ignored. By
default the case of letters is ignored. Several minor replacements are
made, such as {\tt LOGAND}, {\tt LOGOR}, {\tt LSHIFT}, {\tt EQ} and
{\tt LE} are replaved by {\tt\&}, {\tt|}, {\tt<<}. {\tt=} and {\tt<=}.
Missinf close sections brackets are automatically inserted with the
correct indentation when multiple sections are closed by a tagged
closing bracket. All dots in identediters are replaced by underscores.
The cases of letters used in identifiers is modified to agree with the
way each identifier was written when first encountered. To do this the
program reads {\tt GET} files but leave the {\tt GET} directives
unchanged.


\bigskip
\noindent
{\bf bcpl \tt FROM/A,TO/K,ERR/K,SIZE/K/N,NONAMES/S,}\\
\hspace*{2em}{\tt OENDER/S,EQCASES/S,BIN/S,XREF/S,GDEFS/S,HDRS/K,}\\
\hspace*{2em}{\tt GB2312/S,UTF8/S,SAVESIZE/K/N,HARD/S,T16/S,T32/S,T64/S,}\\
\hspace*{2em}{\tt DEFS/K,NOSELST/S,MAP/K,LIST/K,-h/S,-d/N}\IMPL{y}{y}{y}
\indent\label{bcplcommand}\nopagebreak
This invokes the BCPL compiler. The {\tt FROM} argument specified the
name of the source file to be compiled. If the {\tt TO} argument is given,
the compiler generates code to the specified file. Without the {\tt
TO} argument the compiler will output the OCODE intermediate form to
the file {\tt ocode} as a compiler debugging aid, ready to be printed
in a readable form by the command {\tt procode}.
The {\tt ERR} argument redirects the standard output
to a named file. The {\tt SIZE} argument specified the size of the
compiler's work space. The default is 200,000 words. The {\tt NONAMES}
switch causes the compiler not include section and function names in
the compiled code.  
{\tt OENDER} causes code to be
generated for a machine with the opposite endianess of the machine on
which the compiler is running.  {\tt EQCASES} causes all identifiers
to be converted to uppercase during compilation. This allows very old
BCPL programs to be compiled.  {\tt BIN} causes the target Cintcode to
be in binary rather than the ASCII encoded hexadecimal normally used.
The {\tt XREF} option causes a line to be output by the compiler for
each non local identifier occurring in the program. A typical such
line is as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        all G:201 LG queens.b[9] all&~(ld|col|rd)
\end{verbatim}
\end{samepage}

\noindent
It shows that the variable {\tt all} was declared as global variable
201 and its was loaded in the compilation of statements on line 9 of
the program {\tt queens.b} and the context of its use was:
\verb/all&~(ld|col|rd)/. These lines can be filtered and sorted to
form a cross reference listing of a program. See, for instance, the
file {\tt BCPL/cintcode/xrefdata} or {\tt Cintpos/cintpos/xrefdata}.
If both {\tt ERR} and {\tt XREF} are specified the xref data is appended
to the ERR stream. This allows the xref data generated by several
separate compilations to be concatenated. The resulting file can be filtered
and sorted by the {\tt sortxref} command. Typical usage is as follows:

\medskip
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        delete -f rawxref
        c compall "ver rawxref xref"
        sort rawxref to xrefdata
        delete rawxref
\end{verbatim}
\end{samepage}

\medskip
\noindent
For other examples see {\tt cintcode/Makefile}.

The {\tt GDEFS} switch is a debugging aid to output the global numbers
of any global function defined in the program. For example:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        bcpl gdefs com/bench100.b to junk
\end{verbatim}
\end{samepage}

\noindent
generates the following output:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
BCPL (3 July 2007)
G  1 = start
G259 = trace
G260 = schedule
G261 = qpkt
G262 = wait
G263 = holdself
G264 = release
G270 = idlefn
G271 = workfn
G272 = handlerfn
G273 = devfn
Code size = 1436 bytes
\end{verbatim}
\end{samepage}

The {\tt UTF8} and {\tt GB2312} options specify the default encoding
for extended characters in string and character constants. This
default can be overridden in individual constants using the \verb|*#u|
and \verb|*#g| escape sequences, as described on
page~\pageref{stringescapes}.

The {\tt SAVESIZE} option allows the user to specify the number of
words in the argument stack used to hold function return information.
The default value is three making room for the old P pointer, the
return address and the entry point of the current function. When
compiling into native code using the Sial mechanism, the save space
size may be different, since, for instance, some or all of this
information may be stored in the hardware (SP) stack.

The {\tt HARD} options causes both syntax and translation phase errors
to call {\tt abort(100)}. This is useful in commands such as: {\tt
c~compall~hard} allowing each error in a long sequence of compilations
to be inspected separately.

The arguments {\tt T16}, {\tt T32} and {\tt T64} specify the BCPL word
length of the target code. Note that when using a compiler with a 32
bit word length, manifest constants are calculated using 32 bit
integer and floating point arithmetic. If compiling for a 64 bit
target integers will be limited to a 32 bt bit range and floating
point constants will only have a precision of about 6 of 7 decimal
digits. But note that many such constants will still be represented
precisely. To obtain the full range and precision on a 64 bit target,
a compiler with a 64 bit word length must be used.

The argument {\tt DEFS} gives a list of conditional compilation option
names consisting of letters, digits, underline and dot, separated by
plus signs or any other characters not allowed in option names. These
options are declared at the start of compilation of every BCPL
section.

The option {\tt NOSELST} causes the compiler to avoid using the Ocode
instructions {\tt SELLD} and {\tt SELST} when compiling the {\tt OF}
operator. Less efficient code is compiler using shifts and logical
instructions. This option causes the {bcpl2sial} command not to use
the new SIAL function codes {\tt selld}, {\tt selst} and {\tt xselst},
enabling older Sial codegenerators to continue to work.  The option
{\tt-h/S} outputs a message about the current version of the compiler.
The option {\tt-d/N} causes the compiler to generate debugging
information at compile time. To what is available try the shell
command: \verb|bcpl com/fact.b to junk -d 99|. This will output
the following:

\smallskip

\begin{samepage}
{\small
\begin{verbatim}
  Summary of the valid -d values:

  0  No debugging output
  1  Output just the lexical tokens
  2  Output the parse tree before generating the Ocode
  3  Output the parse tree after generating the Ocode
  4  Output the Ocode to file: ocode as a sequence of integers
     suitable for printing using the procode command
  5  Output the Ocode in a readable form
  6  Output the compiled code (Cintcode or machine code)
  7  Output the Ocode operators and the compiled code
  8  Output the Ocode operators, the compiled code
     and the simulated stack
  9  Output the Ocode operators, the compiled code
     and the list of label references
  10 Output the Ocode operators, the compiled code
     and the list of static values
  99 Output this list
\end{verbatim}
}
\end{samepage}

\smallskip
\noindent
Now try the same command, replacing 99 with each value from 1 to 10.

\bigskip
\noindent
{\bf bcpl2sial \tt FROM/A,TO/K,VER/K,SIZE/K/N,NONAMES/S,}\\
\hspace*{2em}{\tt OENDER/S,EQCASES/S,BIN/S,XREF/S,GDEFS/S,HDRS/K,}\\
\hspace*{2em}{\tt GB2312/S,UTF8/S,SAVESIZE/K/N,HARD/S,T16/S,T32/S,T64/S,}\\
\hspace*{2em}{\tt DEFS/K,NOSELST/S,MAP/K,LIST/K,-h/S,-d/N}\IMPL{y}{y}{y}
\indent\label{bcplsialcommand}\nopagebreak
This command compiles a BCPL program into the internal assembly
language Sial which is designed as a low level intermediate target
code for BCPL and is described in Section~\ref{sial}. The command {\tt
  sial-sasm}, described below, can be used to convert Sial into a
human readable form and various commands, such as {\tt sial-386}, {\tt
  sial-alpha} and {\tt sial-arm} will convert Sial to assembly
language for corresponding architectures. The {\tt bcpl2sial} command
uses the same front end as {\tt bcpl} and so takes the same command
arguments as the {\tt bcpl} command.

\bigskip
\noindent
{\bf bcplxref \tt  FROM/A,TO/K,PAT/K}\IMPL{y}{y}{y}
\noindent\nopagebreak
This command outputs a cross reference listing of the program given
by the {\tt FROM} argument. This consists of a list of all identifiers
used in the program each having a list of line numbers where the
identifier was used and a letter indicating how the identifier was
declared. The letters have the following meanings:

\begin{center}
\begin{tabular}{ll}
 V & Local variable\\
 P & Function or Routine\\
 L & Label\\
 G & Global\\
 M & Manifest\\
 S & Static\\
 F & FOR loop variable\\
\end{tabular}
\end{center}
 
The {\tt TO} argument can be used to redirect the output to a file,
and the {\tt PAT} argument supplies a pattern to restrict which names
are to be cross referenced. Within a pattern an asterisk will match
any sequence of characters, so the pattern {\tt a*b*} will match
identifiers such as {\tt ab}, {\tt axxb}or {\tt axbyy}. Upper and
lower case letters are equated. This command has largely been superceded
by the {\tt xref} option in the {\tt bcpl} command and the related
{\tt sortxref} command.



\bigskip
\noindent
{\bf bench100}\IMPL{y}{y}{y}
\indent\nopagebreak
This is a simple benchmark program used to test the efficiency
of systems implementation languages.

\bigskip
\noindent
{\bf bgpm \tt  FROM,TO/K,UPB/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This is an implementation of Christopher Strachey's GPM
macrogenerator.  It takes input from the {\tt FROM} file if specified,
otherwise it reads from the standard input stream. The {\tt TO}
argument specifies the file to receive the macrogenerated result,
otherwise this is sent to the standard output stream. The {\tt UPB}
argument specified the amount of memory that {\tt bgpm} may use.

A macro call is enclosed in square brackets (\verb|[| and \verb|]|)
and contains arguments separated by backslash characters (\verb|\|).
The arguments are macro expanded as they are read in. To avoid macro
expansion text can be enclosed within nested quotation marks (\verb|{|
and \verb|}|). On reaching the close square bracket at the end of a
macro call, the zeroth argument is looked up in the environment of
defined macros and macrogeneration continues from the beginning of its
value. When the end of this value is reached the expansion of the call
is complete and macrogeneration continues from just after the closing
square bracket. While a macro call is being expanded, a parameter of
the form {\tt\^\em n} is replaced by a copy of the $n^{th}$ argument
of the current call. The number $n$ is given as a sequence of decimal
digits. The character {\tt'`'} introduces a comment consisting of all
remaining character of the current line followed by all white space
characters including newlines up to but not including the next non
white space character. The following macros are predefined.

\medskip
\noindent
{\verb|[def\|\em name\verb|\|\em value\verb|]|}\\
\indent
This causes a macro with the given name and value to be declared.

\medskip
\noindent
{\verb|[set\|\em name\verb|\|\em value\verb|]|}\\
\indent
This updates a named macro with a new value which may be truncated if
necessary.

\medskip
\noindent
{\verb|[eval\|\em expression\verb|]|}\\
\indent
This evaluate the given integer expression consisting of numbers and
the numeric operators {\tt *, /, \%, + \rm and \tt-}. Parentheses may
be used for grouping and spaces may appear anywhere except within
numbers.

\medskip
\noindent
{\verb|[lquote|\verb|]|}\\
{\verb|[rquote|\verb|]|}\\
\indent
These macros expand to the quotation marks \verb|{| and \verb|}| respectively.

\medskip
\noindent
{\verb|[eof|\verb|]|}\\
\indent
This macro generates the end of file symbol and can be used to terminate
input from the standard input stream.

\medskip
A simple definition and call is the following.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
[def\xxx\{arg0 is ^0, arg1 is ^1 and arg2 is ^2}]
[xxx\yyy\zzz]
\end{verbatim}
\end{samepage}

\noindent
This would generate:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
arg0 is xxx, arg1 is yyy and arg2 is zzz
\end{verbatim}
\end{samepage}




\noindent
For an extremely obscure example see: {\tt BCPL/cintcode/perm.bgpm}.

\bigskip
\noindent
{\bf bin-hex \tt FROM/A,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This outputs the bytes of the {\tt FROM} in hex. For instance, if
the file {\tt xxx} was

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
ABCDEFGH
12345678
\end{verbatim}
\end{samepage}

\noindent
Then the command {\tt bin-hex xxx} would generate

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
 41 42 43 44 45 46 47 48 0A 31 32 33 34 35 36 37
 38 0A
\end{verbatim}
\end{samepage}

\noindent
Unless {\tt TO} is specified output is sent to the terminal.
 
\bigskip
\noindent
{\bf bin-x8 \tt FROM/A,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This outputs the words of the {\tt FROM} in hex. For instance, if
the file {\tt xxx} was

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
ABCDEFGH
12345678
\end{verbatim}
\end{samepage}

\noindent
Then the command {\tt bin-x8 xxx} would generate

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
44434241 48474645 3332310A 37363534 00000A38 
\end{verbatim}
\end{samepage}

\noindent
The default {\tt TO} file name is {\tt JUNK}.
 

\bigskip
\noindent
{\bf bits2wav \tt FROM,TO/K,B/N,S/N,A/N,D/N,T/S}
\IMPL{y}{y}{y}
\indent\nopagebreak
This commands converts a bit stream file generated by the {\tt raster}
command to a {\tt.wav} sound file. {\tt FROM} and {\tt TO} specify the
source and destination files. {\tt B} specified the bit rate in bits
per second. {\tt S} specifies the {\tt.wav} sample rate which should
be 11025, 22050 or 44100. {\tt A} and {\tt D} control the signal
filtering and {\tt T} turns on tracing as a debugging aid. The default
{\tt FROM} file is {\tt RASTER.bits}. The default {\tt TO} file is
{\tt RASTER.wav} and the default sample rate is 11025 samples per
second.


\bigskip
\noindent
{\bf bmake \tt TARGET,FROM/K,TO/K,-m/S,-l/S,-p/S,-r/S,-s/S,-c/S,-d/S}\\
\IMPL{y}{y}{n}
\indent\nopagebreak
This command provides an approximation the {\tt make} command found in
other systems. It uses a makefile (normally {\tt bmakefile}) to
generate a CLI sequence of commands to bring a specified target up to
date. The makefile is expanded using the BGPM macrogenerator and
parsed to form a set of pattern rules and explicit rules. Each rule
has a target, an optional set of items on which the target depends and
a possibly empty CLI command sequence to execute if the target need to
be brought up to date.

Pattern rules generate explicit rules when needed. They contain
parameters of the form {\tt<\em tag\tt>}. Within a pattern all tags
must be the same and must be declared in the target of the rule.

The optional first argument ({\tt TARGET}) is normally a file name and
specifies the target to make. If no target is specified, the target of
the first rule is used. The optional {\tt FROM} argument specified the
makefile name. The default makefile is {\tt bmakefile}. The optional
{\tt TO} argument specifies where the output is to be sent.

The {\tt-m} argument causes {\tt bmake} to output the makefile file
after macrogeneration. The {\tt-l} argument outputs the makefile as a
sequence of lexical tokens. The {\tt-p} argument outputs the set of
rule patterns.  The arguments {\tt-r} and {\tt-s} output the explicit
rules before and after the application of the rule patterns,
respectively. The {\tt-c} argument outputs the sequence of commands
required to bring the target up to date.  The {\tt-d} argument
generates a debugging trace of the execution of {\tt bmake}.


The BGPM macrogenerator is described elsewhere, but the version use in
{\tt bmake} uses the following special characters:

\medskip
\begin{center}
\begin{tabular}{l|l}
\verb|%| & \parbox[t]{100mm}{Comment - skip all characters
                             until a non white space character
                             on a later input line.}\\
\verb|[| & \parbox[t]{100mm}{Start of a new macro call.}\\
\verb|!| & \parbox[t]{100mm}{Argument separator in macro calls.}\\
\verb|#| & \parbox[t]{100mm}{Argument item prefix.}\\
\verb|]| & \parbox[t]{100mm}{End of macro argument list.}\\
\verb|{| & \parbox[t]{100mm}{Open quote character.}\\
\verb|}| & \parbox[t]{100mm}{Close quote character.}\\
\end{tabular}
\end{center}

\medskip
\noindent
A typical macro definition and call is as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
[def!xxx!{This output results from the call {[xxx!}#1{]}}]
[xxx!yyy]
\end{verbatim}
\end{samepage}

\noindent
This would generate:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
This output results from the call [xxx!yyy]
\end{verbatim}
\end{samepage}

\noindent
The syntax of {\tt bmake} rules is as follows:

\medskip
{\em target-item \tt<= \em item \tt... \em item \tt<< \em command-sequence \tt>>}

\medskip
\noindent
Every rule must have a target item and a body consisting of a possibly
empty command sequence enclosed in \verb|<<| and \verb|>>| brackets.
The command-sequence is an arbitrary sequence of characters not
containing \verb|>>|.  The item list may be empty and, if so, the
symbol \verb|<=| may be omitted.  White space including newlines are
allowed anywhere between items.

\noindent
Pattern rules contain parameter of the form {\tt<\em tag\tt>}
as in:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
cin/<f> <= com/<f>.b g/hdr.h << c bc <f> >>
\end{verbatim}
\end{samepage}

\noindent
Such rules are only used when there is no explicit rule for a given
target. When a rule pattern is applied all occurrences of its
parameter are replaced by the text that allowed the target item to
match the required target.  So if cin/echo must be brought up to date
and has no explicit rule, the above pattern will automatically add the
following explicit rule to the set:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
cin/echo <= com/echo.b g/hdr.h << c bc echo >>
\end{verbatim}
\end{samepage}

\noindent
A target is out of date if it does not exist or if any of the items it
depends on are out of date or have a modify dates later than that of
the target. A target is brought up to date by, first, bringing the
items it depends on up to date and then executing the CLI command
sequence given by the body.

Items may consist of any sequence of characters not including
\verb|%|, \verb|[|, \verb|!|, \verb|]|, \verb|{|, \verb|}|, \verb|=|,
or white space, and \verb|<| and \verb|>| may only appear in
parameters.

In normal use, {\tt bmake} generates a command-command file to bring the
target up to date and then returns to the CLI to cause this file to be
executed.  The {\tt-c} option allows the command-command file to be
inspected without execution.



\bigskip
\noindent
{\bf bounce}\IMPL{n}{y}{n}
\indent\nopagebreak
This command is part of the bounce demonstration that is
only available under Cintpos. It is normally invoked by the
command: {\tt run bounce} which creates a new CLI task and then
enters the {\tt bounce} program whose main loop is:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        qpkt(taskwait()) REPEAT
\end{verbatim}
\end{samepage}

\noindent
which repeatedly suspends the task until a packet is received then
immediately returns it to the sender. Packets are normally sent to
the bounce task using the {\tt send} command, described below.


\bigskip
\noindent
{\bf break \tt TASK/A,A/S,B/S,C/S,D/S,E/S,ALL/S}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command is used to break the normal execution of a
specified task. The first argument gives the task number and the
remaining arguments specify which flags to set. If no flags are
specified flag B is set. If {\tt ALL} is specified all the flags from
A to E are set.

\bigskip
\noindent
{\bf c \em command-file arguments}\IMPL{y}{y}{y}
\indent\nopagebreak
The {\tt c} command allows a file of commands to be executed as though
they had just been typed in. The argument {\em command-file} gives the
name of the file containing the command sequence. It first looks in
the current directory then the directories specified by the scripts
environment variable whose name is in the {\tt rtn\_scriptsvar} field
of the rootnode, and finally, if that fails, it looks in the directory
specified by the root environment variable whose name is in the {\tt
rtn\_rootsvar} field of the rootnode.

Unless explicitly changed, the characters '{\tt=}', '{\tt<}',
'{\tt>}', '{\tt\$}' and '{\tt.}' have special meanings within a
command command.  A dot '{\tt.}' at the start of a line starts a
directive which can specify the command command's argument format, or
replace one of the special character with an alternative.  There are
six possible directives as follows:

\begin{center}
\begin{tabular}{lll}
{\tt.KEY} or {\tt.K} & {\em str} & Argument format string.\\
{\tt.DEFAULT} or {\tt.DEF} & {\em key value} & Give {\em key} a default value,
                                               optionally, {\tt =} is\\
                           &   & allowed between the {\em key} and {\em value}.\\ 
{\tt.BRA} & {\em ch} & Use {\em ch} instead of {\tt<}\\
{\tt.KET} & {\em ch} & Use {\em ch} instead of {\tt>}\\
{\tt.DOLLAR} & {\em ch} & Use {\em ch} instead of {\tt\$}\\
{\tt.DOT} & {\em ch} & Use {\em ch} instead of {\tt.}\\
\end{tabular}
\end{center}

All directives must occur at the start of the command file.  The
{\tt.KEY} directive specifies a format string of the form used by {\tt
rdargs} (see page~\pageref{rdargs}) that describes what arguments can
follow the command file name.  The {\tt.DEFAULT} directive specifies
the default value that a specified key should have if the
corresponding argument was omitted.  The remaining directives allow
the special characters to be changed.

The command sequence occurs after all the directives and may contain
items of the form {\tt<}{\em key}{\tt\$}{\em value}{\tt>} or
{\tt<}{\em key}{\tt>} where {\em key} is one of the keys in the
format string and {\em value} is a default value. Such items are
textually replaced by its corresponding argument or a default
value. If {\tt\$}{\em value} is present, this overrides (for this item
only) any default that might have been given by a {\tt.DEFAULT}
directive.

\bigskip
\noindent
{\bf casech \tt FROM/A,TO/A,DICT/K,U/S,L/S,A/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command systematically converts all reserved words of a BCPL
program to upper case and changing all identifiers to upper case ({\tt
  U}), lower case ({\tt L}, or in the form given by a specified
dictionary ({\tt DICT}). The {\tt A} switch causes all letters including
those in strings to be converted to upper case.


\bigskip
\noindent
{\bf changepri \tt TASK/N/A,PRI=PRIORITY/N}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command changes the priority of the specified task to a
specified value. If two arguments are given the first identifies the
task and the second the new priority. If only one argument is given it
is treated as the new priority of the current task. A Cintpos priority
can be any positive integer but there is the restiction that no two
tasks can have the same priority.

\bigskip
\noindent
{\bf checksum \tt FROM/A,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command calculates a check sum for the file specified by the {\tt FROM}
argument, sending the result to the file specified by the {\tt TO}
argument.



\bigskip\noindent
{\bf cmpltest}\IMPL{y}{y}{y}
\indent\nopagebreak
This is a test program that checks for errors in the BCPL compiler and
Cintcode interpreter.

\bigskip\noindent
{\bf cobench}\IMPL{y}{y}{y}
\indent\nopagebreak
This is a benchmark program to test the efficiency of coroutines.

\bigskip\noindent
{\bf cobounce}\IMPL{y}{y}{y}
\indent\nopagebreak
This is a simple coroutine benchmark that bounces a message between
two coroutines. On my 1.66Ghz Pentium laptop it outputs the following:

\smallskip
{\small
\begin{verbatim}
0.000> cobounce
Calling the bounce coroutine 10000000 times
About 7812500 coroutine changes per second
done
2.560> 
\end{verbatim}
}

\smallskip
\noindent
This shows that transferring control between coroutines is about 12
time faster than transferring control between Cintpos tasks as
demonstrated by the {\tt send} command described below.


\bigskip\noindent
{\bf compare \tt FILE1/A,FILE2/A,TO/K,OPT/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command compares two files outputting a description of how they
differ to the {\tt TO} file if specified, or to standard output if
not.  The {\tt OPT} string consists of items of the form {\tt W\em n},
{\tt M\em n} and {\tt R\em n}, separated by spaces or commas. Each {\em n}
is a number greater than zero. {\tt W\em n} means truncate all input lines
to no more than {\em n} characters. {\tt M\em n} search for up to {\em n}
mismatching lines. {\tt R\em n} means that {\em n} lines must match before
synchronisation is restored after a mismatch.

\bigskip\noindent
{\bf cosim \tt-n/n,-s/n,-p/n,-r/n,-t/s}\IMPL{y}{y}{y}
\indent\nopagebreak
This is a demonstration program showing how to write a discrete event
simulator using coroutines, and it is also be used as a benchmark.
Its arguments can set the variables {\em n}, {\em s}, {\em p} and {\em
r} that configure the test, and the {\tt-t} switch turns on run time
tracing to check that the simulator is behaving correctly.  For a full
description and listing of this program see Section~\ref{cosim}.

\bigskip\noindent
{\bf dat \tt TO/K,MSECS/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This commands output the current date and time to the {\tt TO} file,
if specified, otherwise it is sent to the standard output stream. The
{\tt MSECS} options causes the time to have higher precision. Typical
output is as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        Monday 23-Apr-2010 14:04:12
        Monday 23-Apr-2010 14:04:14.392
\end{verbatim}
\end{samepage}

\begin{samepage}
\noindent
{\bf date \tt TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This commands output the current date to the {\tt TO} file, if
specified, otherwise it is sent to the standard output stream. Typical
output is as follows:

\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        Monday 23-Apr-2010
\end{verbatim}
\end{samepage}

{\samepage
\noindent
{\bf delete \tt ,,,,,,,,,-f/S}\IMPL{y}{y}{y}%
\indent
This command will delete up to ten given files. If the {\tt-f}
argument is given, no error message is generated if any file to be
deleted does not exist.  }

\bigskip
\noindent
{\bf detab \tt  FROM/A,TO/K,SEP/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command copies the file give by the {\tt FROM} argument to
the file given by the {\tt TO} argument replacing all tab characters by
spaces. The tabs are separated by a distance specified by the {\tt SEP}
argument. The default is 8.


\bigskip
\noindent
{\bf dumpmem \tt ON/S,OFF/S}\IMPL{y}{y}{y}
\indent\nopagebreak
The {\tt ON} switch causes Cintsys or Cintpos to set the {\tt
  dumpflag} in the rootnode to {\tt TRUE}. {\tt OFF} causes the {\tt
  dumpflag} to be set to {\tt FALSE}. If the {\tt dumpflag} is {\tt
  TRUE} when a fault occurs or when a return from the interpreter
occurs, the entire Cintcode memory is output in a compacted form.
Such memory dumps are sent to the file {\tt DUMP.mem} for later
inspection by commands such as {\tt sysdebug}, {\tt dumpsys}, {\tt
  posdebug} and {\tt dumppos}.  Calling {\tt dumpmem} without
arguments causes an immediate memory.

\bigskip
\noindent
{\bf dumppos \tt FROM,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This outputs a readable form of a Cintpos memory dump specified by
the {\tt FROM} argument. If {\tt FROM} is not given it uses the file
{\tt DUMP.mem}. The output is sent to the {\tt TO} file if given,
otherwise it goes to standard output.

\bigskip
\noindent
{\bf dumpsys \tt FROM,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This outputs a readable form of a Cintsys memory dump specified by
the {\tt FROM} argument. If {\tt FROM} is not given it uses the file
{\tt DUMP.mem}. The output is sent to the {\tt TO} file if given,
otherwise it goes to standard output.

\bigskip
\noindent
{\bf easter  \tt YEAR/N,CYCLE/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command outputs the date of Easter Sunday for 10 years from the
year given by the {\tt YEAR} argument. If the {\tt YEAR} argument is
nott given the output starts from the current year.

After many years the sequence of Easter dates repeats. Giving the
{\tt CYCLE} option causes the program to discover the length of
this cycle.


\bigskip
\noindent
{\bf echo  \tt TEXT,TO/K,APPEND/S,N/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command outputs its first argument {\tt TEXT}, if given.  The
text will be followed by a newline unless the switch {\tt N} is set.
If the {\tt TO} argument is given, text is sent to the specified file
othewise it goes to the standard output stream. The {\tt APPEND}
switch causes the output to be appended to the {\tt TO} stream, after
creating an empty file if necessary.


\bigskip
\noindent
{\bf edit \tt    FROM/A,TO,WITH/K,VER/K,OPT/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command is meant to provide a simple line editor. It used to run
on the Tripos Portable Operating System but has not yet been modified
to run on this version of the system.


\bigskip\noindent
{\bf endcli}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command causes a CLI task to commit suicide.

\bigskip\noindent
{\bf enlarge \tt /A,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command output a large version of its first argument either to
file or to standard output.  For instance: {\tt enlarge~Hello}
will generate the following:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
                ##    ##  ########  ##        ##         ######  
                ##    ##  ########  ##        ##        ######## 
                ##    ##  ##        ##        ##        ##    ## 
                ########  ######    ##        ##        ##    ## 
                ##    ##  ##        ##        ##        ##    ## 
                ##    ##  ##        ##        ##        ##    ## 
                ##    ##  ########  ########  ########  ######## 
                ##    ##  ########  ########  ########   ######  
\end{verbatim}
\end{samepage}


\bigskip
\noindent
{\bf fact}\IMPL{y}{y}{y}
\indent\nopagebreak
This is a simple example program used in the console session
demonstration presented on page~\pageref{factdemo}.


\bigskip
\noindent
{\bf fail \tt RC/N,REASON/N}\IMPL{y}{y}{y}
\indent\nopagebreak
This command returns to the CLI with the specified return code and
second result.  The default return code is 10 and the default second
result is zero. Unlike the {\tt quit} command described below, it does
not cause the current command-command to terminate.


\bigskip
\noindent
{\bf failat \tt FAILLEVEL/N\label{failat}}\IMPL{y}{y}{y}
\indent\nopagebreak
This sets the CLI fail level to its argument if given, otherwise it
outputs the current setting. The CLI only issues a warning message if a
command yields a return code greater than or equal to the fail level
value.


\bigskip\noindent
{\bf fast}\IMPL{y}{y}{n}
\indent\nopagebreak
This is a program selects the fast interpreter.

\bigskip
\noindent
{\bf getlogname \tt NAME}\IMPL{y}{y}{y}
\indent\nopagebreak
This command outputs the value of a given logical variable name.  If
none is given it lists the names and values of all logical variables.
The list of logical name value pairs is held in the root node element
{\tt rtn\_envlist}.

\bigskip
\noindent
{\bf harness}\IMPL{n}{y}{n}
\indent\nopagebreak
This is Cintpos command whose purpose test a system by generating a
sequences of timed events specified by a script.


\bigskip
\noindent
{\bf help \tt ,,,,,,,,,,,,,,,\#HELPDIR/K,\#TO/K,\#TRACE/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command is meant to provide a help facility but has not yet been
transferred to Cintsys or Cintpos.

\bigskip
\noindent
{\bf hex-bin \tt FROM/A,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This is the inverse of the {\tt bin-hex} command. It reads pairs hex digit
outputting the corresponding 8-bit bytes.

\bigskip
\noindent
{\bf hexdump \tt FROM/A,N/N,P/N,RL/K/N,RLB/K/N,TO/K,}\\
\hspace*{2em}{\tt X1/S,X2/S,X4/S,LIT/S,BIG/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This program dumps a file specified by {\tt FROM} in a combination of
hex and character forms.  If either {\tt RL} or {\tt RLB} is given the
file is treated as a sequence of records. {\tt RL} gives the record
length in BCPL words and {\tt RLB} gives it in bytes. The {\tt P} and
{\tt N} arguments give the number of the first record to dump and {\tt
  N} specifies how many to dump.  If neither {\tt RL} nor {\tt RLB} is
given {\tt P} gives the number of the first byte to dump and {\tt N}
gives the number of bytes to dump. {\tt X1} causes the file to be
dumped as a sequence of individual bytes. {\tt X2} causes the file to
be dumped as a sequence of 16-bit words, and {\tt X4} causes the file
to be dumped as a sequence of 32-bit words. {\tt LIT} or {\tt BIG}
specify whether to use little-ender or big-ender ordering when dumping
words. It neither are specified the enderness of the current computer
is used. If the file {\tt bc} is as follows:

\medskip

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
#!/home/mr/distribution/BCPL/cintcode/cintsys -s
.k file/a,arg
echo "bcpl com/<file>.b to cin/<file> hdrs BCPLHDRS <arg>"
bcpl com/<file>.b to cin/<file> hdrs BCPLHDRS <arg>
\end{verbatim}
\end{samepage}

\noindent
then the command: \verb|hexdump bc 64| would generate the following:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
Dump of bc  from 0 to 63 little-ender mode

    0/    0: 682F2123 2F656D6F 642F726D 72747369   #!/h ome/ mr/d istr
   16/    4: 74756269 2F6E6F69 4C504342 6E69632F   ibut ion/ BCPL /cin
   32/    8: 646F6374 69632F65 7973746E 732D2073   tcod e/ci ntsy s -s
   48/   12: 206B2E0A 656C6966 612C612F 650A6772   ..k  file /a,a rg.e
\end{verbatim}
\end{samepage}

\noindent
{\bf hold \tt TASK/N/A}\IMPL{n}{y}{n}
\indent\nopagebreak
This is only available under Cintpos. It causes the specified task to
be put into HOLD state to stop it being available to run. Its inverse
is {\tt unhold} described below.

\bigskip
\noindent
{\bf idvec \tt ADDRESS/A}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command attempts to identify the vector at a given
address. Two example call are given below:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.000 1> idvec 23522
Stack of task 4
0.000 1> idvec 15994
Code section of task 5: MBXHAND    
0.000 1>
\end{verbatim}
\end{samepage}

\noindent
{\bf if \tt ,NOT/S,WARN/S,ERROR/S,FAIL/S,EQ/K,VAREQ/K,EXISTS/K:}\IMPL{y}{y}{y}
\indent\nopagebreak
This command normally ends with a semicolon and the remainder of the
line is conditionally executed by the CLI depending on whether the
{\tt if} condition is satisfied. The return code and second result of
the previous CLI command are held in the globals {\tt cli\_returncode}
and {\tt cli\_result2}. If one of {\tt WARN}, {\tt ERROR} or {\tt
FAIL} was given, the {\tt if} command tests whether the previous
command's return code greater or equal to warn(=5), error(=10) or
fail(=20). If the {\tt EQ} argument was given, it tests whether the
return code is the same as the first argument. If {\tt VAREQ} is
given, it specifies is a logical variable name and the value of this
variable is compared with the first argument. The {\tt EXISTS}
argument is a file name whose existence is tested. The {\tt NOT}
switch complements the condition.

\bigskip
\noindent
{\bf input \tt   TO/A,TERM/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command will copy text from the current input sending it the the
file specified by the {\tt AS} argument. The input is terminated by a
line starting with {\tt/*} or the value of the {\tt TERM} argument if
given.


\bigskip
\noindent
{\bf interpreter \tt  FAST/S,SLOW/S|}\IMPL{y}{y}{y}
\indent\nopagebreak
\label{interpreter}This command allows the user to select the 
fast ({\tt cintasm}) or the slow ({\tt cinterp}) version of the
interpreter. If no arguments are given the fast one is selected.  It
is implemented using {\tt sys(Sys\_quit,-1)} or {\tt
sys(Sys\_quit,-2)} as described on page~\pageref{sysquit}.
 

\bigskip
\noindent
{\bf join \tt   ,,,,,,,,,,,,,,,AS/A/K,CHARS/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command will concatenat several files sending the result to the
file specified by the {\tt AS} argument. If the {\tt CHARS} switch is
given the files are treated as text files, otherwise they are copied
in binary.


\bigskip
\noindent
{\bf lab \tt LABEL/A}\IMPL{y}{y}{y}
\indent\nopagebreak
This command has no effect. Its sole purpos is be the destination of
{\tt skip} commands.

\bigskip
\noindent
{\bf library \tt
  FROM,OVERRIDE/S,CANCEL/K,LIST/S,-g/S,TO/K}\IMPL{n}{y}{n}
\indent\nopagebreak This rather dangerous command allows the user to
add or delete sections of resident system code. If the {\tt FROM}
argument is given the specified file is loaded and its sections added
to the end of the chain of BLIB sections pointed to by the root node
field {\tt rtn\_blib}. If {\tt OVERRIDE} is given the newly loaded
sections are allowed to replace previous ones with the same section
names, otherwise all newly loaded sections must have names distinct
from those already in the BLIB chain. The {\tt CANCEL} argument
specifies the name of a section to remove from the BLIB chain. The
{\tt LIST} switch argument causes a list of the section names in the
BLIB chain to be output. The argument {\tt-g} causes a list of all the
global functions defined in the BLIB chain to be output including the
names of the sections they are in. The {\tt TO} argument specifies the
name of a file where the output is to be sent. It is often useful to
sort this file using {\tt sortlines}. Normally the {\tt library}
command is only used during the initialisation of special purpose
versions of Cintsys or Cintpos, or when one wishes to see which
functions are defined in {\tt BLIB}.

\bigskip
\noindent
{\bf logout}\IMPL{y}{y}{y}
\indent\nopagebreak
This command causes an exit from the BCPL Cintcode System, typical
returning to an operating system shell.


\bigskip
\noindent
{\bf makeinit \tt ,,,,,,,,,,,TO/A/K,STKSIZE/K,GLOBSIZE/K}\label{makeinit}\IMPL{y}{y}{y}
\indent\nopagebreak
This command is used by the native code version of BCPL to generate a
C program used to initialise a native code compilation of BCPL
program. It takes a list of BCPL source files and writes to the {\tt
TO} file a C program that will perform the necessary runtime
initialisation of them. This program also sets the runtime stack size
and global vector size to 50000 and 1000, respectively, unless
overridden by the {\tt STKSIZE} and {\tt GLOBSIZE} arguments.  The
resulting C program should compiled and linked with the native code
compilations of the BCPL files and various library modules. For more
information look in the directory {\tt BCPL/natbcpl} of the standard
BCPL distribution. An example of the use of {\tt makeinit} is given
on page~\pageref{makeinituse}.

\bigskip
\noindent
{\bf map \tt BLOCKS/S,NAMES/S,CODE/S,MAPSTORE/S,TO/K,PIC/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command outputs the Cintcode memory in a form that depends on the
arguments given. The output goes to the screen unless a filename is
given using the {\tt TO} keyword. {\tt BLOCKS} outputs a list of all
blocks whether allocated or free in the block chain used by {\tt
getvec}. {\tt CODE} outputs a list of all code sections currently in
memory. {\tt MAPSTORE} output the code sections and function entry
points currently in memory, and {\tt PIC} outputs a picture of what
memory is currently allocated.


\bigskip
\noindent
{\bf map \tt BLOCKS/S,NAMES/S,CODE/S,MAPSTORE/S,TO/K,PIC/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command outputs the Cintcode memory in a form that depends on the
arguments given. The output goes to the screen unless a filename is
given using the {\tt TO} keyword. {\tt BLOCKS} outputs a list of all
blocks whether allocated or free in the block chain used by {\tt
getvec}. {\tt CODE} outputs a list of all code sections currently in
memory. {\tt MAPSTORE} output the code sections and function entry
points currently in memory, and {\tt PIC} outputs a picture of what
memory is currently allocated.


\bigskip
\noindent
{\bf mapcode \tt FILE/A,TO/K,-r/N,-t/S,-f/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command inspects both 16-bit Cintcode and 6502 machine code used
on the BBC Microcomputer displaying such data in a readable form.
{\tt FROM} specifies the data file, {\tt TO} specified the output
file.  The {\tt -r} specifies the address of the first byte of machine
code to display. The {\tt -t} argument turns on debugging tracing and
{\tt-f} causes extra information to be displayed about each byte of
data being inspected.

\bigskip
\noindent
{\bf mbxcli \tt MBXNAME}\IMPL{n}{y}{n}
\indent\nopagebreak
This command creates a new CLI task taking input from the specified
mailbox, typically {\tt MBX:\em name}. If no argument is specified the
default mailbox {\tt MBX:commands} is used. Any task can write command
lines to a mailbox in a first come first served manner and any CLI
created by mbxcli can read and perform them, similarly in a first come
first served manner. If a mailbox CLI performs the {\tt endcli}
command it commits suicide.


\bigskip
\noindent
{\bf mbxrx \tt -n/N,-d/N,-b/K}\IMPL{n}{y}{n}
\indent\nopagebreak
This command is designed to test the mailbox system under Cintpos. It
will read a number of mailbox lines specified by the {\tt-n}
argument. Each line read is written to the standard output stream. It
then delays for a number of milli-seconds specified by the {\tt-d}
argument before reading the next mailbox line. The mailbox is
specified by the {\tt-b} argument with the default being {\tt
MBX:junk}.


\bigskip
\noindent
{\bf mbxtx \tt -n/N,-d/N,-b/K}\IMPL{n}{y}{n}
\indent\nopagebreak
This command is designed to test the mailbox system under Cintpos. It
will write a number of lines specified by the {\tt-n} argument to a
mailbox. Each line sent is written to the standard output stream. It
then delays for a number of milli-seconds specified by the {\tt-d}
argument before sending the next mailbox line. The mailbox is
specified by the {\tt-b} argument with the default being {\tt
MBX:junk}.


\bigskip
\noindent
{\bf mcpl}\IMPL{y}{y}{y}
\indent\nopagebreak
This command compiles an MCPL program into Mintcode. See the MCPL
distribution for more details.

\bigskip
\noindent
{\bf mcpl2mial}\IMPL{y}{y}{y}
\indent\nopagebreak
This command compiles an MCPL program into MIAL.

\bigskip
\noindent
{\bf mial-386.b}\IMPL{y}{y}{y}
\indent\nopagebreak
This translates the MIAL form of an MCPL program into Pentium assembly
language.

\bigskip
\noindent
{\bf mial-masm}\IMPL{y}{y}{y}
\indent\nopagebreak
This translates the MIAL form of an MCPL program into a mnemonic form.


\bigskip
\noindent
{\bf mkdata \tt NAME,SIZE/N}\IMPL{y}{y}{y}
\indent\nopagebreak
This creates a file with given name and size. The default name is {\tt
junk} and the default size is 4096*3+10 bytes. Byte {\em i} of the
created file is {\em i \tt MOD 256} except every 64th character is a
newline and the first 6 characters of every line hold a decimal number
giving the position of the first character of that line.


\bigskip
\noindent
{\bf mkjunk \tt  NAME,SIZE/N}\IMPL{y}{y}{y}
\indent\nopagebreak
This creates a file as described in the {\tt mkdata} command and then
tests random access to this file by overwriting some of its bytes.

\bigskip
\noindent
{\bf newcli}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command creates a new CLI task.

\bigskip
\noindent
{\bf nlconv \tt FILE,TOUNIX/S,TODOS/S,Q/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command replaces the specified file with one in which line
endings have been replaced by those appropriate for the desination
system which is specified by the switches {\tt TOUNIX} (the default)
or Windows systems ({\tt TODOS}).  The {\tt Q} argument quietens the
command.


\bigskip
\noindent
{\bf origbcpl}\IMPL{y}{y}{y}
\indent\nopagebreak
This is an old version of the BCPL compiler dated 13 August 2001 sometimes
used for benchmarking purposes.

\bigskip
\noindent
{\bf origbcpl2bmp}\IMPL{y}{y}{y}
\indent\nopagebreak
This is a program to convert the raster data corresponding to the self compilation
of origbcpl.b into a .bmp image showing how memory is used by the origbcpl compiler
compiling itself. When the {\tt bash} shell under Linux this image can be built by
typing the following commands.

\medskip
\begin{verbatim}
    cd $(BCPLROOT)
    rastsys
    slow
    raster
    origbcpl com/origbcpl.b to junk
    c bc origbcpl2bmp
    origbcpl2bmp to origbcpl.bmp
    gimp origbcpl.bmp
\end{verbatim}

\smallskip
\noindent
This image appears in this manual.

\bigskip
\noindent
{\bf playback \tt FROM/A,WAIT/S,NOTIME/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This plays back a console session recording made using the {\tt
record} command.

\bigskip
\noindent
{\bf playfast \tt FROM,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This copies a specified recording file (created by the {\tt record}
command) to the specified output enclosing timing bytes in square
brackets.

\bigskip
\noindent
{\bf playtime \tt FROM/A}\IMPL{y}{y}{y}
\indent\nopagebreak
This outputs how long a specified recording (created by the {\tt
record} command) will take to playback.

\bigskip
\noindent
{\bf posdebug \tt FROM}\IMPL{y}{y}{y}
\indent\nopagebreak
This is an interactive debugger that allows the user to inspect a
given Cintpos memory dump file. The default file name is {\tt
DUMP.mem}. See {\tt dumpmem} described above.

\bigskip
\noindent
{\bf prbbcocode \tt FROM,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts a 16-bit OCODE file used by the BCPL compiler
for the BBC Microcoputer into a more readable form. {\tt FROM}
specifies the Ocode file.  The {\tt TO} argument specifies the
destination file. If it is missing it sends the result to the screen.


\bigskip
\noindent
{\bf prefix \tt  PREFIX,UNSET/S\label{prefix}}\IMPL{y}{y}{y}
\indent\nopagebreak
This command is primarily for systems that do not have the concept of
a current working directory.  If the first argument is given, it
becomes the current prefix string.  If UNSET is specified, the prefix
string is unset, and if no argument is given the current prefix is
output. This command is implemented using {\tt
sys(Sys\_setprefix,}{\em prefix}{\tt)} and {\tt sys(Sys\_getprefix)}
described on page~\pageref{setprefix}.  See also
Section~\ref{filenames}.


\bigskip
\noindent
{\bf preload \tt   ,,,,,,,,,}\IMPL{y}{y}{y}
\indent\nopagebreak
This command will preload up to 10 commands into the Cintcode memory.
Without arguments, it outputs the list of all preloaded commands and
their sizes. Preloading improves the efficiency of command execution
and is also useful in conjunction with the {\tt stats} command, see
below. Preloaded commands can be removed using the {\tt unpreload}
command.


\bigskip
\noindent
{\bf prmcode}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts an MCODE (intermediate code for MCPL) file
specified by {\tt FROM} to a more readable form. If {\tt FROM} is
missing it reads from the file {\tt MCODE}. If the {\tt TO} argument
is missing it sends the result to the screen. The file MCODE is a
byproduct of the {\tt mcpl} command, see {\tt mcpl} above.

\bigskip
\noindent
{\bf procode \tt   FROM,TO/K\label{procode}}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts an OCODE (intermediate code for BCPL) file
specified by {\tt FROM} to a more readable form. If {\tt FROM} is
missing it reads from the file {\tt OCODE}. If the {\tt TO} argument
is missing it send the result to the screen.


\bigskip
\noindent
{\bf prompt \tt PROMPT,P0/S,P1/S,P3/S,P4/S,NO/S}\IMPL{y}{y}{y}
\indent\nopagebreak
If the {\tt NO} switch is given prompts are disabled, otherwise they
will be enabled.  Under Cintpos, disabling prompts is useful, for
instance, if a CLI task is taking input from a TCP/IP connection where
the source of the commands is another program.  The {\tt PROMPT}
argument is optional, but if present will be the new prompt format
string.  The switch parameters {\tt P0} to {\tt P4} select commonly
used prompt formats. The CLI generates prompts using a call of the
following form.

\bigskip
\centerline{{\tt writef(}%
{\em prompt}{\tt, }%
{\em cpumsecs}{\tt, }%
{\em taskno}{\tt, }%
{\em hours}{\tt, }%
{\em mins}{\tt, }%
{\em secs}{\tt, }%
{\em msecs}{\tt)}}
\bigskip

\noindent
where {\em prompt} is the prompt format string, {\em cpumsecs} is the
time in milliseconds used by the previous command, {\em taskno} is the
current task number under Cintpos and zero otherwise.  The arguments
{\em hours}, {\em mins}, {\em secs} and {\em msecs} represent the
current time of day.  The default prompt format under Cintpos is: {\tt
"\%+\%n>~"} and under the other systems is: {\tt "\%5.3d>~"}. An
example of how it might be used is as follows.

\bigskip
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0>
0> prompt "%+%+%z2:%z2:%z2 %-%-%-%-%-%5.3d> "
15:11:52 0.000> 
15:11:55 0.000> bench100

bench mark starting, Count=1000000

starting

finished
qpkt count = 2326410  holdcount = 930563
these results are correct
end of run
15:12:14 10.690> 
\end{verbatim}
\end{samepage}

\noindent
This shows that {\tt bench100} finished execution 14 seconds after
3:12pm after running for 10.690 seconds.


\bigskip
\noindent
{\bf quit \tt RC/N,REASON/N}\IMPL{y}{y}{y}
\indent\nopagebreak
This causes a CLI command-command to terminate returning a completion
code of zero unless overridden by the {\tt RC} argument. If {\tt
  REASON} is given it is placed in {\tt result2}. This command differs
from {\tt fail} since it terminates the execution of a command-command
while {\tt fail} allows a command-command to continue run.


\bigskip
\noindent
{\bf rast2ps \tt FROM,SCALE/N,TO/K,ML/N,MH/N,MG/N,FL/N,FH/N,FG/N,}\\
\verb|        DPI/K/N,INCL/K,A5/S,A4/S,A3/S,A2/S,A1/S,A0/S|\IMPL{y}{y}{y}
\indent\nopagebreak
This command has been superseded by programs such as {\tt
  com/origbcpl2bmp.b}.  This command used to be used to converts a
raster data file (written using the {\tt raster} command described
below) into a postscript file suitable for printing.

The {\tt FROM} parameter specifies the name of the raster data file.
{\tt RASTER} is the default.  {\tt SCALE} specifies a magnification as
a percentage. The default is 80.  The {\tt TO} parameter specifies the
name of the postscript file to be generated. {\tt RASTER.ps} is the
default. The parameters {\tt ML} and {\tt MH} specify the low and high
limits of the address space to be processed. {\tt MG} specifies the
separation of the grid line on the memory axis. The default values of
{\tt MH} and {\tt FH} are given by the {\tt FROM} file. The default
values of {\tt ML} and {\tt FL} are both zero. Unless {\tt MG} and
{\tt FG} are given, suitable values are chosen automatically.  The
units are in bytes.  The parameters {\tt FL} and {\tt FH} specify the
low and high limits of the instruction count axis to be
displayed. {\tt FG} specifies the separation of the grid line on the
memory axis.  {\tt DPI} specified the approximate number of dots per
inch used by the output device.  The default is 300. {\tt A}$n$
specified the output page size. The default is {\tt A4}. The {\tt
  INCL} parameter specifies the name of a file to be copied into the
postscript file. This file allows annotations to be made in the
picture. The file {\tt cintcode/origbcplps.h} was used to annotate the
memory time graph shown in Figure~\ref{bcpleps}.  This file contains
lines such as:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
F2 setfont
(SYN) 1.1 35 2 PDL
(TRN) 8.1 30 1.7 PUL
(CG) 15.3 36 2.1 PUR
(GET Stream) 0.45 270 1.7 PUL
...
(OCODE Buffer) 13.9 245 2 PDR
% 8.5 150 MVT (HELLO WORLD) SC 
F3 setfont
(Self Compilation of the Cintcode BCPL Compiler) TITLE
\end{verbatim}
\end{samepage}

The postscript macros {\tt PDL}, {\tt PUL}, {\tt PUR} and {\tt PDR}
draw arrows with specified labels, byte address, instruction count and
arrow lengths. The arrow directions are respectively: down left, up
left, up right and down right. The macro {\tt MVT} moves to the
specified position in the graph and {\tt SC} draws a string centered
at that position.  The {\tt TITLE} macro draws the graph title and
{\tt F2} and {\tt F3} are fonts suitable for the labels and title.
The resulting postscript file can, of course, be further edited by
hand.



\bigskip
\noindent
{\bf rast2wav \tt FROM,TO/K,n/N,s=secs/N,r/N,d/N,stereo/N,t/N}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts a raster data file (written using the {\tt raster}
command described below) into {\tt .wav} sound file based on the pattern
of memory accesses during the CLI command following the call of {\tt raster}.

The {\tt FROM} parameter specifies the name of the raster data file.
{\tt RASTER} is the default.  The {\tt TO} parameter specifies the
name of the {\tt .wav} file to be generated. {\tt RASTER.wav} is the
default.  By default, the program only generated notes that are equal
temperament semitone (12 per octave), but the {\tt n} argument allows
the user to specify a different number of notes per octave, susch as
24 or 41. The duration of the generated sound file can be specified
using the {\tt s} or {\tt secs} argument. The default {\tt .wav}
sample rate is 44100 per second, but 22050 or 11025 can be specified
using the {\tt r} argument. By default notes are numbered upwards from
0 to 60 with 12 notes per octave the lowest note id C two octaves
below middle C. The {\tt d} option is a debugging aid that causes all
notes other that a specified one to be silent. This allows the
algorithm to choose when to sound a note to be tested including how it
volumes envelope changes. The {\tt t} argument is not yet implemented
but willin due course generate trace output during the execution of
{\tt rast2wav}. This command was written the sound generated by EDSAC
2's loudspreaker in the 1960s was a remarkably useful debugging aid.

As a demonstration, {\tt origbcpl.wav} or {\tt origbcpl.mp3} is the
sound of the early version of the BCPL compiler compiling itself, and
the following command sequence from a {\tt bash} prompt will generate
an approximation to Bach's Invention no 10, bwv 784. These
demonstrations are not yet ready.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        rastsys
        c bc bwv784
        raster
        bwv784
        rast2wav
        ctrl-c
        audacity RASTER.wav
\end{verbatim}
\end{samepage}




\bigskip
\noindent
{\bf raster \tt COUNT/N,SCALE/N,TO/K,BITS/S,HELP/S}\IMPL{y}{y}{y}
\indent\nopagebreak\label{raster}
This command controls the generation of raster data but only works
when the BCPL Cintcode system is running under the rastering
interpreter {\tt rasterp}. The implementation uses {\tt
  sys(Sys\_setraster,...)} calls that are described on
page~\pageref{syssetraster}.  If {\tt raster} is called without the
{\tt BITS} options it activates the rastering mechanism for the
duration of the next CLI command. Without the {\tt BITS} option the
default {\tt TO} file is {\tt RASTER}.  The format of this file is
outlined on page~\pageref{syssetraster}.

The {\tt COUNT} argument specifies the number of Cintcode instructions
to obey per raster line. The default is 1000. The {\tt SCALE} argument
gives the number of byte addresses per unit on the memory axis.  The
default being 8.

The raster data file can be processed and converted to Postscript
using the {\tt rast2ps} command described above.  Typical use of the
{\tt raster} command is following script, starting from a linux {\tt
  bash} prompt:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim}
        rastsys
        raster
        origbcpl com/origbcpl.b to junk
        rast2ps incl origbcplps.h
        ctrl-c
        ps2pdf RASTER.ps
        okular RASTER.pdf
\end{verbatim}
\end{samepage}

\noindent
This will create a {\tt.pdf} file for an early version of the BCPL
compiler compiling itself, similar to that shown in
Figure~\ref{bcpleps}. For a more detailed view of the parse tree
while {\tt SYN} is being compiled, try:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        rastsys
        raster
        origbcpl com/origbcpl.b to junk
        rast2ps incl origbcplps.h ml 350000 mh 500000 fh 6000000
        ctrl-c
        ps2pdf RASTER.ps
        okular RASTER.pdf
\end{verbatim}
\end{samepage}

\begin{figure}[tbh!]
\centerline{\includegraphics[width=160.0mm]{bfigs/origbcpl.png}}
%\centerline{\includegraphics[width=140.0mm]{bfigs/origbcpl.pdf}}
\caption{\label{bcpleps}Self compilation memory-time graph}
\end{figure}

Noth that {\tt rast2ps} is now obsolete having been superseded by
programs such as {\tt com/origbcpl2bmp} which can be used to convert
the raster data files into a .bmp image files.

If {\tt raster} is called with the {\tt BITS} option, the next CLI
command will generate a bit stream file corresponding to the fifth bit
of every Cintcode byte address accessed. The default {\tt TO} file
name is {\tt RASTER.bits}. This file contains one byte for every 8
memory references so can become very large. It can be converted to a
{\tt.wav} sound file using the {\tt bits2wav} command.


\bigskip
\noindent
{\bf record \tt TO,OFF/S}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command starts sending a recording data including timing
information of the current console sessions to the specified file. The
recording is stopped by the command {\tt record off}. See the commands
{\tt playback}, {\tt playfast}, and {\tt playtime}.

\bigskip
\noindent
{\bf rename \tt   FROM/A,TO=AS/A/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This will rename the file given by {\tt FROM} to that specified
by the {\tt AS} argument.



\bigskip
\noindent
{\bf repeat}\IMPL{y}{y}{y}
\indent\nopagebreak
This attempt to reposition CLI input to the start of the current
command line thereby causing it to be executed again. For example:

{\tt wait 3; echo hello; repeat}

\noindent
will output {\tt hello} to the screen every 3 seconds until
interrupted by the D flag (set by \verb|@d|).

\bigskip
\noindent
{\bf run \em command-line}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command creates a new CLI task giving it {\em
  command-line} to execute. On complete this new CLI task commits
suicide.

\bigskip
\noindent
{\bf send \tt TASK/N,COUNT/N}\IMPL{n}{y}{n}
\indent\nopagebreak
This is part of the Cintpos bounce demonstration. It repeatedly sends
a packet to the specified task the specified number of times. The
default task number is 7 and the default count is 1000000. It can be
used to measure the efficiency of inter-task communication.  On my
1.66Ghz Pentium laptop, {\tt send} runs for 3.19secs corresponding to
about 630000 task changes per second.

\bigskip
\noindent
{\bf setflags \tt TASK,A/S,B/S,C/S,D/S,E/S,QUIET/S}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command sets the specified flags in the task control
block of the given task.  Unless {\tt QUIET} is given it outputs the
previous setting of the flags.

\bigskip
\noindent
{\bf setlogname \tt NAME,VALUE}\IMPL{y}{y}{y}
\indent\nopagebreak
This command sets or possible displays Cintsys or Cintpos logical
variables.  These must not be confused with shell environments
variables described in Section~\ref{envvars}. Cintsys and Cintpos
logical variables are held in a linked list held in the rootnode
element {\tt rtn\_envlist}.  If both {\tt NAME} and {\tt VALUE} are
given, the given logical variable name is given the specified value,
but if no value is given the specified variable is unset. If {\tt
setlogname} is called without arguments, the names and values of all
logical variables are output. A running program can lookup and set
logical variables using the functions {\tt getlogname} and {\tt
setlogname}.

\bigskip
\noindent
{\bf setroot \tt ROOT,PATH,HDRS,SCRIPTS}\IMPL{y}{y}{y}
\label{setroot}
\indent\nopagebreak
If no arguments are given it just outputs the current settings
of the four environment variable names. Otherwise, the specified
variables are given new names.

\bigskip
\noindent
{\bf shellcom \tt COMMAND/A}\IMPL{y}{y}{y}
\indent\nopagebreak
This command causes its argument to be processed by the command
language interpreter shell of the underlying operating system
(typically Linux or Windows). It does not return until the shell
has completed processing the command.

\bigskip
\noindent
{\bf sial-arm \tt FROM,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts the Sial intermediate code generated by {\tt
bcpl2sial} to the equivalent assembly language for machines using the
ARM processor.

\bigskip
\noindent
{\bf sial-386 \tt FROM,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts the Sial intermediate code generated by {\tt
bcpl2sial} to the equivalent assembly language for i386 machines such
as Pentiums.

\bigskip
\noindent
{\bf sial-alpha}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts the Sial intermediate code generated by {\tt
bcpl2sial} to the equivalent assembly language for DEC Alpha machines.

\bigskip
\noindent
{\bf sial-sasm}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts the Sial intermediate code generated by {\tt
bcpl2sial} into a human readable form.

\bigskip
\noindent
{\bf sial-vax}\IMPL{y}{y}{y}
\indent\nopagebreak
This command converts the Sial intermediate code generated by {\tt
bcpl2sial} to the equivalent assembly language for VAX machines.

\bigskip
\noindent
{\bf skip \tt LABEL}\IMPL{y}{y}{y}
\indent\nopagebreak
The command {\tt skip \em label} skips through the command stream
until a line starting with {\tt lab \em label} is encountered.  It
then skips until the end of that line before resuming normal command
execution from there.  The {\tt skip} command is only allowed within
command-commands.


\bigskip\noindent
{\bf slow}\IMPL{y}{y}{n}
\indent\nopagebreak
This is a program selects the slow interpreter.

\bigskip
\noindent
{\bf sortlines \tt FROM/A,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This command sorts the lines specified by the {\tt FROM} file sending
the result to the {\tt TO} file, removing duplicate lines. Output is
sent to the screen if the {\tt TO} parameter is not given. This can be
used to sort the data generated by the command: {\tt
  library~-g~to~junk}.


\bigskip
\noindent
{\bf sortxref \tt FROM/A,TO/K,FNS/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command sorts the lines specified by the {\tt FROM} file sending
the result to the {\tt TO} file, removing duplicate lines. Output is
sent to the screen if the {\tt TO} parameter is not given. Only lines
lines containing {\tt G:}, {\tt M:}, {\tt F:} or {\tt S:} are
included, and if {\tt FNS} is specified, only lines also containing
{\tt FN} or {\tt RT} are included. This is useful when processing
cross reference data generated by the BCPL compiler when the {\tt
  XREF} parameter is specified. A typical cross reference listing can
be found in {\tt cintcode/xrefdata}.



\bigskip
\noindent
{\bf stack \tt SIZE}\IMPL{y}{y}{y}
\indent\nopagebreak
The command {\tt stack} $n$ causes the size of the coroutine stack
allocated for subsequent commands to be $n$ words long. Without an
argument it outputs the current setting.


\bigskip
\noindent
{\bf stats \tt TO/K,PROFILE/S,ANALYSIS/S}\IMPL{y}{y}{y}
\indent\label{stats}\nopagebreak
This command controls the tallying facility which counts the execution
of individual Cintcode instructions.  If no arguments are given, {\tt
stats} turns on tallying by clearing the tally vector and causing
tallying to be enabled for the next command to be executed.
Subsequent commands are not tallied, making it possible to process the
tally vector while it is in a static state.  Typical usage of the {\tt
stats} command is illustrated below:

\bigskip
\begin{tabular}{ll}
{\tt preload queens}           &Preload the program to study\\
{\tt stats on}                 &Enable stats gathering on next command\\
{\tt queens}                   &Execute the command to study\\[2mm]
 
{\tt interpreter}              &Select the fast interpreter ({\tt cintasm})\\
                               &{\tt stats} automatically selects 
                                the slow one\\[2mm]

{\tt stats to STATS}           &Send instruction frequencies to file\\
                               &or\\
{\tt stats profile to PROFILE} &Send detailed profile info to file\\
                               &or\\
{\tt stats analysis to ANALYSIS}
                               &Generate statistical analysis to file\\
\end{tabular}




\bigskip
\noindent
{\bf status \tt TASK,FULL/S,TCB/S,SEGS/S,CLI=ALL/S}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command outputs information about all currently existing
Cintpos tasks.

\bigskip\noindent
{\bf syncdemo}\IMPL{n}{y}{n}
\indent\nopagebreak
This is a program to demonstrate various synchronisation mechanisms
implemented using coroutines and multi-event tasks.

\bigskip
\noindent
{\bf sysdebug \tt FROM}\IMPL{y}{y}{y}
\indent\nopagebreak
This is an interactive debugger that allows the user to inspect a
given Cintsys memory dump file. The default file name is {\tt
DUMP.mem}. See {\tt dumpmem} described above.

\bigskip
\noindent
{\bf sysinfo }\IMPL{y}{y}{y}
\indent\nopagebreak
This outputs some information about the current BCPL system and
the host machine on which it is running. Typical output is
as follows:

{\small
\begin{verbatim}
This version of BCPL is running on a little ender machine
The BCPL word length is 32 bits

The host address size = 64 bits
\end{verbatim}
}

\bigskip
\noindent
{\bf system}\IMPL{y}{y}{y}
\indent\nopagebreak
This command outputs a message indicating whether the current system
is Cintsys, Cintpos or Unknown. It determines which by inspecting the
rootnode field {\tt rtn\_system}.

\bigskip\noindent
{\bf taskid \tt FORMAT}\IMPL{n}{y}{n}
\indent\nopagebreak
This command calls {\tt writef} with the given format and the current
task number as the second argument. The default format is
\verb|"Taskid=%n*n"|.

\bigskip
\noindent
{\bf tcpaddr \tt HOST,PORT}\IMPL{n}{y}{n}
\indent\nopagebreak
This attempts to output the IP address and port number given the names
of the host and port.

\bigskip
\noindent
{\bf tcpbench \tt-n/K,-k/K,-s/K,-h/K,-t/S,master/s,slave/s}\IMPL{n}{y}{n}
\indent\nopagebreak
This is a benchmark program to test the efficiency of TCP/IP
communication.  For information about what it does and how to use it,
see the comments at the start of the source code.

\bigskip
\noindent
{\bf tcpcli \tt PORT,NOPROMPT/S}\IMPL{n}{y}{n}
\indent\nopagebreak
This command creates a new CLI task communicating through the given
port.  The default port number is 8000. If {\tt NOPROMPT} is specified
the newly created CLI will not issue prompts.

\bigskip
\noindent
{\bf tcpdump}\IMPL{n}{y}{n}
\indent\nopagebreak
This outputs the list of Cintpos TCP/IP devices that currently exist.
The list includes information about sockets, states and associated
hosts and port numbers.

\bigskip
\noindent
{\bf tcprx \tt HOST,PORT}\IMPL{n}{y}{n}
\indent\nopagebreak
This is a TCP/IP demonstration program to be used in conjuction with
{\tt tcptx}. It will output data received from a specified host via a
specified port. If no host is specified wait for a connection from any
host. The default port number is {\tt 9000}.

\bigskip
\noindent
{\bf tcptest \tt-n/K,-k/K,-s/K,-h/K,-t/S}\IMPL{n}{y}{n}
\indent\nopagebreak
This is a TCP/IP test program. See its source code for details.

\bigskip
\noindent
{\bf tcptx \tt HOST,PORT,N}\IMPL{n}{y}{n}
\indent\nopagebreak
This is a TCP/IP test program to be used in conjunction with {\tt
tcprx}.  It attempts to send the message {\tt hello world} to a
specified host via a specified port. The number of times the message
is sent is given by the {\tt N} argument.

\bigskip
\noindent
{\bf testtime}\IMPL{y}{y}{y}
\indent\nopagebreak
This command tests the real time clock, outputting a line such as:

\noindent
\verb|days=14876 hours=11 mins=59 secs=11 msecs=982|

\bigskip
\noindent
{\bf time \tt TO/K,MSECS/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command outputs the current time of day to the {\tt TO} file,
if specified, otherwise it is sent to the standard output stream. The
{\tt MSECS} options causes the time to have higher precision. Typical
output is as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        14:12:36.069
\end{verbatim}
\end{samepage}

\bigskip
\noindent
{\bf type \tt   FROM/A,TO,N/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command will output the file given by the {\tt FROM} argument,
sending it to the screen unless the {\tt TO} argument is given. The
swirch argument {\tt N} causes line numbers to be added.


\bigskip
\noindent
{\bf typehex \tt  FROM/A,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This will convert the file specified by {\tt FROM} in hexadecimal and
send the result to the {\tt TO} file if this argument is given. Its
output should be compared with that generated by the {\tt hexdump}
command.


\bigskip
\noindent
{\bf unhold \tt TASK/N/A}\IMPL{n}{y}{n}
\indent\nopagebreak
This Cintpos command resets the HOLD status bit of a specified
task. That task is then immediately available to run unless suspended
of other reasons.

\bigskip
\noindent
{\bf unpreload \tt,,,,,,,,,,ALL/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command will remove up to 10 specified preloaded commands from
the Cintcode memory.  The {\tt ALL} switch will cause all preloaded
commands to be removed.  Commands can be preloaded into memory using
the {\tt preload} which can also be used to list all preloaded
commands.

\bigskip
\noindent
{\bf vecstats}\IMPL{y}{y}{y}
\indent\nopagebreak
This command output information about blocks of Cintcode memory that
are currently allocated. Typical output (from Cintpos) is the
following:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
     3:  12     4:   2     6:   1    15:   2    22:   1    23:   7
    27:   4    28:   1    41:   1    80:   1   200:   2   291:   1
   306:   2   316:   1   406:   1   462:   1   500:   1   506:   3
   571:   1   597:   1   757:   1   982:   1  1000:  10  1006:   6
  1025:   2  1901:   1  2422:   1  3303:   1 20000:   1
\end{verbatim}
\end{samepage}
\noindent
This indicates, for instance, that there are currently 7 blocks of
requested size 23 allocated.

\bigskip
\noindent
{\bf wait \tt N/N,SEC=SECS/S,MIN=MINS/S,UNTIL/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This causes the CLI to wait for a specified number of seconds or
minutes, or until a specified time is reached.

\bigskip
\noindent
{\bf why}\IMPL{y}{y}{y}
\indent\nopagebreak
This command attempts to give the reason why the previous command
failed. For fun you can type {\tt why} several times.

\bigskip
\noindent
{\bf x8-bin \tt FROM/A,TO/K}\IMPL{y}{y}{y}
\indent\nopagebreak
This converts a file of 32-bit words in hex into a file of the
corresponding bytes. For instance, it will convert the file:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
44434241 48474645 4C4B4A49 504F4E4D 54535251 58575655 310A5A59 35343332 
39383736 00000A30 
\end{verbatim}
\end{samepage}
\noindent
to

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1234567890
\end{verbatim}
\end{samepage}




\bigskip\noindent
{\bf xcmpltest}\IMPL{y}{y}{y}
\indent\nopagebreak
This is a test program that checks for errors in the XBCPL compiler
and extended features in the Cintcode interpreter.

\bigskip\noindent
{\bf xcdecode \tt FROM/A,LIST/S,BIN/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command is the inverse of {\tt xcencode}. With the {\tt LIST}
option it will inspect the {\tt FROM} file listing the names of the
files it contains. Without the {\tt LIST} option it will extract and
decode these files. If {\tt BIN} is set, files are written using {\tt
binwrch} so that carriage return characters ({\tt'*c'}) are not
ignored. All characters before the first file separator are ignored.

\bigskip\noindent
{\bf xcencode \tt FILE,LIST/K,TO/K/A,BIN/S}\IMPL{y}{y}{y}
\indent\nopagebreak
This command is designed to encode one or more files in such a way
that they can be passed as the body of an email message without
interferring with the email mechanism. It uses a simple form of run
length encoding to reduce the size of the resulting file. Either {\tt
FILE} or {\tt LIST} or both must be supplied.  If given {\tt FILE} is
the first filename to be encoded followed by those given in {\tt LIST}
file, if present.  If {\tt BIN} is set, files are read using {\tt
binrdch} so that carriage return characters ({\tt'*c'}) are not
ignored. Each encoded file is preceded by a separator of the form:

\bigskip
\verb|#####filename#|

\bigskip
\noindent
followed by the encoded file in which all characters with ASCII codes
in the range 33 to 126 except for \verb|'#'|, \verb|'='| and
\verb|'.'| are copied, spaces are replaced by dots (\verb|'.'|) and
all other characters (including \verb|'#' '='| and \verb|'.'|) are
encoded by \verb|#hh| where \verb|hh| is the ASCII code in hex. The
encoded files are broken into lines of about 50 characters.  The last
file to be encoded is terminated by \verb|######+#|.

Such xencode'd files can be decoded by the {\tt xdecode} command.

\section{\label{cliimplementation}{\tt cli.b} and {\tt cli\_init.b}}

The Command Language Interpreter is a simple program implemented in
BCPL whose source code can be found in the files {\tt sysb/cli.b} and
{\tt sysb/cli\_init.b}. This section mainly describes the Cintpos
version. The CLI is the first program the interacts with after
starting the system. Under Cintpos it runs as task one (named {\tt
  Root\_Cli}). It uses variables in the global vector to hold its
state during command execution. These variables have reserved global
numbers typically in the range 133 to 149. They are declared in {\tt
  g/clihdr.b}. Since running commands use the same global vector they
can access (and even modify) these variables -- a feature that is both
dangerous and useful. Commands such as {\tt run} and {\tt c} rely on
this feature. The CLI global variables are as follows.


%return\_severe    =  20
%return\_hard      =  10
%return\_soft      =   5
%return\_ok        =   0
%cli\_module_gn    =  149
%cli\_initialstack =  50000       // Changed 21/5/2001
%cli\_faillevel    = return_hard
%cli\_initialfaillevel = return_hard






\bigskip
\noindent
{\bf cli\_init}
\IMPL{y}{y}{y}
\indent\nopagebreak
This holds the function used to initialise the CLI, and depends on
which context the CLI is to run in. It is called when the CLI is first
entered using the following code.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
  { LET f =   cli_init(parm.pkt)
    IF f DO f(result2) // Must get result2 after calling cli_init
  }
\end{verbatim}
\end{samepage}

\noindent
As can be seen {\tt cli\_init} must either return zero or a function
that can be applied to {\tt result2}. The function is typically {\tt
  deletetask} or {\tt unloadseg} with {\tt result2} being suitably
set.



\bigskip
\noindent
{\bf cli\_returncode, cli\_result2}
\IMPL{y}{y}{y}
\indent\nopagebreak
These hold the return code and the value of {\tt result2} of the most
recently executed command.


\bigskip
\noindent
{\bf cli\_faillevel}
\IMPL{y}{y}{y}
\indent\nopagebreak


\bigskip
\noindent
{\bf cli\_data}
\IMPL{y}{y}{y}
\indent\nopagebreak
This holds CLI data dependant on the context in which the CLI is running.


\bigskip
\noindent
{\bf cli\_commanddir}
\IMPL{y}{y}{y}
\indent\nopagebreak



\bigskip
\noindent
{\bf cli\_prompt}
\IMPL{y}{y}{y}
\indent\nopagebreak
This variable holds the current prompt which should be a {\tt
writef} format string since it used in the CLI as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
    writef(cli_prompt,
           cpumsecs, // msecs used by last command
           taskid,   // The task number, if running under Cintpos
           hours, mins, secs, msecs) // The time of day
\end{verbatim}
\end{samepage}

\noindent
where {\tt hours}, {\tt mins} and {\tt secs} correspond to the current
time of day. On single threaded BCPL systems {\tt taskid} is set to 1.



\bigskip
\noindent
{\bf cli\_currentinput, cli\_currentoutput, cli\_standardinput,
cli\_standardoutput}
\IMPL{y}{y}{y}
\indent\nopagebreak
The standard input and output streams are those that were setup when
the CLI was started. Sometimes a CLI will change its currently
selected streams. For instance, while executing a command-command the
currently selected input will be from a temporary file of commands. On
reaching the end of file input will revert to the standard input.

\bigskip
\noindent
{\bf cli\_commandfile}
\IMPL{y}{y}{y}
\indent\nopagebreak
\indent
This is either zero or holds the name of temporary command file used
in command-commands.



\bigskip
\noindent
{\bf cli\_status}
\IMPL{y}{y}{y}
\indent\nopagebreak
This holds a collection of bits specifying the context in which the
CLI is running. The mnemonics for these bits and their meanings are as
follows.

\bigskip
\begin{center}
\begin{tabular}{ll}
clibit\_noprompt  & \parbox[t]{100mm}{ Do not output prompts even when
not in a command-command.}\\
clibit\_eofdel    &  \parbox[t]{100mm}{Delete this task when EOF is received
under Cintpos.}\\
clibit\_comcom    & \parbox[t]{100mm}{This CLI is currently in a command-command
executing commands from a temporary file.}\\
clibit\_maincli   & \parbox[t]{100mm}{This CLI is the task 1 CLI under Cintpos
or the main CLI under other systems.}\\
clibit\_newcli    & \parbox[t]{100mm}{This CLI was created by the {\tt newcli}
command under Cintpos.}\\
clibit\_runcli    & \parbox[t]{100mm}{This CLI was created by the {\tt run}
command under Cintpos.}\\
clibit\_mbxcli    & \parbox[t]{100mm}{This CLI was created by the {\tt mbxcli}
command under Cintpos.}\\
clibit\_tcpcli    & \parbox[t]{100mm}{This CLI was created by the {\tt tcpcli}
command under Cintpos.}\\
clibit\_endcli    & \parbox[t]{100mm}{The {\tt endcli} command has been executed
on this CLI under Cintpos.}
\end{tabular}
\end{center}

\bigskip
\noindent
{\bf cli\_background}
\IMPL{y}{y}{y}
\indent\nopagebreak
This is an obsolete variable that mainly controlled the generation of
prompts.  It is to be superceded by the {\tt noprompt} bit in {\tt
  cli\_status}.

\bigskip
\noindent
{\bf cli\_defaultstack}
\IMPL{y}{y}{y}
\indent\nopagebreak
This holds the size of the coroutine stack that the CLI creates every time
it runs a command. Its value can be changed by the {\tt stack} command.

\bigskip
\noindent
{\bf cli\_commandname}
\IMPL{y}{y}{y}
\indent\nopagebreak
This holds the name of the current command

\bigskip
\noindent
{\bf cli\_module}
\IMPL{y}{y}{y}
\indent\nopagebreak
This is either zero or the module of loaded code corresponding to the
currently executing command. It is used by the CLI to unload commands
after they have been run.


\cleardoublepage


\chapter{\label{console}Console Input and Output}

When {\tt cintsys} or {\tt cintpos} is started a stream is opened to
receive input from standard input which is normally the keyboard and a
second stream is opened to allow output to standard output which is
normally the screen. This combination of keyboard and screen is called
the console. The treatment of console streams depends on whether {\tt
cintsys} or {\tt cintpos} is being used.

\section{Cintsys console streams}

The stream control block for the keyboard is obtained by
calling \verb|findinput("**")|. The stream is created the first time
it is called. Subsequent calls yield exactly the same stream control
block. This stream has a buffer large enough to hold 4096 characters.
Characters are read from the keyboard using {\tt sardch} which reads
and echoes each character to the screen. Exceptionally, ctrl-c (code
3) causes a SIGINT interrupt, RUBOUT (code 127) is translated to
backspace (code 8), ctrl-j, ctrl-m and the ENTER (or RETURN) key all
yield code 10 (the BCPL newline character) but they all echo carriage
return and linefeed to the screen unless running in quiet mode.

Simple line editing of keyboard input is performed as follows.  As
characters are typed they are normally transferred into the buffer,
but if a backspace is received, the latest character, is any, in the
buffer is removed. Unless running i quiet mode its echoed symbol is
removed from the screen. The contents of the buffer is not made
available to the user until either a newline character is received or
the buffer becomes full.

A user can receive keyboard characters as soon as they are typed using
calls of {\tt sardch}. It is also possible to read keyboard characters
by polling them using the call {\tt sys(Sys\_pollsardch)}. This yields
the next character if one is available, otherwise it returns {\tt
  pollingch=-3}, allowing the program to do other work before trying
again.

The program {\tt BCPL/bcplprogs/test/inputtst.b} can be used to
demonstate some of the features of console input.

The stream control block for the screen is obtained by calling
\verb|findoutput("**")|. The stream is created the first time it is
called. Subsequent calls yield exactly the same stream control
block. This stream has a buffer large enough to hold 4096 characters.
Calls of {\tt wrch} places characters in this buffer, and when a
newline or newpage character is written, or when the buffer becomes
full, or a call of {\tt deplete} is made, the contents of the buffer
is transmitted to the screen by calls of {\tt sawrch}.



\section{Cintpos console streams}

Under Cintpos interaction with the console is somewhat more
complicated since Cintpos can have several tasks all wishing to
communicate with the keyboard and screen. This interaction is
controlled by a task called the Console Handler (typically task
3). Tasks wishing to read from the keyboard or write to the screen
must send request packets to this task where they will be properly
scheduled.

The call \verb|findinput("**")| yields a new stream control block
connected to the keyboard. Initially it has no buffer. When the client
task tries to read from this stream, a read request packet is sent to
the console handler which will in due course return with a buffer of
one or more characters or an indication that the keyboard stream is
exhausted. Keyboard read requests can be sent simultaneously from
several tasks and, indeed, a single task can send multiple
requests. These are queued in the console handler and processed on a
first come first served basis.

The console handler obtains characters from the keyboard by sending
ttyin request packets to the keyboard device (typically device
-2). This device returns keyboard characters to the console handler as
they are typed without echoing them to the screen. It does no
translation except that the characters ctrl-j, ctrl-m and the ENTER
key all yield code 10 (the BCPL newline character). Keyboard
characters received by the console handler are normally packed into an
input buffer to form input lines. Simple line editing is performed
using the backspace key (code 8 or 127) which causes the most recent
character in the line buffer to be removed. When a newline is received
or the buffer is full or the escape sequence {\tt@e} is typed, the
line buffer is ready to send to the currently selected task. Initially
this is task 1 (the main CLI task) but can be changed by the user
using the escape mechanism described below. While a user is typing an
input line, it will appear on the screen and other screen output
requests will be held until the input line is complete. At any time if
there is a completed input line for a task that has sent a read
request packet, it will be returned to the client with the line buffer
and number of characters in its two result fields. Lines that have not
yet been requested are queued as are read requests that are not yet
satisfied. Note that a simple way to temporally stop output to the
screen is to type a character such as SPACE, and then delete it later
using backspace.

Cintpos console input has the following escape mechanism. All escape
sequence start with an at sign ({\tt@}) and their effects are shown in
the following table.

\medskip

\begin{center}
\begin{tabular}{l|p{100mm}}
Sequence & Purpose \\
\hline
{\tt@A}  & Set flag 1 in the currently selected task \\
{\tt@B}  & Set flag 2 in the currently selected task \\
{\tt@C}  & Set flag 3 in the currently selected task \\
{\tt@D}  & Set flag 4 in the currently selected task \\
{\tt@E}  & Send the current incomplete line to the currently selected task \\
{\tt@F}  & Throw away the current incomplete line and all outstanding 
           completed lines\\
{\tt@H}  & Hold the currently selected task \\
{\tt@L}  & Throw away the current incomplete line \\
{\tt@S\em dd}  & Set the currently selected task to task {\em dd} and
                 allow output from any task\\
{\tt@T\em dd}  & Set the currently selected task to task {\em dd} and
                 only allow output from task {\em dd}\\
{\tt@U}  & Unhold the currently selected task \\
{\tt@X\em hh}  & Input the character with hex code {\em hh}\\
{\tt@Y}  & Toggle message tagging. When tagging is enabled every line of
           output identifies the originating task\\
{\tt@Z}  & Toggle echo mode. When echoing is off subsequent characters
           are not echoed to the screen. This is useful for typing
           passwords. \\
{\tt@\em ddd}  & Input the character with octal code {\em ddd}\\
{\tt@@}  & Input {\tt@} \\
\end{tabular}
\end{center}

\subsection{Devices}

The input and output device intentifiers may be inspected and changed
by the following call:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
old_in_devid := sendpkt(notinuse, console_task, Action_devices,
                        ?, ?,
                        new_in_devid,
                        new_out_devid)
old_out_devid := result2
\end{verbatim}
\end{samepage}

\noindent
The device identifiers are only changed if the new identifiers are non
zero. This call is used, for instance, by the {\tt record} command to
change replace the screen output device with a task that forwards each
character to the screen while recording timing information. For
details, see the programs {\tt com/record.b} and {\tt
com/recordtask.b}

\subsection{Exclusive Input}

The console handler can be set to exclusive input mode by the call:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
sendpkt(notinuse, console_task, Action_exclusiveinput,
        ?, ?,
        TRUE)
\end{verbatim}
\end{samepage}

\noindent
While in {\tt exclusiveinput} mode normal input line editing by the
console handler is suspended and client tasks have direct access to
the keyboard input device on a first come first served basis by the
call:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
ch := sendpkt(notinuse, console_task, Action_exclusiverdch,
              ?, ?)
\end{verbatim}
\end{samepage}

\noindent
Sending an {\tt exclusiveinput} request with argument {\tt FALSE}
returns the console handler to its normal line editing mode and causes
all outstanding {\tt exclusiverdch} requests to return end-of-file
characters (-1) to their client tasks.

\subsection{Direct access to the screen and keyboard}

Although it is not recommended, client task can send read ({\tt
Action\_ttyin}) and write ({\tt Action\_ttyout}) requests to keyboard
and screen devices. These will be serviced in a first come first
served basis and since the console handler is making such requests
you can expect strange results.

Finally the functions {\tt sardch} and {\tt sawrch} provide direct
access to the keyboard and screen but are mainly only used for system
debugging particularly when the console handler is not running. Note
that {\tt sawrch} is the character output function used by
{\tt sawritef} whose output may be merged with output from the
console handler.

The following test programs can be used to demonstate some of the
console handlers features.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
Cintpos/posprogs/test/inputtst.b
Cintpos/posprogs/test/sardchtst.b
Cintpos/posprogs/test/devrdchtst.b
Cintpos/posprogs/test/xintst.b
\end{verbatim}
\end{samepage}


\cleardoublepage

\chapter{\label{posdevices}Cintpos Devices}

Cintpos allows asynchronous communication with peripheral devices
using the {\tt qpkt} and {\tt taskwait} functions. If the {\tt
pkt\_id} field of packet given to {\tt qpkt} is negative, the packet
is sent to the identified device. It is returned when the device has
completed the requested operation. Most devices have device control
blocks (DCBs) that contain device related data. There is a device
table pointed to by \verb|rootnode!rtn_devtab| whose upper bound is
held in its zeroth element. The $n^{th}$ element of the device table
is zero if the device does not exist, otherwise it points to the DCB
of device -$n$. Most devices are implemented using threads of the host
operating system, but some devices such as the clock and screen are
special and use a polling mechanism implemented entirely within the
interpreter thread. The extra overhead for this is small since the
interpreter only performs the polling operation about once every 10000
or so Cintcode instructions. This figure is typically adjusted to
cause polling to take place about once per millisecond.  When Cintpos
has no work to do it should enter the Idle task and stop executing
Cintcode instructions so that other programs can run. For the polling
mechanism to work, such suspensions must be short. This is normally
implemented using the {\tt waitirq} {\tt sys} function with a short
timeout. Each time {\tt waitirq} returns, a counter in the intepreter
is set to zero to cause the polling mechanism to be activated.

The resident Cintpos devices are described below.

\subsection{The Clock Device}

This device has identifier {\tt -1} and is treated specially by both
{\tt qpkt} and the interpreter. The {\tt pkt\_arg1} field of its
packet holds the number of milliseconds that the packet should remain
with the clock before being returned. The time stamp of when it should
be returned is calculated by {\tt qpkt} and placed in the {\tt
pkt\_res1} and {\tt pkt\_res2} fields of the packet. It is then
inserted into the time ordered clock queue held in
\verb|rootnode!rtn_clwkq|. Every time the interpreter performs the
polling operation it tests the packets at the start of the clock queue
returning though that have expired to their task.

\subsection{The Keyboard Device}

This device has identifier {\tt -2} and is currently not treated
specially, and so it has a DCB, and a device thread that is
continually trying to read character from standard input which is
normally the keyboard. Packets for this device are placed on the end
of the work queue held in the {\tt dcb\_wkq} field of the DCB. When a
character becomes available it is placed in the {\tt pkt\_res1} field
of the first packet in the queue before returning the packet to its
task.

It is planned to modify keyboard packets to allow them to handle
timeouts. This will be done by setting the {\tt pkt\_arg1} field to a
timeout value. If it is is negative no timeout is used and the packet
will remain with the device until a character is received, otherwise
it specifies a timeout in milliseconds. If no character is received
within that time, {\tt pollingch} (=-2) is returned in the {\tt res1}
field, but if a character becomes available within that time it it
returned in the normal way.

\subsection{The Screen Device}

This device has identifier {\tt -3} and is treated specially.  The
{\tt pkt\_arg1} field of the packet holds the next character to send
to the screen and when this transfer is complete the packet is
returned to the client task. Normally output to the screen causes no
real time delay.

\subsection{TCP/IP Devices}

TCP/IP devices provide a mechanism to communicate with other machines
over the internet. The {\tt pkt\_type} field specified the TCP/IP
operation required and the argument field provide additional
information about the request. The possible packet type are as follows.

\bigskip
\noindent
{\bf Tcp\_name2ipaddr \tt arg1: \em name}\\
\indent
This looks up the URL {\em name} and returns its IP address. Names such
as {\tt 127.0.0.1} are allowed. 

\bigskip
\noindent
{\bf Tcp\_name2port \tt arg1: \em name}\\
\indent
This looks up the the given port name and returns its its number.

\bigskip
\noindent
{\bf Tcp\_socket}\\
\indent
This attempts to create a port for a two way byte stream using the
IPv4 protocol. If the result is {\tt -1} there was an error, otherwise
it returns the number of the new socket.

\bigskip
\noindent
{\bf Tcp\_reuseaddr arg1: \em sock \tt arg2: \em flag}\\
\indent
If {\em flag\tt=1} this modifies the socket {\em sock} to allow reuse
of local addresses, otherwise these are disallowed. A result of zero
indicates success.


\bigskip
\noindent
{\bf Tcp\_sndbufsz arg1: \em sock \tt arg2: \em size}\\
\indent
This sets the send buffer size of the given socket to {\em size}
bytes. A zero result indicates success.
 

\bigskip
\noindent
{\bf Tcp\_rcvbufsz \tt arg1: \em sock \tt arg2: \em sz}\\
\indent
This sets the receive buffer size of the given socket to {\em size}
bytes. A zero result indicates success.

\bigskip
\noindent
{\bf Tcp\_bind \tt arg1: \em sock \tt arg2: \em ipaddr \tt arg3: \em port}\\
\indent
This assigns local host and port numbers to the specified socket.  A
zero result indicates success.

\bigskip
\noindent
{\bf Tcp\_connect \tt arg1: \em sock \tt arg2: \em ipaddr
\tt arg3: \em port \tt arg4: \em timeout}\\
\indent
This attempts to establish a connection to a remote host via the given
socket within the given timeout. If {\em timeout} is greater than zero
it specifies a timeout time in milli-seconds, if it is zero there is
no timeout and if it is {\tt-1} polling will be used but this is not
yet implemented. The result is zero if a connection was established,
otherwise it is negative and the second result indicates why the
connection was not established. A value greater than zero indicates an
error, the value {\tt-1} the connection was closed by the remote host,
{\tt-2} indicates that the connection was not established within the
timeout period, and {\tt-3} indicates that when polling the connection
has not yet been established.


\bigskip
\noindent
{\bf Tcp\_listen \tt arg1: \em sock \tt arg2: \em n}\\
\indent
This causes the specified socket to be willing to accept incoming
calls from remote hosts. The queue limit for incoming connections is
specified by {\em n}. A zero result indicates success.


\bigskip
\noindent
{\bf Tcp\_accept \tt arg1: \em sock \tt arg2: \em tcp, \tt arg4: \em timeout}\\
\indent
BEWARE: the implementation does not yet quite match the following
specification.
This attempts to accept a connection from a remote host via a
listening socket within a specified timeout period.  If {\em timeout}
is greater than zero it is the timeout period in milli-seconds, if it
is zero there is no timeout and if it is negative the packet is
returned immediately having accepted a connection if possible.  A
positive result indicates success and is the number of a new socket to
to be used by the connection.  A negative result indicates failure
with a reason in the second result. A second result of {\tt-1}
indicates the connection was closed by the remote host, {\tt-2} means
a connection was not accepted within the timeout period, and {\tt-3}
indicates that there is currently no connection to accept when
polling.


\bigskip
\noindent
{\bf Tcp\_recv \tt arg1: \em sock \tt arg2: \em buf
\tt arg3: \em len \tt arg4: \em timeout}\\
\indent
This attempts to read up to {\em len} bytes into the given buffer from
the specified socket within a specified timeout period. If {\em
timeout} is greater than zero it is the timeout period in
milli-seconds, if it is zero there is no timeout and if it is negative
the packet is returned immediately with as many characters as are
currently available. A negative result indicates failure with a reason
given in the second result, otherwise it is the number of bytes
actually read.


\bigskip
\noindent
{\bf Tcp\_send \tt arg1: \em sock \tt arg2:
\em buf \tt arg3: \em len \tt arg4: \em timeout}\\
\indent
This attempts to send {\em len} bytes from the given buffer via the
specified socket within a specified timeout period. If {\em timeout}
is greater than zero it is the timeout period in milli-seconds, if it
is zero there is no timeout and if it is negative the packet is
returned immediately having written as many bytes as are currently
possible. A negative result indicates failure with a reason given in
the second result, otherwise it is the number of bytes actually sent.

\bigskip
\noindent
{\bf Tcp\_close \tt arg1:\em sock}\\
\indent
This closes the specified socket. A zero result indicates success.


\cleardoublepage

\chapter{\label{debugging}The Debugger}

Both Cintsys and Cintpos have interactive debuggers but these are slightly
different and so will be described separately.

\section{The Cintsys Debugger}

When the Cintsys starts up, control first passes to {\tt BOOT}
which initialises the system and creates a running environment for the
command language interpreter ({\tt CLI}). This is run by a recursive
invocation of the interpreter and so when faults occur control returns
to {\tt BOOT} which then enters an interactive debugger. This allows
the user to inspect the state of the registers and memory, and perform
other debugging operations on the faulted program. The debugger can
also be entered using the {\tt abort} command, as follows:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
560> abort

!! ABORT 99: User requested
*
\end{verbatim}
\end{samepage}

\noindent
The asterisk ({\tt*}) is the debugger's prompt character. A brief
description of the available debug commands can be display using
the query ({\tt?}) command.

\pagebreak[0]
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
* ?
?          Print list of debug commands
Gn Pn Rn Vn                Variables
G  P  R  V                 Pointers
n #b101 #o377 #x7FF 'c     Constants
*e /e %e +e -e |e &e ^e    Dyadic operators
!e                         Subscription
< >                        Shift left/right one place
$b $c $d $e $f $o $s $u $x Set the print style
SGn SPn SRn SVn            Store in variable
=          Print current value
TRn        Trace the next n instructions
Tn         Print n consecutive locations
I          Print current instruction
N          Print next instruction
Q          Quit
B 0Bn eBn  List, Unset or Set breakpoints
C          Continue execution
X          Equivalent to G4B9C
Z          Equivalent to P1B9C
\          Execute one instruction
,          Move down one stack frame
. ; [ ]    Move to current/parent/first/next coroutine
*
\end{verbatim}
%$
\end{samepage}

\noindent
The debugger has a current value that can be loaded, modified
and displayed. For example:

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|* 12                               | Set the current value to 12\\*
\verb|* -2                               | Subtract 2\\*
\verb|* *3                               | Multiply by 3\\*
\verb|* =         30                     | Display the current value\\*
\verb|* <                                | Shift left one place\\*
\verb|* =         60                     | Display the current value\\*
\verb|* 12 -2 *3 < =         60          | Do it all on one line\\*
\verb|*|
\end{flushleft}

\noindent
Four areas of memory, namely: the global vector, the current stack frame,
the Cintcode register, and 10 scratch variables are easily accessed using
the letters {\tt G}, {\tt P}, {\tt R}, {\tt V}, respectively. 

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|* 10sv1 11sv2                      | Put 10 and 11 in variables 1 and 2\\*
\verb|* vt5                              | Display the first 5 variables\\*
\verb| |\\*
\verb|V  0:          0          10          11           0           0|\\*
\verb|*|\\*
\verb|* v1*50+v2=         511            | A calculation using variables\\*
\verb|* g0=       1000                   | Display global zero ({\tt globsize})\\*
\verb|* g=       3615                    | Display the address of global zero\\*
\verb|* ! =       1000                   | Indirect and display\\*
\verb|* gt10                             | Display the first 10 globals\\*
\verb| |\\*
\verb|G  0:       1000     start       stop        sys         clihook|\\*
\verb|G  5:    GLOB  5     changec       6081        6081          52|\\*
\verb|*|
\end{flushleft}

Notice that values that appear to be entry points display the first 7
characters of the function's name.  Other display styles can be
specified by the commands {\tt\$C}, {\tt\$D}, {\tt\$F}, {\tt\$B},
{\tt\$O}, {\tt\$S}, {\tt\$U} or {\tt\$X}.  These respectively display
values as characters, decimal number, in function style (the default),
binary, octal, string, unsigned decimal and hexadecimal.

It is possible to display Cintcode instructions using the commands
{\tt I} and {\tt N}. For example:

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|* g4=    clihook                   | Get the  entry to {\tt clihook}\\*
\verb|* n    3340:    K4G  1             | Call global 1, incremeting P by 4\\*
\verb|* n    3342:    RTN                | Return from the function\\*
\verb|*|
\end{flushleft}

\noindent
A breakpoint can be set at the first instruction of {\tt clihook} and
debugged program re-entered by the following:

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|* g4=    clihook                   | Get the  entry to {\tt clihook}\\*
\verb|* b9                               | Set break point 9\\*
\verb|* c                                | Resume execution\\*
\verb|20>|
\end{flushleft}

\noindent
The {\tt X} command could have been used since it is a shorhand for
{\tt G4B9C}.  The function {\tt clihook} is defined in {\tt BLIB} and
is called whenever a command is invoked. For example:

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|10> echo ABC                       | Invoke the {\tt echo} command\\*
\verb| | \\*
\verb|!! BPT 9:      clihook             | Break point hit\\*
\verb|   A=          0 B=          0     3340:    K4G  1|\\*
\verb|*|
\end{flushleft}

\noindent
Notice that the values of the Cintcode registers {\tt A} and {\tt B}
are displayed, followed by the program counter {\tt PC} and the
Cintcode instruction at that point. Single step execution is possible,
for example:

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|* \A=          0 B=          0    24228:    LLP  4     |\\*
\verb|* \A=       6097 B=          0    24230:    SP3        |\\*
\verb|* \A=       6097 B=          0    24231:     SP  89    |\\*
\verb|* \A=       6097 B=          0    24233:      L  80    |\\*
\verb|* \A=         80 B=       6097    24235:     SP  90    |\\*
\verb|* \A=         80 B=       6097    24237:    LLL  24272 |\\*
\verb|* \A=       6068 B=         80    24239:     LG  78    |\\*
\verb|* \A=    rdargs  B=       6068    24241:      K  85    |\\*
\verb|* \A=       6068 B=       6068     5480:    LP4        |\\*
\verb|*|
\end{flushleft}

\noindent
At this point the first instruction of {\tt rdargs} is about to be
executed. Its return address is in {\tt P1}, so a breakpoint can be
set to catch the return, as follows:

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|* p1b8|\\*
\verb|* c|\\*
\verb| |\\*
\verb|!! BPT 8:        24243 |\\*
\verb|   A=    createc B=          1    24243:   JNE0  24254 |\\*
\verb|*|
\end{flushleft}

\noindent
A breakpoint can be set at the start of {\tt sys}, as follows:

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|* g3b1          | Set breakpoint 1\\*
\verb|* b             | Display the currently set of breakpoints\\*
\verb|1:      sys     |\\*
\verb|8:        24243 |\\*
\verb|9:      clihook |\\*
\verb|* 0b8 0b9       | Unset breakpoints 8 and 9\\*
\verb|* b             | Display the remaining breakpoint\\*
\verb|1:      sys     |\\*
\verb|*|
\end{flushleft}

\noindent
The next three calls of {\tt sys} will be to write the characters
{\tt ABC}. The following example steps through these and displays the
state of the runtime stack just before the third call, before leaving the
debugger.

%####################################################################

\begin{flushleft}
\renewcommand{\baselinestretch}{0.8}\small
\verb|* c|\\*
\verb| |\\*
\verb|!! BPT 1:      sys     |\\*
\verb|   A=         11 B=         65    21188:    SYS|\\*
\verb|* c|\\*
\verb|A|\\*
\verb|!! BPT 1:      sys     |\\*
\verb|   A=         11 B=         66    21188:    SYS|\\*
\verb|* c|\\*
\verb|B|\\*
\verb|!! BPT 1:      sys     |\\*
\verb|   A=         11 B=         67    21188:    SYS|\\*
\verb|* .   42844:  Active coroutine     clihook   Size 20000  Hwm   127|\\*
\verb|      43284:    sys              11          67         312       43228 |\\*
\verb|* ,   43268:    cnslwrf       37772 |\\*
\verb|* ,   43248:    wrch             67          32 |\\*
\verb|* ,   43228:    writes        42915          67 |\\*
\verb|* ,   42888:    start         42904       42912           0     4407873 |\\*
\verb|* ,   42872:    clihook           0 |\\*
\verb|* , Base of stack|\\*
\verb|* 0b1c                | Clear breakpoint 1 and resume\\*
\verb|C|\\*
\verb|210>|
\end{flushleft}

\noindent

The following debugging commands allow the coroutine structure to be
explored.

\begin{center}
\begin{tabular}{|c|l|}
\hline
Command       & Effect  \rule[-3mm]{0mm}{8mm}\\
\hline
\verb|.|      & Select current coroutine \\
\verb|,|      & Display next stack frame \\
\verb|;|      & Select parent coroutine \\
\verb|[|      & Select first coroutine \\
\verb|]|      & Select next coroutine \\
\hline
\end{tabular}
\end{center}

\noindent
Finally, the command {\tt Q} causes a return from the Cintcode system.

\section{The Cintpos Debugger}

Under Cintpos, the interactive debugger can be entered by connecting
the console to task 2 (using \verb|@s02|). This allows debugging to
take place while other tasks are running. Alternatively, the debugger
is automatically entered in standalone mode when a fault is
encountered or by an explicit call of {\tt abort}. Most of its
facilities are the same as for the Cintsys version, however a few more
operations are available to access Cintpos features. The \verb|?| command
prints the following.

\pagebreak[0]
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
?          Print list of debug commands
Gn Pn Rn Vn Wn An          Variables
G  P  R  V  W  A           Pointers
123 #o377 #FF03 'c         Constants
*e /e %e +e -e |e &e ^e    Dyadic operators
!e                         Subscription
< >                        Shift left/right one place
$b $c $d $f $o $s $u $x    Set the print style
SGn SPn SRn SVn SWn SAn    Store current value
Sn                         Select task n
S.                         Select current task
H          Hold/Release selected task
K          Disable/Enable clock interrupts
=          Print current value
TRn        Trace the next n instructions
Tn         Print n consecutive locations
I          Print current instruction
N          Print next instruction
D          Dump Cintcode memory to DUMP.mem
Q          Quit -- leave the cintpos system
M          Set/Reset memory watch address
B 0Bn eBn  List, Unset or Set breakpoints
X  (G4B9C) Set breakpoint 9 at start of clihook
Z  (P1B9C) Set breakpoint 9 at return of current function
C          Continue normal execution
\          Single step execute one Cintcode instruction
. ; [ ]    Move to current/parent/first/next coroutine
,          Move down one stack frame
a1#
\end{verbatim}
%$
\end{samepage}

The main additions as {\tt S\em n} to select a task, {\tt S.} to
select the current task and {\tt H} to hold or unhold the currently
selected task. Since interrupts (particularly from the clock device)
interfere with single stepping of Cintcode instructions, the {\tt K}
command is provided to turn clock interrupts on and off. The address
of the task control block of the currently selected task is given by
{\tt W}. Thus the first locations of the control block can be printed
by the command {\tt Wt10}.

The debugger prompt contains a letter indicating whether the next
instruction is to be executed in user mode ({\tt a}), in kernel mode
({\tt k}) or within the interrupt service routine ({\tt i}). It also
contains a number indicating which user task was running.

\section{Debugging Techniques}

This section explores techniques that can be used to find and
eliminate errors in programs. To ensure this process is realistic
a program called {\tt com/rast2wav.b} of about 1000 lines has been
chosen as a case study.  This program contains various pairs of lines
one correct and the other containing a a bug. Normally the line with
the bug is commented out. By changing which line is commented, it is
possible to see the effect of a bug and demonstrate how it can be
found.

The program is intended to create a {\tt .wav} sound file based on
raster data created by the rastering version of the BCPL system called
{\tt rastsys} with the aid of the command {\tt raster}. Raster data in
the file {\tt RASTER} can be created by the following sequence of
commands.

\smallskip
{\small
\begin{verbatim}
rastsys
c b testrast         -- Compile testraster.b.
raster               -- Cause the next command to
                     -- generate raster data.
testraster           -- Actually generate the data.
\end{verbatim}
}

\smallskip

\noindent
This creates the raster data file {\tt RASTER} representing
the accesses of memory locations during the execution of
the program {\tt testraster.b} whose source is:

\smallskip
{\small
\begin{verbatim}
GET "libhdr"

LET start() = VALOF
{ FOR p = 1 TO 250000 DO IF !p LOOP
  RESULTIS 0
}
\end{verbatim}
}

\smallskip
\noindent

As can be seen this is a simple test program that that reads every
Cintcode memory word from 0 to 250000. Under 32-bit BCPL these
correspond to byte addresses in the range 0 to 1000000.  The resulting
file {\tt RASTER} starts as follows:

\smallskip
{\small
\begin{verbatim}
F1750051 M1000000   K1000 S8
W0B71W3073B1W858B1W23B3W562B1W2B1W396B1W43B4W1B1
W213B1W5B1W2135B2W67B3W7B6W1B1N
W70B72W7325B2W14B1N
W142B71W7254B2W14B1N
W213B72W7182B2W14B1N
W284B72W7111B2W14B1N
W356B72W7039B2W14B1N
\end{verbatim}
}

\smallskip
\noindent
The first line specifies the rastering parameters. {\tt F1750051}
states that the program executed 1750051 Cintcode instructions.  {\tt
  M1000000} specifies that the highest byte address referenced was
1000000. {\tt K1000} indicates that 1000 Cintcode instructions were
executed per raster line and {\tt S8} says that one unit in the raster
lines correspond to 8 address bytes. What then follows are raster
lines with each indentifying which addresses have been referenced by
the previous 1000 instructions. They use run length encoding with {\tt
  Wn} indicating that none the next {\tt n} units of address space
have been referenced and {\tt Bn} states that all the next {\tt n}
have been referenced. Each raster line is terminated by an {\tt
  N}. This file and others, some hand written, are used as test data
for {\tt rast2wav}.

The output generated by the program is a {\tt.wav} file and so it is
necessary to fully understand the format of such a file. The structure
is quite simple with a small header block that describes such things
as whether mono or stereo is being used and what the sample rate
is. This block is followed by 16-bit samples. Luckily it is easy to
check that the {\tt.wav} file structure is correct using the freely
available {\tt audacity} program. This allows the user inspect, edit
and play {\tt.wav} files.

Probably the most important advice on debugging is to spend sufficient
time proof reading the source code with great care. This is likely to
save time in the long run. It is, of course, essential to thoroughly
understand the meaning of every construct in the code.
Misunderstanding the meaning of a statement can lead to bugs that are
hard to find. Luckily BCPL is simple and is easy to
learn. Additionally, there are compile options that help the user to
check the meaning of any construct. The precedence of expression operators
such as {\tt+}, {\tt-}, {\tt*} and {\tt/} are fairly intuitive, and
can be checked by console sessions such as the following.

{\small
\begin{verbatim}
0.000> 
0.000> type t24.b  
LET f(x,y,z) = x * y / z
0.012> c b t24 tree
bcpl t24.b to t24 tree

BCPL (3 Sep 2019) 32 bit with the FLT feature
bcpl compiling to file: t24
Parse Tree
LET  t24.b[1]
*-FNDEF  t24.b[1]
! *-NAME: f
! *-COMMA
! ! *-NAME: x
! ! *-COMMA
! !   *-NAME: y
! !   *-NAME: z
! *-DIV
!   *-MUL
!   ! *-NAME: x
!   ! *-NAME: y
!   *-NAME: z
*-Nil
Code size =    36 bytes of 32-bit little ender Cintcode
0.044> 
\end{verbatim}
}

\smallskip
\noindent
This shows that {\tt x*y} is computed before dividing by {\tt z}.
Using integer arithmetic the result would often be different if the
division was done first. This difference is significant in the meaning
of \verb|q := memvupb * (n+1) / (C7-C2+1)| taken from {\tt
  rast2wav.b}. The {\tt -d} option is also sometimes helpful, as in:

{\small
\begin{verbatim}
00.000> bcpl t24.b to t24 -d 6

32 bit BCPL (4 Mar 2026), 32 bit target
   0:  DATAW #x00000000
   4:  DATAW #x0000DFDF
   8:  DATAW #x2020660B
  12:  DATAW #x20202020
  16:  DATAW #x20202020
// Entry to:   f          
  20: L1:
  20:    LP4  
  21:    MUL  
  22:    LP5  
  23:    DIV  
  24:    RTN  
  25: L2:
  28:  DATAW #x00000000
  32:  DATAW #x00000000
Code size =    36 bytes of 32-bit little ender Cintcode
0.045> 
\end{verbatim}
}

\smallskip
\noindent
Note that the three arguments of {\tt f} are held in positions 3, 4
and 5 relative to the {\tt P} pointer.

The precedence of non arithmetic operators are not so intuitive and,
indeed, tend to be different in different languages. A typical BCPL
error is the belief that \verb|IF a&7 = b&7 DO| means
\verb|IF (a&7)=(b&7) DO|. BCPL uses operators such as {\tt\&} and
     {\tt|} for both Boolean and bit pattern operations and gives them
     the precedence normally given to Boolean operators.

The transformations performed by the FLT feature and not always
understood but can be checked using the {\tt TREE2} compiler option
that outputs the parse tree after these transformations have been done
by the translation phase. As an example study the following console
session.

{\small
\begin{verbatim}
0.000> type t25.b
LET f(x, FLT y, z) BE
  x, y, z +:= 1, FLOAT x + y * 2, FIX y / z
0.012> c b t25 tree2
bcpl t25.b to t25 tree2

BCPL (3 Sep 2019) 32 bit with the FLT feature
bcpl compiling to file: t25

Parse Tree after calling translate
LET  t25.b[1]
*-RTDEF  t25.b[1]
! *-NAME: f
! *-COMMA
! ! *-NAME: x
! ! *-COMMA
! !   *-FLT
! !   ! *-NAME: y
! !   *-NAME: z
! *-SEQ
!   *-ASSADD  t25.b[2]
!   ! *-NAME: x
!   ! *-NUMBER: 1
!   *-SEQ
!     *-ASSFADD  t25.b[2]
!     ! *-NAME: y
!     ! *-FADD
!     !   *-FLOAT
!     !   ! *-NAME: x
!     !   *-FMUL
!     !     *-NAME: y
!     !     *-FNUM:       2.000000
!     *-ASSADD  t25.b[2]
!       *-NAME: z
!       *-DIV
!         *-FIX
!         ! *-NAME: y
!         *-NAME: z
*-Nil
Code size =    68 bytes of 32-bit little ender Cintcode
0.047>
\end{verbatim}
}

\smallskip
\noindent
This shows that the so called simultaneneous assignment is, in fact, a
sequence of three assignments with the second one promoted to floating
point. It shows that {\tt FLOAT} and {\tt FIX} are monadic operators
more binding that multiplication and division. It also shows that {\tt
  FLOAT x+y*2} is transformed to {\tt FLOAT x\#+y\#*2.0}.

Another useful debugging aid is BCPL's cross referencing facility. A
cross reference file {\tt xrast2wav} can be created by the command
{\tt make~xrast2wav}. This uses the following commands in {\tt Makefile}.

{\small
\begin{verbatim}
xrast2wav:      allcompiled com/rast2wav.b
        cintsys -c c bc rast2wav xref >rawxref
        cintsys -c sortxref rawxref to xrast2wav
        rm rawxref
\end{verbatim}
}

\smallskip
A few lines from {\tt xrast2wav} are as follows:

{\small
\begin{verbatim}
fcount G:226 DEF com/rast2wav.b[97] fcount=
fcount G:226 LG com/rast2wav.b[643]
    line_fsecs#:=ftotalsecs#*FLOAT fcount#/fmaxfcount
fcount G:226 LG com/rast2wav.b[705] fcount:=fcount+kval
fcount G:226 LG com/rast2wav.b[706] line_fsecs#:=pos2secs(fcount)
fcount G:226 SG com/rast2wav.b[360] fcount:=0
fcount G:226 SG com/rast2wav.b[440] fcount:=maxfcount
fcount G:226 SG com/rast2wav.b[705] fcount:=fcount+kval
filter G:209 DEF com/rast2wav.b[71] filter=
filter G:209 LG com/rast2wav.b[725] filter(notev,C7)
filter G:209 RT com/rast2wav.b[923] LET filter(v,upb)BE..
\end{verbatim}
}

\smallskip
This shows that {\tt fcount} was declared as global variable 226 on
line 97 of rast2wav.b. This variable is used to hold the number of
Cintcode instructions obeyed to reach the current raster line. On line
643 it is used to compute the time in seconds as a floating point
number corressponding to the time of the current raster line. The
actual statement in {\tt rast2wav.b} is:

{\small
\begin{verbatim}
line_fsecs := ftotalsecs * FLOAT fcount / fmaxfcount
\end{verbatim}
}

\smallskip
The last three lines show that the function {\tt filter} was declared
to be global 209 and was defined on line 923 and used just once on
line 725. We can see that the arguments in the call matches the
parameters in its definition. Careful reading of the cross reference
listing can sometime find errors in the program. This is worth doing
occasionally as the program is being developed.

Another vital tool to assist debugging is the interactive debugger.
This is entered automatically when a fault is detected but can also
be entered explicitly by the user. At an early stage of debugging
the following sequence of commands are useful.

{\small
\begin{verbatim}
0.000> abort

!! ABORT 99: User requested
* x
Breakpoint 9 at start of clihook

0.011> rast2wav

!! BPT 9:        clihook
    A=            0  B=            0   25100:    K4G  1
* 
\end{verbatim}
}

\smallskip
\noindent
This sets breakpoint 9 to be in {\tt clihook} which is in the resident
system. It causes a breakpoint just as the {\tt rast2wav} command is
about to be entered after it has been loaded into memory and
initialised. The instruction {\tt K4G 1} is about to call the function
{\tt start} in rast2wav.b. At this point we can inspect the global
vector, as in:

{\small
\begin{verbatim}
* g+200t15

G  200:  smoot'mples     wrsample        mark0        mark1          rdn
G  205:  read_'arams  read_'lines      testmem     notecofn       filter
G  210:      addnote     note2str      #G0212#      #G0213#      #G0214#
* 
\end{verbatim}
}

\smallskip
\noindent
This shows that the 13 global functions in {\tt rast2wav.b} have been
correctly initionalised. These are useful since they allow the user to
set breakpoints at the the the first instruction of any of these
functions, as in:

{\small
\begin{verbatim}
* g209=       filter
* b1
* b
1:         filter
9:        clihook
* c
Converting file RASTER to RASTER.wav
sample_rate = 44100
mono 16-bit samples
Total time with the extra second: 11 seconds

maxaddress =    460876
maxfcount  =  58862328
kval=1000 sval=8
c2=0 C3=0 C4=24 C5=36 C6=48 C7=60
Data bytes = 970184
Total number of samples: 440992

debugnote=-1 


!! BPT 1:         filter
    A=       145563  B=           60   63920:    LM1
* 
\end{verbatim}
}

\smallskip
Another good way to enter the debugger is to insert calls of {\tt
  abort} in the code usually preceded by a call of {\tt writef} or
{\tt sawritef} to output the values of some relevant variables. In the
early stages of debugging it is useful to call {\tt abort} after the
command arguments have been decoded. For example:

{\small
\begin{verbatim}
0.000> c bc rast2wav
bcpl com/rast2wav.b to cin/rast2wav 

BCPL (3 Sep 2019) 32 bit with the FLT feature
bcpl compiling to file: cin/rast2wav
Code size =  5516 bytes of 32-bit little ender Cintcode
0.151> rast2wav
Converting file RASTER to RASTER.wav
sample_rate = 44100
mono 16-bit samples
Total time with the extra second: 11 seconds

maxaddress =    460876
maxfcount  =  58862328
kval=1000 sval=8

!! ABORT 8889: Unknown fault
* 
\end{verbatim}
}

\smallskip
\noindent
This method means we do not need to set the breakpoint in {\tt
  clihook}.  Giving the call of abort an essentially random argument
makes it easier to find the call in the source code later.

{\em More to follows.}

\section{Finding a bug during the development of {\tt playmus.b}}

This is a case study of how I tracked down a bug in the program {\tt
  com/playmus.b} in the early stages of developing that program.  {\tt
  playmus} is a program ultimately intended to accompany a soloist
playing a musical composition, using realtime data from a microphone
to allow it to synchronise with the soloist. This program is currently
over 9000 lines long.

This program starts by reading a specification of the complete score
in the MUS language which gives all the notes to be played by the
accompanist and the soloist including fine detail of how they should
be played. These annotations include the information about how the
tempo, volume, legatoness and many other aspects of the performance
should change as it is played. Details of the MUS language can be
found in {\tt musman.pdf} and the {\tt Musprogs} distribution both
available from my homepage.

A bug was detected when applying {\tt playmus} to the following MUS
file.

{\small
\begin{verbatim}
$get!mushdr;
\score "Opus 1" [
\conductor ( s1        || )
\part      ( 4c4 d e f || )
]
}
\end{verbatim}

\smallskip
\noindent


\cleardoublepage


\chapter{The Design of OCODE}

BCPL was designed to be a portable language with a compiler that is
easily transferred from machine to machine.  To help to achieve this,
the compiler is structured as shown in figure~\ref{f5cmpstr} so that
the codegenerator (CG), which is inherently machine dependent, is
separated from the frontend of the compiler.  The front end performs
syntax analysis producing a parse tree (Tree) which is then translated
by the translation phase (TRN) to produce an intermediate form (OCODE)
suitable for code generation.

                                                              
\begin{figure}[tbh!]
\centerline{\includegraphics[width=151.5mm]{bfigs/f5cmpstr.png}}
\caption{\label{f5cmpstr}The structure of the compiler}
\end{figure}
                                         
\section{Representation of OCODE}

Since OCODE is output by TRN to be read in by CG, there is little need
for it to be readable by humans and so is encoded as a sequence of
integers which, in the current Cintcode implementation the OCODE is
buffered in memory, however if the compiler is not given the {\tt TO}
argument it does not invoke the codegenerator but, instead,
outputs the OCODE data to the file {\tt ocode} in text form as a
sequence of signed decimal numbers. This numerical representation of
OCODE can be transformed to a more readable mnemonic form using the
{\tt procode} command, described on page~\pageref{procode}. As an
example, if the file {\tt test.b} is the following:


\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        GET "libhdr"

        LET start() BE { LET a, b, c = 1, 0, -1
                         writef("Answer is %n*n", a+b+c)
                       }
\end{verbatim}
\end{samepage}

\noindent
then the command: \verb|bcpl test.b| would
write the following text to the file {\tt ocode}.:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
85 2 94 1 5 115 116 97 114 116 95 3 42 1 42 0 42 -1 92 91 9 43
13 65 110 115 119 101 114 32 105 115 32 37 110 10 40 4 40 3 14
40 5 14 41 74 51 6 97 91 3 103 91 3 90 2 92 76 1 1 1 
\end{verbatim}
\end{samepage}

\noindent
These numbers encode the OCODE statements in a natural way as can be
verified by comparing them with the following more readable form of
the same statements, generated by the {\tt procode} command:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        JUMP L2
        ENTRY L1 5  's' 't' 'a' 'r' 't'
        SAVE 3 LN 1 LN 0 LN -1 STORE STACK 9
        LSTR 13  'A' 'n' 's' 'w' 'e' 'r' ' ' 'i' 's' ' ' '%' 'n' 10 
        LP 4 LP 3 ADD LP 5 ADD LG 74 RTAP 6 RTRN STACK 3
        ENDPROC STACK 3 LAB L2 STORE GLOBAL 1 1 L1
\end{verbatim}
\end{samepage}

\section{The OCODE Abstract Machine}

OCODE was specifically designed for BCPL and is a compromise between
the desire for simplicity and the conflicting demands of efficiency
and machine independence.  OCODE is an assembly language for an
abstract stack based machine that has a global vector and an area of
memory for program and static data as shown in figure~\ref{f5mem}.

\begin{figure}[tbh!]
\centerline{\includegraphics[width=103.3mm]{bfigs/f5mem.png}}
\caption{\label{f5mem}The BCPL abstract machine}
\end{figure}

The OCODE machine has four registers {\tt G}, {\tt P}, {\tt PC} and
{\tt A}. {\tt G} points to the global vector and {\tt P} points to the
stack frame of the currently executing function. {\tt PC} points to
the next instruction to execute and {\tt A} is a register used hold
the results of function calls and in the compilation of {\tt VALOF}
expressions. The symbol {\tt S} holds the current size of the stack
frame. It is not a register since its value is known at every point in
the program by both the frontend of the compiler and the
codegenerator. They both know the effect on {\tt S} of every OCODE
statement. Program labels are of the form {\tt L\em n} where $n$ is an
integer. These point to positions in the program such as the entry
points of function, the desinations of jumps and the location of
static data. As with {\tt S} labels do not need registers since their
values are known.

Static variables, tables and string constants are allocated space
embedded in the compiled code.  All global, local and static variables
are of the same size which is commonly 32 or 64 bits. Some old
versions of BCPL have other word length, such as 16 bits for the Intel
6502 or Zilog Z80.

OCODE is normally encoded as a sequence of integers since it is
generated by the frontend of the compiler and read by the
codegenerator. A more readable form can be created using the {\tt
  procode} command described on page~\pageref{procode}.  An OCODE
statement consists of a function code or directive followed
by operands that are either optionally signed integers, quoted
characters or labels such as {\tt L13} or {\L97).
The following are examples of mnemonic OCODE statements:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        LSTR 5 'H' 'e' 'l' 'l' 'o'
        LP 3
        GETBYTE
        SL L36
\end{verbatim}
\end{samepage}

There are OCODE statements for loading and storing values, for
applying expression operators, for the implementation of functions and
routines, and for controlling the flow of execution.  There are also
directives for the allocation of static storage.

\section{\label{loading}Loading and Storing values}

BCPL variables may be local, global or static, and may be accessed in
various ways depending on its context. The Ocode 9 statements for
accessing variables as shown in the following table.

\bigskip
\begin{tabular}{l|l}
Statement & Meaning\\
\hline
{\tt LP}   $n$ & {\tt P!S := P!}$n${\tt; S := S+1}\\
{\tt LG}   $n$ & {\tt P!S := G!}$n${\tt; S := S+1}\\
{\tt LL  L}$n$ & {\tt P!S :=  L}$n${\tt; S := S+1}\\
{\tt LLP}  $n$ & {\tt P!S := @P!}$n${\tt; S := S+1}\\
{\tt LLG}  $n$ & {\tt P!S := @G!}$n${\tt; S := S+1}\\
{\tt LLL L}$n$ & {\tt P!S := @L}$n${\tt; S := S+1}\\
{\tt SP}   $n$ & {\tt S := S-1; P!}$n$ {\tt:= P!S}\\
{\tt SG}   $n$ & {\tt S := S-1; G!}$n$ {\tt:= P!S}\\
{\tt SL  L}$n$ & {\tt S := S-1; L}$n$ {\tt:= P!S}\\
{\tt RSTACK  }$n$ & {\tt P!}$n$ {\tt:= A; S := }$n${\tt+1}\\
\end{tabular}
\bigskip

The {\tt RSTACK} statement is used in conjunction with the {\tt RES}
statement in the compilation of {\tt VALOF} expressions. See
page~\pageref{res} for details.

The following tables shows the statements for loading constants.

\bigskip
\begin{tabular}{l|l}
Statement & Meaning\\
\hline
{\tt LF  L}$n$ & {\tt P!S := L}$n${\tt; S := S+1}\\
{\tt LN}   $n$ & {\tt P!S := }$n${\tt; S := S+1}\\
{\tt TRUE}     & {\tt P!S :=  TRUE; S := S+1}\\
{\tt FALSE}    & {\tt P!S :=  FALSE; S := S+1}\\
{\tt QUERY}    & {\tt P!S :=  ?; S := S+1}\\
{\tt LSTR }$n$ $C_1\ldots C_n$ & {\tt P!S := "}$C_1\ldots C_n${\tt"; S := S+1}\\
\end{tabular}
\bigskip

\noindent
{\tt LF L\em n} loads the entry address of a non global function onto
the stack.  {\tt LN \em n} loads the signed integer constant {\em n}
onto the stack.  If {\tt LN} is loading a floating point value {\em n}
will be a 32 or 64 bit integer has a bit pattern corresponding to a
single or double length floating point number.  The statements {\tt
  TRUE} and {\tt FALSE} are present to improve portability between
machines that may use ones complement representation for integers.  On
such machines {\tt TRUE} is not equivalent to {\tt LN -1}.  {\tt
  QUERY} loads an undefined value onto the stack, and the {\tt LSTR}
statement allocates a string in static memory and loads a pointer to
it onto the stack.

Indirect assignments and assignments to elements of word and byte
arrays normally use the statements {\tt STIND} and {\tt PUTBYTE} whose
meanings are given in table 5.3.

\bigskip
\begin{tabular}{l|l}
Statement & Meaning\\
\hline
{\tt STIND}   & {\tt !(P!(S-1)) := P!(S-2); S := S-2}\\
{\tt PUTBYTE} & {\tt (P!(S-2))\%(P!(S-1)) := P!(S-3); S := S-3}\\
\end{tabular}
\bigskip

Assuming {\tt ptr} is in global 200, the following
assignments:

{\small
\begin{verbatim}
        !ptr := 12;  ptr!3 := 99; ptr%3 := 65
\end{verbatim}
}

\noindent
translate into the following OCODE:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        LN 12  LG 200  STIND
        LN 99  LG 200  LN 3  ADD    STIND
        LN 65  LG 200  LN 3  PUTBYTE
\end{verbatim}
\end{samepage}




\section{Field Selection Operators}

Accessing and updating fields as required by the {\tt OF} operator are
implemented using the OCODE operators {\tt SELLD} and {\tt SELST}.

\bigskip
\noindent
{\tt SELLD} takes two argments {\em len} and {\em sh}. It effect is 
equivalent to

\medskip
\noindent
{\tt P!(S-1) := !(P!(S-1)) >> \em sh \tt \& \em mask}

\medskip
\noindent
where {\em mask} is a bit pattern containing {\em len} right justified
ones.  If {em len} is zero no masking is done.

\bigskip
\noindent
{\tt SELST} takes three argments {\em op}, {\em len} and {\em sh}.
If {\em op} is zero, its effect is equivalent to

\medskip
\noindent
{\tt SLCT \em len\tt:\em sh\tt:0 OF (P!(S-1)) := P!(S-2); S := S-2}

\medskip
\noindent
but if {\em op} is non zero it represents and assignment operator ({\em assop})
and the statement is equivalent to:

\medskip
\noindent
{\tt SLCT \em len\tt:\em sh\tt:0 OF (P!(S-1)) \em assop\tt:= P!(S-2); S := S-2}

\medskip
\noindent
The mapping between {\em op} and {\em assop} is given by the following table.

\bigskip
\begin{tabular}{rc|rc|rc}
\label{assops}\em op & \em assop & \em op & \em assop & \em op & \em assop \\
\hline
 0 & \tt  none &   1 & \tt     ! &   2 & \tt \#* \\
 3 & \tt   \#/ &   4 & \tt \#MOD &   5 & \tt \#+ \\
 6 & \tt   \#- &   7 & \tt     * &   8 & \tt   / \\
 9 & \tt   MOD &  10 & \tt     + &  11 & \tt   - \\
12 & \tt    << &  13 & \tt    >> &  14 & \tt  \& \\
15 & \tt     | &  16 & \tt   EQV &  17 & \tt  XOR \\
\end{tabular}
\bigskip

\noindent

The floating-point assignment operators are only allowed when the
specified field is a full word, typically with {\em len} and {\em sh}
both zero. The {\tt SELST} operator with {\em len} and {\em sh} both
zero is used in the compilation {\em assop\tt:=} assignments where the
left hand side is a simple variable or a subscripted expression.  For
instance, the assigment {\tt v!3+:=1} might generate the following
OCODE.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        LN 1
        LN 3 LG 200 ADD
        SELST ADD 0 0
\end{verbatim}
\end{samepage}
 

\section{Expression Operators}

The monadic expression operators only affect the topmost item of the
stack and do not change the value of {\tt S}. They are shown in the
next table.

\bigskip
\begin{tabular}{l|l}
Statement & Meaning\\
\hline
{\tt RV}    & {\tt P!(S-1) :=  !      P!(S-1)}\\
{\tt ABS}   & {\tt P!(S-1) :=  ABS    P!(S-1)}\\
{\tt FABS}  & {\tt P!(S-1) :=  FABS   P!(S-1)}\\
{\tt FLOAT} & {\tt P!(S-1) :=  FLOAT  P!(S-1)}\\
{\tt FIX}   & {\tt P!(S-1) :=  FIX    P!(S-1)}\\
{\tt NEG}   & {\tt P!(S-1) :=  -      P!(S-1)}\\
{\tt FNEG}  & {\tt P!(S-1) :=  \#-    P!(S-1)}\\
{\tt NOT}   & {\tt P!(S-1) :=  $\sim$ P!(S-1)}\\
\end{tabular}
\bigskip


All dyadic expression operators take two operands from stack replacing
them the result and decrementing {\tt S} by 1.  These operators are
shown in the following table.

\bigskip
\begin{samepage}
\begin{tabular}{l|l}
Statement & Meaning\\
\hline
{\tt GETBYTE} & {\tt S := S-1; P!(S-1) :=  P!(S-1) \%   P!S}\\
{\tt MUL}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) *    P!S}\\
{\tt FMUL}    & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#*  P!S}\\
{\tt DIV}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) /    P!S}\\
{\tt FDIV}    & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#/  P!S}\\
{\tt MOD}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) MOD  P!S}\\
{\tt ADD}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) +    P!S}\\
{\tt FADD}    & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#+  P!S}\\
{\tt SUB}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) -    P!S}\\
{\tt FSUB}  & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#-  P!S}\\
{\tt EQ}      & {\tt S := S-1; P!(S-1) :=  P!(S-1) =    P!S}\\
{\tt FEQ}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#=  P!S}\\
{\tt NE}      & {\tt S := S-1; P!(S-1) :=  P!(S-1) $\sim$=    P!S}\\
{\tt FNE}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#$\sim$=  P!S}\\
{\tt LS}      & {\tt S := S-1; P!(S-1) :=  P!(S-1) <    P!S}\\
{\tt FLS}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#<  P!S}\\
{\tt GR}      & {\tt S := S-1; P!(S-1) :=  P!(S-1) >    P!S}\\
{\tt FGR}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#>  P!S}\\
{\tt LE}      & {\tt S := S-1; P!(S-1) :=  P!(S-1) <=    P!S}\\
{\tt FLE}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#<=  P!S}\\
{\tt GE}      & {\tt S := S-1; P!(S-1) :=  P!(S-1) >=    P!S}\\
{\tt FGE}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) \#>=  P!S}\\
{\tt LSHIFT}  & {\tt S := S-1; P!(S-1) :=  P!(S-1) <<    P!S}\\
{\tt RSHIFT}  & {\tt S := S-1; P!(S-1) :=  P!(S-1) >>    P!S}\\
{\tt LOGAND}  & {\tt S := S-1; P!(S-1) :=  P!(S-1) \&    P!S}\\
{\tt LOGOR}   & {\tt S := S-1; P!(S-1) :=  P!(S-1) |     P!S}\\
{\tt EQV}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) EQV   P!S}\\
{\tt XOR}     & {\tt S := S-1; P!(S-1) :=  P!(S-1) XOR   P!S}\\
\end{tabular}
\end{samepage}
\bigskip

\noindent

Vector subscription ($E_1${\tt!}$E_2$ is implemented using {\tt PLUS}
and {\tt RV}. The value of {\tt x MOD y} is either zero or it has the
same sign as {\tt x} and its magnitude is less than {\tt ABS
  y}. Shifts by a negative amounts yield undefined results, but on
some versions of BCPL the shift direction is reversed.  Shifts greater
than the word length yield zero.

\section{Functions and Routines}

The design of the OCODE statements for the implementation of function
and routine calls have been designed with care to allow code
generators as much freedom as possible.  The mechanism allows some
arguments to be passed in registers if this is worthwhile, and the
distribution of work between the code for a call and the code at the
entry point is up to the implementer.  In a typical program there are
about five calls for each function or routine and so there is some
incentive to keep the size of the call small by transferring some of
the work to the save sequence.

The compilation of a function or routine definition generates an OCODE
sequence of the following form:

\begin{center}
\begin{tabular}{l}
{\tt ENTRY L}$i$  $n$ {\tt C}$_1$ \ldots { \tt C}$_n$\\
{\tt SAVE} $s$\\
{\em body of function or routine}\\
{\tt ENDPROC}\\
\end{tabular}
\end{center}

{\tt L}$i$ is the label allocated for the entry point.  As a debugging
aid, the length of the function or routine name is given by n and its
characters by the {\tt C}$_1$\ldots {\tt C}$_n$.  The {\tt SAVE}
statement specifies the initial setting of {\tt S}, which is just the
save space size (typically 3) plus the number of formal parameters.
For functions defined using pattern matching the number of formal
parameters is determined by the patterns in the match list.  The state
of the stack just after entry is shown in figure~\ref{f5procargs}.


\begin{figure}[tbh!]
\centerline{\includegraphics[width=81.9mm]{bfigs/f5procargs.png}}
\caption{\label{f5procargs}The stack frame on function or routine entry}
\end{figure}

The save space is used to hold {\tt P1} the previous value of {\tt P},
{\tt L} the return address and {\tt B} the function entry
address. Although in some versions of BCPL the save space is reduced
to two word by omitting the function entry address. This saves a
little stack space but makes certain debugging aids impossible. Thus,
the first argument of a function is normally at position 3 relative to
the {\tt P} pointer.

The end of the body is marked by an {\tt ENDPROC} statement which is
non executable but allows the code generator to keep track of nested
function definitions.

The language insists that arguments are laid out in consecutive
locations on the stack and that there is no limit to their number.
This suggests that a good strategy is to place the arguments of a call
in the locations they will occupy when the function or routine is
entered.  Thus, a typical call $E(E_1,\ldots,E_n)$ is compiled by
first incrementing {\tt S} to leave room for the save space in the new
stack frame, then generate code to evaluate the arguments
$E_1,\ldots,E_n$ before generating code for to make a subroutine jump
to $E$.  The state is then as shown in figure~\ref{f5call}.  The
subroutine jump is made using {\tt FNAP }$k$ or {\tt RTAP }$k$,
depending on whether a function or routine call is being compiled.
Notice that $k$ is the distance between the old and new stack frames.

\begin{figure}[tbh!]
\centerline{\includegraphics[width=89.5mm]{bfigs/f5call.png}}
\caption{\label{f5call}The moment of calling {\tt E(E1,E2,...En)}}
\end{figure}

The return from a routine is performed by {\tt RTRN} which restores
the previous value of {\tt P} and resumes execution at the return
address.  The return from a function is performed by {\tt FNRN} just
after the function result has been evaluated on the top of the stack.
{\tt FNRN} performs the same action as {\tt RTRN}, after placing the
function result in a special register ({\tt A}) ready for {\tt FNAP}
to store it in the required location in the previous stack frame.

\section{Control\label{res}}

The {\tt PC} register holds the address of the next instructions to be
executed. For most OCODE statements it is incremented by the size of
the instruction, but for control statements {\tt PC} is set
specifically as needed by, for instance, conditional jumps
or {\tt SWITCHON} commands. The OCODE statements concerned with
function and routine calls have already been described above. The
remaining control statements are described here.

\medskip

\noindent
\begin{tabular}{p{2.8cm}p{6.6cm}}
  {\tt LAB L}$n$ & {\tt L}$n$ {\tt:= PC}\\
\end{tabular}

\indent This directive sets the value of label {\tt L}$n$ to the
current position in the compiled code.

\medskip

\noindent
\begin{tabular}{p{2.8cm}p{6.6cm}}
  {\tt JUMP L}$n$ & {\tt PC := L}$n$\\
  {\tt JT L}$n$ & {\tt s := S-1; IF P!S DO PC := L}$n$\\
  {\tt JF L}$n$ & {\tt S := S-1; UNLESS P!S DO PC := L}$n$\\
\end{tabular}

\indent
{\tt JUMP} causes an unconditional jump to the instruction labelled by
{\tt L}$n$. Both {\tt JT} and {\tt JF} pop the top item from the stack
then conditionally jump to label {\tt L}$n$ depending on its value.

\medskip

\noindent
\begin{tabular}{p{2.8cm}p{6.6cm}}
  {\tt GOTO } & {\tt S := S-1; PC := P!S}\\
\end{tabular}

\indent
This is used in the translation of the BCPL GOTO command.

\medskip

\noindent
\begin{tabular}{p{2.8cm}p{6.6cm}}
  {\tt RES L}$n$ & {\tt S := S-1; A := P!S; PC := L}$n$\\
\end{tabular}

\indent
This is used in the compilation of {\tt RESULTIS} commands. The result
is evaluated and placed on the top of the stack, followed by a {\tt
  RES} statement which pops the result from the stack and places the
it in register {\tt A} before jumping to {\tt L}$n$. This label points
to the first instruction after the code for the {\tt VALOF} block
where there is an {\tt RSTACK} statement will push {\tt A} onto the
top of the stack after setting {\tt S} appropriately for this point in
the program.

If the {\tt VALOF} block is the body of a function, the compiled code
for its {\tt RESULTIS} commands is optimised using {\tt FNRN} rather
than {\tt RES}.

\medskip

\noindent
\begin{tabular}{l}
{\tt SWITCHON }$n$ {\tt L}$d K_1 L_1 \ldots K_n L_n$
\end{tabular}

\noindent
This is used in the compilations of switches.  It makes a jump
determined by the value on the top of the stack.  Its first argument
($n$) is the number of cases in the switch and the second argument
({\tt L}$d$) is the default label.  $K_1$ to $K_n$ are the case
constants and $L_1$ to $L_n$ are the corresponding labels. This is
normally compiled as a squence of tests, a label vector switch or a
mechanism involving binary chopping, depending on the number and range
of the case constants.

\medskip

\noindent
\begin{tabular}{p{2.8cm}p{6.6cm}}
  {\tt FINISH L}$n$ & {\tt S := S-1; A := P!S; PC := L}$n$\\
\end{tabular}

\noindent
This statement is the compilation of the BCPL {\tt FINISH} command. It
should be converted by the codegenerator into code equivalent to {\tt
  stop(0)} by the code generator. Users are strongly discourage
from using {\tt FINISH}

\section{Directives}

Sometimes the size of the stack frame changes other than in the course
of expression evaluation.  This happens, for instance, when control
leaves a block in which local variables were declared.  The statement
{\tt STACK }$s$ informs the code generator that the size of the
current stack frame is now $s$.

The {\tt STORE} statement is used to inform the code generator that
the point separating the declarations and body of a block has been
reached and that any anonymous results on the stack are actually
initialised local variables and so should be stored in their true
stack locations.

Static variables and tables are allocated space in the program area
using statements of the form {\tt ITEMN }$n$, where $n$ is the initial
value of the static cell.  The elements of table are placed in
consecutive locations by consective {\tt ITEMN} statements.  A label
may be set to the address of a static cell by preceding the {\tt
ITEMN} statement by a statement of the form {\tt DATALAB L}$n$.

The {\tt SECTION} and {\tt NEEDS} directives in a BCPL program
translate into {\tt SECTION} and {\tt NEEDS} statements of the form:

\begin{center}
\begin{tabular}{l}
{\tt SECTION }{\em n $C_1 \ldots C_n$}\\
{\tt NEEDS }{\em n $C_1 \ldots C_n$}\\
\end{tabular}
\end{center}

\noindent
where $C_1$ to $C_n$ are the characters of the {\tt SECTION} or {\tt
NEEDS} name and $n$ is the length.

The end of an OCODE module is marked by the {\tt GLOBAL} statement
which contains information about global functions, routines and
labels.  The form of the {\tt GLOBAL} statement is as follows:

\begin{center}
\begin{tabular}{l}
{\tt GLOBAL }{\em n $K_1 L_1 \ldots K_n L_n$}
\end{tabular}
\end{center}

\noindent
where $n$ is the number of items in the global initialisation list.
$K_i$ is the global number and $L_i$ is its label.  When a module is
loaded its global entry points must be initialised.


\section{Discussion}

A very early version of OCODE used a three address code in which the
operands were allowed to be the sum of up to three simple values with
a possible indirection.  The intention was that reasonable code should
be obtainable even when codegenerating one statement at a time.  It
was soon found more convenient to use an intermediate code that
separates the accessing of values from the application of operators.
This improved portability by making it possible to implement very
simple non optimising codegenerators.  Optimising codegenerators could
absorb several OCODE statements before emitting compiled code.

The {\tt TRUE} and {\tt FALSE} statements were added in 1968 to
improve portability to machines using sign and modulus or one's
complement arithmetic.  Luckily two's complement arithmetic has now
become the norm.  Other extensions to OCODE, notably the {\tt ABS},
{\tt QUERY}, {\tt GETBYTE} and {\tt PUTBYTE} statements were added as
the corresponding constructs appeared in the language.

In 1980, the BCPL changed slightly to permit position independent code
to be compiled.  This change specified that non global functions,
routines and labels were no longer variables, and the current version
of OCODE reflects this change by the introduction of the {\tt LF}
statement and the removal of the old {\tt ITEML} statement that used
to allocate static cells for such entry points.

Another minor change in this version of OCODE is the elimination of
the {\tt ENDFOR} statement that was provided to fix a problem on
16-bit word addressed machines with more than 64 Kbytes of memory.


\cleardoublepage

\chapter{\label{cintcode}The Design of Cintcode}

The original version of Cintcode was a byte stream interpretive code
designed to be both compact and capable of efficient interpretation on
small 16~bit machines based on 8 bit micro processors such as
the Z80 and 6502.  Versions that ran on the BBC Microcomputer and
under CP/M were marketed by RCP Ltd \cite{Jobson83}.  The current
version of Cintcode was extended for 32~bit implementations of BCPL
and mainly differs from the original by the provision of 32~bit
operands and the removal of a size restriction of the global vector.

\label{64bitcintcode}
There is now also a version of Cintcode for 64-bit implementations of
BCPL. This is almost identical to the 32-bit version.  A nineth
Cintcode register ({\tt MW}) has been added. This is normally zero but
can be set by a new Cintcode instruction ({\tt MW}), see below.  On
64-bit implementations, the instructions that take four byte immediate
operands, namely {\tt KW}, {\tt LLPW}, {\tt LW}, {\tt LPW}, {\tt SPW},
{\tt APW}, and {\tt AW}, sign extend the four byte immediate operand
before adding the {\tt MW} register into the senior half of the 64-bit
result before resetting the {\tt MW} to zero. In this version static
variables are allocated in 64-bit 8 byte aligned locations.


The Cintcode machine has nine registers as shown in
figure~\ref{cintmc}.

                                                
\begin{figure}[tbh!]
\centerline{\includegraphics[width=4.0in]{bfigs/cintmc.png}}
\caption{\label{cintmc}The Cintcode machine}
\end{figure}

The registers {\tt A} and {\tt B} are used for expression evaluation,
and \verb|C| is used in in byte subscription.  {\tt P} and {\tt G} are
pointers to the current stack frame and the global vector,
respectively. {\tt ST} is used as a status register in the Cintpos
version of Cintcode, and {\tt PC} points to the first byte of the next
Cintcode instruction to execute.  {\tt Count} is a register used by
the debugger. While it is positive, {\tt Count} is decremented on each
instruction execution, raising an exception (code 3) on reaching zero.
When negative, it causes a second (faster) interpreter to be used.

Cintcode encodes the most commonly occurring operations as single byte
instructions, using multi-byte instructions for rarer operations.  The
first byte of an instruction is the function code.  Operands of size
1, 2 or 4 bytes immediately follow some function bytes.  The two
instructions used to implement switches have inline data following the
function byte. Cintcode modules also contains static data for stings,
integers, tables and global initialisation data.

\section{Designing for Compactness}

To obtain a compact encoding, information theory suggests that each
function code should occur with approximately equal frequency.  The
self compilation of the BCPL compiler, as shown in
figure~\ref{bcpleps}, was the main benchmark test used to
generate frequency information and a summary of how often various
operations are used during this test is given in table~\ref{opcounts}.
This data was produced using the tallying feature controlled by the
{\tt stats} command, described on page~\pageref{stats}.

\begin{table}[tbh!]
\begin{center}
\begin{tabular}{l|rr}

\bf Operation & \bf   Executions & \bf Static count\\[0.5ex]
\hline\\[-1.5ex]

Loading a local variable      &\tt 3777408&\tt 1479\\
Updating a local variable     &\tt 1965885&\tt 1098\\[0.5ex]

Loading a global variable     &\tt 5041968&\tt 1759\\
Updating a global variable    &\tt  796761&\tt  363\\[0.5ex]

Using a positive constant     &\tt 4083433&\tt 1603\\
Using a negative constant     &\tt  160224&\tt   93\\[0.5ex]

Conditional jumps (all)       &\tt 2013013&\tt  488\\
Conditional jumps on zero     &\tt  494282&\tt  267\\
Unconditional direct jump     &\tt  254448&\tt  140\\
Unconditional indirect jumps  &\tt  152646&\tt   93\\[0.5ex]

Procedure calls               &\tt 1324206&\tt 1065\\
Procedure returns             &\tt 1324204&\tt  381\\[0.5ex]

Binary chop switches          &\tt   43748&\tt   12\\
Label vector switches         &\tt   96461&\tt   17\\[0.5ex]

Addition                      &\tt 2135696&\tt  574\\
Subtraction                   &\tt  254935&\tt  111\\
Other expression operations   &\tt  596882&\tt   74\\[0.5ex]

Loading a vector element      &\tt 1356315&\tt  429\\
Updating a vector element     &\tt  591268&\tt  137\\[0.5ex]

Loading a byte vector element  &\tt 476688&\tt   53\\
Updating a byte vector element &\tt 405808&\tt   29
\end{tabular}
\caption{\label{opcounts}Counts from the BCPL self compilation test}
\end{center}
\end{table}

The statistics from different programs vary greatly, so while encoding
the common operations really compactly, there is graceful degradation
for the rarer cases ensuring that even unusual programs are handled
reasonably well.  There are, for instance, several one byte
instructions for loading small integers, while larger integers are
handled using 2, 3 and 5 byte instructions. The intention is that
small changes in a source program should cause small small changes in
the size of the corresponding compiled code.

Having several variant instructions for the same basic operation
does not greatly complicate the compiler. For example the
four variants of the {\tt AP} instruction that adds a local variable
into register {\tt A} is dealt with by the following code fragment
taken from the codegenerator.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
      TEST 3<=n<=12 THEN gen(f_ap0 + n)
                    ELSE TEST 0<=n<=255
                         THEN genb(f_ap, n)
                         ELSE TEST 0<=n<=#xFFFF
                              THEN genh(f_aph, n)
                              ELSE genw(f_apw, n)
\end{verbatim}
}

It is clear from table~\ref{opcounts} that accessing variables and
constants requires special care, and that conditional jumps, addition,
calls and indirection are also important.  Since access to local
variables accounts for about a quarter of the operations performed,
about this proportion of codes were allocated to instructions
concerned with local variables.  Local variables are allocated words
in the stack starting at position 3 relative to the {\tt P} pointer
and, as one would expect, small numbered locals are used far more
frequently than the others, so operations on low numbered locals often
have single byte codes.

Although not shown here, other statistics, such as the distribution of
relative addressing offsets and operand values, influenced the design
of Cintcode.  

\subsection{Global Variables}

Global variables are referenced as frequently as locals and therefore
have many function codes to handle them.  The size of the global
vector in most programs is less than 512, but Cintcode allows this to
be as large are 65536 words.  Each operation that refers to a global
variable is provided with three related instructions.  For instance,
the instructions to load a global into register {\tt A} are as
follows:

\bigskip
\centerline{\includegraphics[width=4.3in]{bfigs/cintlg.png}}

\noindent
Here, {\tt b} and {\tt h} are unsigned 8 and 16~bit values,
respectively.

\subsection{Composite Instructions}

Compactness can be improved by combining commonly occurring pairs (and
triples) of operations into a single instructions.  Many such
composite instructions occur in Cintcode; for instance, {\tt AP3} adds
local {\tt 3} to the {\tt A} register, and {\tt L1P6} will load {\tt
v!1} into register {\tt A}, assuming {\tt v} is held in local {\tt 6}.


\subsection{\label{reladdressing}Relative Addressing}

A relative addressing mechanism is used in conditional and
unconditional jumps and the instructions: {\tt LL}, {\tt LLL}, {\tt SL}
and {\tt LF}.  All these instructions refer to locations within the
code and are optimised for small relative distances.  To simplify the
codegenerator all relative addressing instructions are 2 bytes in
length. The first being the function code and the second being an
8~bit relative address.

\begin{figure}[tbh!]
\centerline{\includegraphics[width=4.3in]{bfigs/cintjumps.png}}
\caption{\label{cintjumps}The relative addressing mechanism}
\end{figure}

All relative addressing instructions have two forms: direct and
indirect, depending on the least significant bit of the function byte.
The details of both relative address calculations are shown in
figure~\ref{cintjumps}, using the instructions {\tt J} and {\tt J\$} as
examples.  For the direct jump ({\tt J}), the operand ({\tt a}) is a
signed byte in the range -128 to +127 which is added to the address
({\tt x}) of the operand byte to give the destination address
({\tt dest}).  For the indirect jump, {\tt J\$}, the operand ({\tt b})
is an unsigned byte in the range 0 to 255 which is doubled and added
to the rounded version of {\tt x} to give the address ({\tt q}) of a
16~bit signed value {\tt hh} which is added to {\tt q} to give the
destination address ({\tt dest}).

The compiler places the resolving half word as late as possible to
increase the chance that it can be shared by other relative addressing
instructions to the same desination, as could happen when several
ENDCASE statements occur in a large SWITCHON command. The use of a 16
bit resolving word places a slight restriction on the maximum size of
relative references. Any Cintcode module of less than 64K bytes will
have no problem.






\section{The Cintcode Instruction Set}

The resulting selection of function codes is shown in
Table~\ref{cintfcodes} and they are described in the sections that
follow.  In the remaining sections of this chapter the following
conventions hold:

\medskip
\begin{tabular}{c|l}
Symbol       & Meaning\\ \hline
$n$          & An integer encoded in the function byte.\\
$Ln$         & The one byte operand of a relative addressing instruction.\\
$b$          & An unsigned byte, range $0\le b\le255$.\\
$h$          & An unsigned halfword, range $0\le h\le65535$.\\
$w$          & A signed 32 bit word.\\
{\em filler} & Optional filler byte to round up to a 16~bit boundary.\\
\tt A        & The Cintcode {\tt A} register.\\
\tt B        & The Cintcode {\tt B} register.\\
\tt C        & The Cintcode {\tt C} register.\\
\tt P        & The Cintcode {\tt P} register.\\
\tt G        & The Cintcode {\tt G} register.\\
\tt PC       & The Cintcode {\tt PC} register.\\
\tt MW       & The Cintcode {\tt MW} register used in 64-bit Cintcode.
\end{tabular}
\bigskip


\begin{table}[tbhp]
\begin{center}
\renewcommand{\baselinestretch}{0.95}\normalsize
\tt
\begin{tabular}{r|rrrrrrrr}
  &      0&     32&     64&     96&    128&    160&   192&   224\\[4pt]
\hline

 0&      -&     K &    LLP&      L&     LP&     SP&    AP&     A\\
 1&  FLTOP&     KH&   LLPH&     LH&    LPH&    SPH&   APH&    AH\\
 2&    BRK&     KW&   LLPW&     LW&    LPW&    SPW&   APW&    AW\\
 3&     K3&    K3G&   K3G1&   K3GH&    LP3&    SP3&   AP3&  L0P3\\
 4&     K4&    K4G&   K4G1&   K4GH&    LP4&    SP4&   AP4&  L0P4\\
 5&     K5&    K5G&   K5G1&   K5GH&    LP5&    SP5&   AP5&  L0P5\\
 6&     K6&    K6G&   K6G1&   K6GH&    LP6&    SP6&   AP6&  L0P6\\
 7&     K7&    K7G&   K7G1&   K7GH&    LP7&    SP7&   AP7&  L0P7\\
 8&     K8&    K8G&   K8G1&   K8GH&    LP8&    SP8&   AP8&  L0P8\\
 9&     K9&    K9G&   K9G1&   K9GH&    LP9&    SP9&   AP9&  L0P9\\
10&    K10&   K10G&  K10G1&  K10GH&   LP10&   SP10&  AP10& L0P10\\
11&    K11&   K11G&  K11G1&  K11GH&   LP11&   SP11&  AP11& L0P11\\
12&     LF&    S0G&   S0G1&   S0GH&   LP12&   SP12&  AP12& L0P12\\
13&   LF\$&    L0G&   L0G1&   L0GH&   LP13&   SP13& XPBYT&     S\\
14&     LM&    L1G&   L1G1&   L1GH&   LP14&   SP14&   LMH&    SH\\
15&    LM1&    L2G&   L2G1&   L2GH&   LP15&   SP15&   BTC&  MDIV\\
16&     L0&     LG&    LG1&    LGH&   LP16&   SP16&   NOP& CHGCO\\
17&     L1&     SG&    SG1&    SGH&    SYS&     S1&    A1&   NEG\\
18&     L2&    LLG&   LLG1&   LLGH&    SWB&     S2&    A2&   NOT\\
19&     L3&     AG&    AG1&    AGH&    SWL&     S3&    A3&  L1P3\\
20&     L4&    MUL&    ADD&     RV&     ST&     S4&    A4&  L1P4\\
21&     L5&    DIV&    SUB&    RV1&    ST1&    XCH&    A5&  L1P5\\
22&     L6&    MOD&    LSH&    RV2&    ST2&   GBYT&  RVP3&  L1P6\\
23&     L7&    XOR&    RSH&    RV3&    ST3&   PBYT&  RVP4&  L2P3\\
24&     L8&     SL&    AND&    RV4&   STP3&    ATC&  RVP5&  L2P4\\
25&     L9&   SL\$&     OR&    RV5&   STP4&    ATB&  RVP6&  L2P5\\
26&    L10&     LL&    LLL&    RV6&   STP5&      J&  RVP7&  L3P3\\
27&   FHOP&   LL\$&  LLL\$&    RTN&   GOTO&    J\$& ST0P3&  L3P4\\
28&    JEQ&    JNE&    JLS&    JGR&    JLE&    JGE& ST0P4& L4P3\\
29&  JEQ\$&  JNE\$&  JLS\$&  JGR\$&  JLE\$&  JGE\$& ST1P3& L4P4\\
30&   JEQ0&   JNE0&   JLS0&   JGR0&   JLE0&   JGE0& ST1P4&SELLD\\
31& JEQ0\$& JNE0\$& JLS0\$& JGR0\$& JLE0\$& JGE0\$&    MW&SELST
\end{tabular}
\caption{\label{cintfcodes}The Cintcode function codes}
\end{center}
\end{table}


\subsection{Byte Ordering and Alignment}

A Cintcode module is a vector of 32 bit words containing the compiled
code and static data of a section of program.  The first word of a
module holds its size in words that is used as a relative address to
the end of the module where the global initialisation data is
placed. The last word of a module holds the highest referenced global
number, and working back, there are pairs of words giving the global
number and relative entry address of each global function or label
defined in the module.  A relative address of zero marks the end of
the initialisation data.  See section~\ref{loading} for more details.

The compiler can generate code for either a big- or little-endian
machine. These differ only in the byte ordering of bytes within words.
For a little endian machine, the first byte of a 32 bit word is at the
least significant end, and on a big-endian machine, it is the most
significant byte.  This affect the ordering of bytes in 2 and 4 byte
immediate operands, 2 byte relative address resolving words, 4 byte
static quantities and global initialisation data. Resolving words are
aligned on 16~bit boundaries relative to the start of the module, and
4 byte statics values are aligned on 32 bit boundaries. The 2 and 4
byte immediate operands are not aligned.

For efficiency reasons, the byte ordering is chosen to suit the
machine on which the code is to be interpreted. The compiler option
{\tt OENDER} causes the BCPL compiler to compile code with the
opposite endianess to that of the machine on which the compiler is
running, see the description of the {\tt bcpl} command on
page~\pageref{bcplcommand}.


\subsection{Loading Values}

The following instructions are used to load constants, variables, the
addresses of variables and function entry points. Notice that all
loading instructions save the old value of register {\tt A} in {\tt B}
before updating {\tt A}.  This simplifies the translation of dyadic
expression operators.


{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
L$n$     \> $0\le n\le10$     \> B := A; A := $n$\\
LM1      \>                   \> B := A; A := -1\\
L $b$    \>                   \> B := A; A := $b$\\
LM $b$   \>                   \> B := A; A := -$b$\\
LH $h$   \>                   \> B := A; A := $h$\\
LMH $h$  \>                   \> B := A; A := -$h$\\
LW $w$   \>                   \> B := A; A := $w$\\
MW $w$   \>                   \> MW := $w$
\end{tabbing}
}

\noindent
These instructions load integer constants.  Constants are in the range
{\tt-1} to {\tt10} are the most common and have single byte
instructions. The other cases use successively larger instructions.
The {\tt MW} instruction is only used in 64-bit Cintcode. See
page~\pageref{64bitcintcode} for more details.

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
LP$n$    \> $3\le n\le16$     \> B := A; A := P!$n$\\
LP $b$   \>                   \> B := A; A := P!$b$\\
LPH $h$  \>                   \> B := A; A := P!$h$\\
LPW $w$  \>                   \> B := A; A := P!$w$
\end{tabbing}
}

\noindent
These instructions load local variables and anonymous results
addressed relative to {\tt P}.  Offsets in the range 3 to 16 are the
most common and use single byte instructions. The other cases use
succesively larger instructions.

\pagebreak[3]
{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
LG $b$   \>                   \> B := A; A := G!$b$\\
LG1 $b$  \>                   \> B := A; A := G!($b+256)$\\
LGH $h$  \>                   \> B := A; A := G!$h$
\end{tabbing}
}

\noindent
{\tt LG} loads the value of a global variables in the range 0 to 255,
{\tt LG1} load globals in the range 256 to 511, and {\tt LGH} can load
globals up to 65535. Global numbers must be in the range 0 to 65535.

\pagebreak[3]
{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
LL $Ln$  \>                   \> B := A; A := {\rm variable} $Ln$\\
LL\$ $Ln$\>                   \> B := A; A := {\rm variable} $Ln$\\
LF $Ln$  \>                   \> B := A; A := {\rm entry point} $Ln$\\
LF\$ $Ln$\>                   \> B := A; A := {\rm entry point} $Ln$
\end{tabbing}
}

\noindent
{\tt LL} loads the value of a static variable and {\tt LF} loads the
entry address of a function, routine or label in the current module.


{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
LLP $b$  \>                   \> B := A; A := \verb|@|P!$b$\\
LLPH $h$ \>                   \> B := A; A := \verb|@|P!$h$\\
LLPW $w$ \>                   \> B := A; A := \verb|@|P!$w$\\
LLG $b$  \>                   \> B := A; A := \verb|@|G!$b$\\
LLG1 $b$ \>                   \> B := A; A := \verb|@|G!($b+256)$\\
LLGH $h$ \>                   \> B := A; A := \verb|@|G!$h$\\
LLL $Ln$ \>                   \> B := A; A := \verb|@|(variable $Ln$)\\
LLL\$ $Ln$ \>                 \> B := A; A := \verb|@|(variable $Ln$)
\end{tabbing}
}

\noindent 
These instructions load the BCPL pointers to local, global and static
variables.

\subsection{Indirect Load}

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
GBYT       \>               \> A := B\%A\\
RV         \>               \> A := A!0\\
RV$n$      \> $1\le n\le6$  \> A := A!$n$\\
RVP$n$     \> $3\le n\le7$  \> A := P!$n$!A\\
L0P$n$     \> $3\le n\le12$ \> B := A; A := P!$n$!0\\
L1P$n$     \> $3\le n\le6$  \> B := A; A := P!$n$!1\\
L2P$n$     \> $3\le n\le5$  \> B := A; A := P!$n$!2\\
L3P$n$     \> $3\le n\le4$  \> B := A; A := P!$n$!3\\
L4P$n$     \> $3\le n\le4$  \> B := A; A := P!$n$!4\\
L$n$G $b$  \> $0\le n\le2$  \> B := A; A := G!$b$!$n$\\
L$n$G1 $b$ \> $0\le n\le2$  \> B := A; A := G!($b$+256)!$n$\\
L$n$GH $h$ \> $0\le n\le2$  \> B := A; A := G!$h$!$n$
\end{tabbing}
}

\noindent
These instructions are used in the implementation of byte and word
indirection operators {\tt\%} and {\tt!} in right hand contexts.

\subsection{Expression Operators}

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
NEG       \> \> A := -A\\
NOT       \> \> A := \verb|~|A
\end{tabbing}
}

\noindent
These instructions implement the three monadic expression operators.

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
MUL       \> \> A := B * A\\
DIV       \> \> A := B / A\\
MOD       \> \> A := B MOD A\\
ADD       \> \> A := B + A\\
SUB       \> \> A := B - A\\
LSH       \> \> A := B << A\\
RSH       \> \> A := B >> A\\
AND       \> \> A := B \& A\\
OR        \> \> A := B | A\\
XOR       \> \> A := B XOR A
\end{tabbing}
}
\noindent
These instructions provide for all the normal arithmetic and bit
pattern dyadic operators. The instructions {\tt DIV} and {\tt MOD}
generate exception 5 if the divisor is zero. Evaluation of relational
operators in non conditional contexts involve conditional jumps and
the {\tt FHOP} instruction, see page~\pageref{fhop}. Addition is the
most frequently used arithmetic operation and so there are various
special instructions improve its efficiency.

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
A$n$      \> $1\le n\le5$ \> A := A + $n$\\
S$n$      \> $1\le n\le4$ \> A := A - $n$\\
A $b$     \>              \> A := A + $b$\\
AH $h$    \>              \> A := A + $h$\\
AW $w$    \>              \> A := A + $w$\\
S $b$     \>              \> A := A - $b$\\
SH $h$    \>              \> A := A - $h$
\end{tabbing}
}

\noindent
These instructions implement addition and subtraction by constant
integer amounts. There are single byte instructions for incrementing
by 1 to 5 and decremented by 1 to 4. For other values longer
instructions are available.

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
AP$n$     \> $3\le n\le12$ \> A := A + P!$n$\\
AP $b$    \>               \> A := A + P!$b$\\
APH $h$   \>               \> A := A + P!$h$\\
APW $w$   \>               \> A := A + P!$w$\\
AG $b$    \>               \> A := A + G!$b$\\
AG1 $b$   \>               \> A := A + G!($b$+256)\\
AGH $h$   \>               \> A := A + G!$h$
\end{tabbing}
}

\noindent
These instructions allow local and global variables to be added to
{\tt A}. Special instructions for addition by static variables are not
provided, and subtraction by a variable is not common enough to
warrant special treatment.


\subsection{Simple Assignment}

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
SP$n$    \> $3\le n\le16$     \> P!$n$ := A\\
SP $b$   \>                   \> P!$b$ := A\\
SPH $h$  \>                   \> P!$h$ := A\\
SPW $w$  \>                   \> P!$w$ := A\\
SG $b$   \>                   \> G!$b$ := A\\
SG1 $b$  \>                   \> G!($b$+256) := A\\
SGH $h$  \>                   \> G!$h$ := A\\
SL $Ln$  \>                   \> variable $Ln$ := A\\
SL\$ $Ln$\>                   \> variable $Ln$ := A
\end{tabbing}
}

\noindent
These instructions are used in the compilation of assignments to named
local, global and static variables. The {\tt SP} instructions are also
used to save anonymous results and to layout function arguments.

\subsection{Indirect Assignment}

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
PBYT     \>                \> B\%A := C\\
XPBYT    \>                \> A\%B := C\\
ST       \>                \> A!0 := B\\
ST$n$    \> $1\le n\le3$   \> A!$n$ := B\\
ST0P$n$  \> $3\le n\le4$   \> P!$n$!0 := A\\
ST1P$n$  \> $3\le n\le4$   \> P!$n$!1 := A\\
STP$n$   \> $3\le n\le5$   \> P!$n$!A := B\\
S0G $b$  \>                \> G!$b$!0 := A\\
S0G1 $b$ \>                \> G!($b$+256)!0 := A\\
S0GH $h$ \>                \> G!$h$!0 := A
\end{tabbing}
}

\noindent
These instructions are used in assignments in which {\tt\%} or
{\tt!} appear as the leading operator on the left hand side.

\subsection{Function and Routine Calls}

At the moment a function or routine is called the state of the stack
is as shown in figure~\ref{cink}. At the entry point of a function or
routine the first argument, if any, will be in register {\tt A} and in
memory {\tt P!3}.

\begin{figure}[tbh!]
\centerline{\includegraphics[width=102.4mm]{bfigs/cink.png}}
\caption{\label{cink}The moment of calling {\tt E(E1,E2,...En)}}
\end{figure}

\pagebreak[4]
{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
K$n$       \> $3\le n\le11$\\
K $b$\\
KH $h$\\
KW $w$
\end{tabbing}
}

\noindent
These instructions call the function or routine whose entry point is in
{\tt A} and whose first argument (if any) is in {\tt B}.
The new stack frame at position {\tt k} relative to {\tt P} where {\tt
k} is $n$, $b$, $h$ or $w$ depending on which instruction is used. The
effect of these instructions is as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        P!k := P    // Save the old P pointer
        P   := P+k  // Set its new value
        P!1 := PC   // Save the return address
        PC  := A    // Set PC to the entry point
        P!2 := PC   // Save it in the stack for debugging
        A   := B    // Put the first argument in A
        P!3 := A    // Save it in the stack
\end{verbatim}
}

\noindent
As can be seen, three words of link information (the old {\tt P}
pointer, the return address and entry address) are stored in the base
of the new stack frame.

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
K$n$G $b$  \> $3\le n\le11$\\
K$n$G1 $b$ \> $3\le n\le11$\\
K$n$GH $h$ \> $3\le n\le11$
\end{tabbing}
}

\noindent
These instructions deal with the common situation where the entry
point of the function is in the global vector and the stack increment
is in the range 3 to 11. The global number {\tt gn} is $b$, $b+256$ or
$h$ depending on which function code is used and stack increment {\tt
k} is $n$.  The first argument (if any) is in {\tt A}.  The effect of
these instructions is as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        P!k := P    // Save the old P pointer
        P   := P+k  // Set its new value
        P!1 := PC   // Save the return address
        PC  := G!gn // Set the new PC value from the global value
        P!2 := PC   // Save it in the stack for debugging
        P!3 := A    // Save the first argument in the stack
\end{verbatim}
}


\pagebreak[3]
{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
RTN
\end{tabbing}
}

\noindent
This instruction causes a return from the current function or routine
using the previous {\tt P} pointer and the return address held in {\tt
P!0} and {\tt P!1}.  The effect of the instruction is as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        PC  := P!1 // Set PC to the return address
        P   := P!0 // Restore the old P pointer
\end{verbatim}
}

\noindent
When returning from a function the result will be in {\tt A}.



\subsection{Flow of Control and Relations}

The following instructions are used in the compilation of conditional
and unconditional jumps, and relational expressions.  The symbol $rel$
denotes {\tt EQ}, {\tt NE}, {\tt LS}, {\tt GR}, {\tt LE} or {\tt GE}
indicating the relation being tested.

\pagebreak[3]
{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
J $Ln$         \> PC := $Ln$\\
J\$ $Ln$       \> PC := $Ln$\\
J$rel$ $Ln$    \> IF B $rel$ A DO PC := $Ln$\\
J$rel$\$ $Ln$  \> IF B $rel$ A DO PC := $Ln$\\
J$rel$0 $Ln$   \> IF A $rel$ 0 DO PC := $Ln$\\
J$rel$0\$ $Ln$ \> IF A $rel$ 0 DO PC := $Ln$
\end{tabbing}
}

\noindent
The destinations of these jump instructions are computed using the
relative addressing mechanism described in
Section~\ref{reladdressing}. Notice than when the comparison is
with zero, {\tt A} holds the left operand of the relation.
 
{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
GOTO           \> PC := A
\end{tabbing}
}

\noindent
This instruction is only used in the compilation of the {\tt GOTO}
command.

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
FHOP           \> A := 0; PC := PC+1
\end{tabbing}
}

\noindent
\label{fhop}The {\tt FHOP} instruction is only used in the compilation 
of relational expressions in non conditional contexts as in the
compilation. The assignment: \verb| x := y < z| is typically compiled
as follows:

{\renewcommand{\baselinestretch}{0.95}\normalsize
\begin{center}
\begin{tabular}{ll}
\tt LP4    & Load \tt y\\
\tt LP5    & Load \tt z\\
\tt JLS 2  & Jump to the {\tt LM1} instruction if {\tt y<z}\\
\tt FHOP   & A := FALSE; and hop over the {\tt LM1} instruction\\
\tt LM1    & A := TRUE\\
\tt SP3    & Store in {\tt x}
\end{tabular}
\end{center}
}

 

\subsection{Switch Instructions}

The instructions are used to implement switches are {\tt SWL} and {\tt
SWB}, switching on the value held in {\tt A}. They both assume that
all case constants are in the range 0 to 65535, with the compiler
taking appropriate action when this constraint is not satisfied.

\bigskip
\noindent
{\tt SWL} {\em filler} $n$ {\em dlab} $L_0$ \ldots $L_{n-1}$

\bigskip
\noindent
This instruction is used when there are sufficient case constants all
within a small enough range. It performs the jump by selecting an
element from a vector of 16~bit resolving half words.  The quantities
$n$, {\em dlab}, and $L_0$ to $L_{n-1}$ are 16~bit half words, aligned
on 16~bit boundaries by the optional filler byte.  If {\tt A} is in the
range 0 to $n-1$ it uses the appropriate resolving half word $L_{\tt
A}$, otherwise it uses the resolving half word {\em dlab} to jump to
the default label. See Section~\ref{reladdressing} for details on how
resolving half words are interpreted.
 
\bigskip
\noindent
{\tt SWB} {\em filler} $n$ {\em dlab} $K_1$ $L_1$ \ldots $K_n$ $L_n$

\bigskip
\noindent
This instruction is used when the range of case constants is too large
for {\tt SWL} to be economical.  It performs the jump using a binary
chop strategy.  The quantities $n$, {\em dlab}, $K_1$ to $K_n$ and
$L_1$ to $L_n$ are 16~bit half words aligned on 16~bit boundaries by
the option filler byte.  This instruction successively tests {\tt A}
with the case constants in the balanced binary tree given in the
instruction. The tree is structured in a way similar to that used in
heapsort with the children of the node at position $i$ at positions
$2i$ and $2i+1$. References to nodes beyond $n$ are treated as null
pointers. Within this tree, $K_i$ is greater than all case constants in
the tree rooted at position $2i$, and less than those in the tree at
$2i+1$.  The search starts at position 1 and continues until a
matching case constant is found or a null pointer is reached. If {\tt
A} is equal to some $K_i$ then {\tt PC} is set using the resolving
half word $L_i$, otherwise it uses the resolving half word {\em dlab}
to jump to the default label. See Section~\ref{reladdressing} for
details on how resolving half words are interpreted.
 
The use of this structure is particularly good for the hand written
machine code interpreter for the Pentium where there are rather few
central registers. Cunning use can be made of the add with carry
instruction ({\tt adcl}). In the following fragment of code,
{\tt\%esi} points to $n$, {\tt\%eax} holds $i$ and {\tt A} is held in
{\tt\%eab}. There is a test elsewhere to ensure that {\tt A} is in the
range 0 to 65535.

\begin{samepage}
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
swb1:  cmpw (%esi,%eax,4),%bx ; { compare A with Ki
       je swb3                ;   Jump if A=Ki
       adcl %eax,%eax         ;   IF A>Ki THEN i := 2i
                              ;           ELSE i := 2i+1
       cmpw (%esi),%ax        ;
       jle swb1               ; } REPEATWHILE i<=n
\end{verbatim}
}
\end{samepage}

\noindent
The compiler ensures that the tree always has at least 7 nodes
allowing the code can be further improved by preceding this loop with
two copies of:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
       cmpw (%esi,%eax,4),%bx ;   compare Ki with A
       je swb3                ;   Jump if match found
       adcl %eax,%eax         ;   IF A>Ki THEN i := 2i
                              ;           ELSE i := 2i+1
\end{verbatim}
}

\noindent
The above code is a great improvement on any straightforward
implementation of the standard binary chop mechanism.


\subsection{Miscellaneous}

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
XCH     \> Exchange {\tt A} and {\tt B}\\
ATB     \> B := A\\
ATC     \> C := A\\
BTC     \> C := B
\end{tabbing}
}

\noindent
These instructions are used move values between register
{\tt A}, {\tt B} and {\tt C}. 


\bigskip
\noindent
{\tt NOP}

\bigskip
\noindent
This instruction has no effect.

\bigskip
\noindent
{\tt SYS}

\bigskip
\noindent
This instruction is used in body of the hand written library routine
{\tt sys}. If {\tt A} is zero, the interpreter returns with exception
code {\tt P!4}.

If {\tt A} is {\tt-1} it sets register {\tt count} to {\tt P!4},
setting {\tt A} to the previous value of {\tt count}. Changing the
value of {\tt count} may change which of the two interpreters is used.
For more details see Section~\ref{interpreter}.

Otherwise, it performs a system operation returning the result in {\tt
A}.  In the C implementation of the interpreter this is done by the
following code:

\pagebreak[3]
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        c = dosys(p, g);
\end{verbatim}
}

 
\bigskip
\noindent
{\tt MDIV}

\bigskip
\noindent
This instruction is used as the one and only instruction in the body
of the hand written library routine {\tt muldiv}, see
Section~\ref{muldiv}.  It divides {\tt P!5} into the double length
product of {\tt P!3} and {\tt P!4} placing the result in {\tt A} and
the remainder in the global variable {\tt result2}. It then performs a
function return ({\tt RTN}).  Its effect is as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        A            := <the result>
        G!Gn_result2 := <the remainder>
        PC           := P!1              // PC      := P!1
        P            := P!0              // P       := P!0
\end{verbatim}
}


\bigskip
\noindent
{\tt CHGCO}

\bigskip
\noindent
This instruction is used in the implementation of coroutines. It is
the one and only instruction in the body of the hand written library
routine {\tt changeco(val,cptr)} where {\tt val} is passed in Cintcode
register {\tt A} and {\tt cptr} is in \verb|P!4|. Its effect, which is
rather subtle, is shown below. For more information see
page~\pageref{changeco}.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim}
  G!Gn_currco!0 := P!0   // !currco := !P  -- changeco's old P pointer
  PC            := P!1   // PC      := P!1 -- changeco's return address
  G!Gn_currco   := P!4   // currco  := cptr
  P             := P!4!0 // P       := !cptr
\end{verbatim}
}



\noindent
{\tt BRK}

\bigskip
\noindent
This instruction is used by the debugger to implement break points. It
causes the interpreter to return with exception code~2.

\subsection{Floating-point Instructions}

Floating-point operations other than those performed by {\tt SELST}
are provided by the {\tt FLTOP} instruction. They are as follows.

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
FLTOP  1  $b$     \> {\tt A := floating point(${\tt A}\times 10^b$)}\\
FLTOP  3          \> {\tt A := FLOAT A}\\
FLTOP  4          \> {\tt A := FIX A}\\
FLTOP  5          \> {\tt A := \#ABS A}\\
FLTOP  6          \> {\tt A := A \#* B}\\
FLTOP  7          \> {\tt A := A \#/ B}\\
FLTOP  8          \> {\tt A := A \#+ B}\\
FLTOP  9          \> {\tt A := A \#- B}\\
FLTOP 10          \> {\tt A := \#+A}\\
FLTOP 11          \> {\tt A := \#-A}\\
FLTOP 12          \> {\tt A := A \verb|#=| B}\\
FLTOP 13          \> {\tt A := A \verb|#~=| B}\\
FLTOP 14          \> {\tt A := A \verb|#<| B}\\
FLTOP 15          \> {\tt A := A \verb|#>| B}\\
FLTOP 16          \> {\tt A := A \verb|#<=| B}\\
FLTOP 17          \> {\tt A := A \verb|#>=| B}\\
\end{tabbing}
}

\noindent
In the above table, $b$ is a signed byte representing a decimal
exponent in the range -128 to +127. Floating point numbers with
exponents outside this range can be generated using {\tt sys(Sys\_flt,
fl\_mk, x, e)} as described on page~\ref{sysfltmk}.

\subsection{Select Instructions}

Access to fields and some {\em op\tt:=} assignment are performed
using the following instructions.

{\renewcommand{\baselinestretch}{0.95}\normalsize\tt
\begin{tabbing}
xxxxxxxxxxxxxxxxxxxx \= $0\le n\le10xxxx$ \= xx \= \kill
SELLD \em len sh     \> {\tt A := SLCT \em len\tt:\em sh\tt:0 OF A}\\
SELST 0 \em len sh   \> {\tt SLCT \em len\tt:\em sh\tt:0 OF A := B}\\
SELST \em op len sh  \> {\tt SLCT \em len\tt:\em sh\tt:0 OF A \em op\tt:= B}\\
\end{tabbing}
}

The mapping between {\em op} and its corresponding expression operator is
given by the table on page~\pageref{assops}.

\subsection{Undefined Instructions}

\noindent
There is now only one undefined instruction and it code is 0. It will cause
the interpreter to return with exception code of 1.

\subsection{Corruption of {\tt B}}

To improve the efficiency of some hand written machine code interpreters,
the following instructions are permitted to corrupt the value held in
{\tt B}:

\bigskip
{\tt K KH KW K$n$ K$n$G K$n$G1 K$n$GH}

{\tt SWL SWB MDIV CHGCO}

\bigskip
\noindent
All other instructions either set {\tt B} explicitly or leave its
value unchanged.

\subsection{Exceptions}

When an exception occurs, the interpreter saves the Cintcode registers
in its register vector and yields the exception number as result.  For
exceptions caused by non existent instructions, BRK, DIV or MOD the
program counter is left pointing to the offending instruction. For
more details see the description of {\tt sys(Sys\_interpret,...)} on
page~\pageref{sysinterpret}.

\section{Example translation of code fragments}

This section contains fragments of BCPL code and their translation
into Cintcode. The purpose of these examples is to consolidate the
reader's understanding of BCPL and show the simplicity of its
translation into Cincode. It also shows the level of optimisation
performed by the compiler. It is easy to see how a fragment of code is
compiled. For instance, consider the program in {\tt z.b}.

\smallskip

{\small
\begin{verbatim}
GLOBAL { w:200; f }

LET f(x) BE WHILE x<10 DO
{ w := x
  IF x=5 BREAK
  x := x+2
}
\end{verbatim}
}      

\smallskip

\noindent
The parse tree for this program can be printed using the following
command.

\smallskip

\begin{samepage}
{\small
\begin{verbatim}
0.000> bcpl z.b tree

32 bit BCPL (30 Oct 2021) with pattern matching, 32 bit target

Parse Tree
GLOBAL  z.b[1]
*-CONSTDEF  z.b[1]
! *-CONSTDEF  z.b[1]
! ! *-Nil
! ! *-NAME: f
! ! *-Nil
! *-NAME: w
! *-NUMBER: 200
*-LET  z.b[3]
  *-RTDEF  z.b[3]
  ! *-NAME: f
  ! *-NAME: x
  ! *-WHILE  z.b[3]
  !   *-LS
  !   ! *-NAME: x
  !   ! *-NUMBER: 10
  !   *-SEQ
  !     *-ASS  z.b[4]
  !     ! *-NAME: w
  !     ! *-NAME: x
  !     *-SEQ
  !       *-IF  z.b[5]
  !       ! *-EQ
  !       ! ! *-NAME: x
  !       ! ! *-NUMBER: 5
  !       ! *-BREAK  z.b[5]
  !       *-ASS  z.b[6]
  !         *-NAME: x
  !         *-ADD
  !           *-NAME: x
  !           *-NUMBER: 2
  *-Nil

OCODE size:    52/400000
\end{verbatim}
}      
\end{samepage}

\smallskip

\noindent
This shows that the parse tree for the {\tt WHILE} command on line 3 of
{\tt z.b} has a first argument representing {\tt x<10} and a second
argument representing a sequence of three commands, the first being
the assigment to {\tt w}. the second being the {\tt IF}statement and
the third being the assignment to {\tt x}.

In addition to outputing the pase tree this command also creates a
file {\tt ocode} of the corresponding Ocode of the program. This can
be printed using the {\tt procode} commnd.

\smallskip

{\small
\begin{verbatim}
0.000> procode
converting ocode to *
ENTRY L10 1  'f'
SAVE 4
LP 3
LN 10
LS
JF L12
LAB L11
LP 3
SG 200
LN 5
LP 3
EQ
JT L12
LN 2
LP 3
ADD
SP 3
LP 3
LN 10
LS
JT L11
LAB L12
RTRN
RTRN
ENDPROC
STACK 3
STORE
GLOBAL 1
     201   L10
\end{verbatim}
}      

\smallskip

\noindent
The corresponding Cintcode translation can be seen using the
compiler's {\tt d1} option.

\smallskip

\begin{samepage}
{\small
\begin{verbatim}
0.001> c b z d1
bcpl z.b to z d1

32 bit BCPL (30 Oct 2021) with pattern matching, 32 bit target
   0:  DATAW #x00000000
   4:  DATAW #x0000DFDF
   8:  DATAW #x2020660B
  12:  DATAW #x20202020
  16:  DATAW #x20202020
// Entry to:   f          
  20: L10:
  20:    L10  
  21:    JGE  L12
  23: L11:
  23:    LP3  
  24:     SG  200
  26:     L5  
  27:    JEQ  L12
  29:     L2  
  30:    AP3  
  31:    SP3  
  32:    L10  
  33:    JLS  L11
  35: L12:
  35:    RTN  
  36:  DATAW #x00000000
  40:  DATAW #x000000C9
  44:  DATAW #x00000014
  48:  DATAW #x000000C9
Code size =    52 bytes of 32-bit little ender Cintcode
0.040>
\end{verbatim}
}      
\end{samepage}

\smallskip

\noindent

You can see from this output that most of the compiled Cintcode
instructions occupy one byte, the only exceptions are the conditional
jumps and the {\tt SG} instruction. Note that the {\tt WHILE} loop
conditions {\tt x<10} is evaluated before the body is executed for the
first time and also at the end of the body. This strategy is used
since the code at both places can be compiled more efficiently, and if
the result of the initial test can be determined at compile time, a
conditional jump is not required.

The actual compiled code was placed in the file {\tt z} which is a
text file of hexdecimal words.

\smallskip

{\small
\begin{verbatim}
0.001> type z
000003E8 0000000D 
0000000D 0000DFDF 2020660B 20202020 20202020 830DBC1A 1C15C831 A3C31207 
7BF55C1A 00000000 000000C9 00000014 000000C9 
\end{verbatim}
}      

\smallskip

\noindent
Note that this contains the bytes of the compiled code prefixed by the
two words {\tt 000003E8 0000000D} saying that the compiled code is a
hunk consisting of 13 (0000000D) 32 bit words. The word at location
zero has been updated with this size now that it is known.

Most of the BCPL code fragments in this section are take from programs
in the directories {\tt cintcode/com} and {\tt cintcode/sysb}. The
Cintcode translation of the BCPL compiler was placed in {\tt bcpl.cin}
by the command:
\smallskip


{\tt bcpl com/bcpl.b to junk d1 ver bcpl.cin}.

\subsection{Translation of {\tt mk1}}

The definition of {\tt mk1} is:

\smallskip

{\small
\begin{verbatim}
AND mk1(x) = VALOF
{ LET p = newvec(0)
  p!0 := x
  RESULTIS p
}
\end{verbatim}
}      

\smallskip

\noindent
Its Cintcode translation is:

\smallskip

{\small
\begin{verbatim}
// Entry to:   mk1        
9200: L576:
9200:     L0  
9201:   K4G1   67
9203:    SP4  
9204:    LP3  
9205:  ST0P4  
9206:    LP4  
9207:    RTN  
\end{verbatim}
}      

\smallskip

\noindent
The call {\tt newvec(0)} is compiled as \verb|L0 K4G1 67| because {\tt
  newvec} is in global 323 (=67+256). The variable p is in stack
location P4 so the assignment to p!0 can be performed by {\tt ST0P4}.

\subsection{Translation of {\tt mk2}}

The definition of {\tt mk2} is:

\smallskip

{\small
\begin{verbatim}
AND mk2(x, y) = VALOF
{ LET p = newvec(1)
  p!0, p!1 := x, y
  RESULTIS p
}
\end{verbatim}
}      

\smallskip

\noindent
Its Cintcode translation is:

\smallskip

{\small
\begin{verbatim}
// Entry to:   mk2        
9224: L577:
9224:     L1  
9225:   K5G1   67
9227:    SP5  
9228:    LP3  
9229:    XCH  
9230:     ST  
9231:    LP4  
9232:    LP5  
9233:    ST1  
9234:    LP5  
9235:    RTN  
\end{verbatim}
}      

\smallskip

\noindent
Here the assignment to {\tt p!0} is compiled by \verb|LP3 XCH ST|
since Cintcode does not have the instruction {\tt ST0P5}. Note that
even though {\tt p} is in the {\tt A} register just before the
instruction {\tt ST1} it must be reloaded after the indirect
assignment since the compiler cannot assume that {\tt ST1} will not
change the value of {\tt p}.

\subsection{Translation of {\tt rnamelist}}

The definition of {\tt rnamelist} is:

\smallskip

{\small
\begin{verbatim}
AND rnamelist() = VALOF
{ // Read a list of names each possibly prefixed by FLT
  LET a = rname()
  UNLESS token=s_comma RESULTIS a
  lex()
  RESULTIS mk3(s_comma, a, rnamelist())
}
\end{verbatim}
}      

\smallskip

\noindent
Its Cintcode translation is:

\smallskip

\begin{samepage}
{\small
\begin{verbatim}
// Entry to:   rnamelist  
11152: L641:
11152:   K3G1   47
11154:    SP3  
11155:      L   37
11157:    LG1   18
11159:    JEQ  L678
11161:    LP3  
11162:    RTN  
11163: L678:
11163:   K4G1   23
11165:   K9G1   46
11167:    SP9  
11168:    LP3  
11169:    SP8  
11170:      L   37
11172:   K4G1   60
11174:    RTN  
\end{verbatim}
}
\end{samepage}

\smallskip

\noindent
It starts by calling {\tt rname} (G303=47+256) and saving the result
in stack location P3 for variable {\tt a}. If {\tt token} is not equal
to {\tt s\_comma} (=37), it returns from {\tt rnamelist} with {\tt a}
as the result. If the token was {\tt s\_comma} it calls {\tt lex}
(G279) then makes a recursive call of {\tt rnamelist} storing the
result in stack location P9, the position of {\tt mk3}'s third
argument. The second argument at P8 is given the value {\tt a} (P3),
and the first argument {\tt s\_comma} (=37) is loaded into register
{\tt A}. The call of {\tt mk3} (G316) is made by {\tt K4G1~60} and its
result immediately becomes the result of {\tt rnamelist}.


\subsection{Translation of {\tt trnext}}

The definition of {\tt trnext} is:

\smallskip

{\small
\begin{verbatim}
LET trnext(next) BE
{ // Compile code to follow a command
  // next is >0, =0 or =-1
  
  IF next=0 RETURN // No code to compile.
  
  IF next>0 DO { out2(s_jump, next); RETURN }
  
  // next must be =-1
  TEST proccontext=s_fnrn
  THEN { out2(s_ln, 0); out1(s_fnrn) }
  ELSE { out1(s_rtrn) }
}
\end{verbatim}
}      

\smallskip

\noindent
Its Cintcode translation is:

\smallskip

\begin{samepage}
{\small
\begin{verbatim}
// Entry to:   trnext     
 664: L37:
 664:   JNE0  L38
 666:    RTN  
 667: L38:
 667:    LP3  
 668:   JLE0  L39
 670:    SP8  
 671:      L  146
 673:   K4G1  148
 675:    RTN  
 676: L39:
 676:      L  156
 678:    LG1  135
 680:    JNE  L40
 682:     L0  
 683:    SP8  
 684:      L  136
 686:   K4G1  148
 688:      L  156
 690:   K4G1  147
 692:    RTN  
 693: L40:
 693:      L  157
 695:   K4G1  147
 697:    RTN  
\end{verbatim}
}
\end{samepage}

\smallskip

\noindent
If the argument {\tt next} is zero it returns from {\tt trnext}
immediately. At label L39 we know that the {\tt A} register still
holds {\tt next} but since the compiler assumes that there may be
other instructions jumping to this label it has to reload {\tt next}
using {\tt LP3} before testing whether it is greater than zero. If it
is {\tt A} still holds {\tt next} and can be placed in stack location
P8, the location of the second argument of {\tt out2}. The first
argument {\tt s\_jump} (=146) is then loaded into {\tt A} ready for the
call {\tt H4G1 148} of {\tt out2} (G404=148+256). The remaining code
for this routine is straightforward.





\pagebreak

\subsection{Translation of {\tt tst} in {\tt patcmpltest.b}}

The definition of {\tt trt} is:

\smallskip

{\small
\begin{verbatim}
    // p -> [101, 102, 103, [201, [301,302,303], 203], 105, 106]
    
    LET tst : [a1, a2, a3, [a41, [a421,a422,a423], a43], a5, a6] BE
    { t(a1,   101)
      t(a2,   102)
      t(a3,   103)
      t(a41,  201)
      t(a421, 301)
      t(a422, 302)
      t(a423, 303)
      t(a43,  203)
      t(a5,   105)
      t(a6,   106)
    }
\end{verbatim}
}      

\smallskip

\noindent
As can be seen in the Cintcode translation below pattern variables can
be accessed with reasonable efficiency. The table below shows the code
sequence used to access each of the pattern variables used in this
function.

\smallskip

\begin{center}
\begin{tabular}{l|l|l}
  Variable & Code to load the value & Equivalent to \\
  \hline \\
  \tt a1    & \tt L0P3         & \tt p!0     \\
  \tt a2    & \tt L1P3         & \tt p!1     \\
  \tt a3    & \tt L2P3         & \tt p!2     \\
  \tt a41   & \tt L3P3 RV      & \tt p!3!0   \\
  \tt a421  & \tt L3P3 RV1 RV  & \tt p!3!1!0 \\
  \tt a422  & \tt L3P3 RV1 RV1 & \tt p!3!1!1 \\
  \tt a423  & \tt L3P3 RV1 RV2 & \tt p!3!1!2 \\
  \tt a43   & \tt L3P3 RV2     & \tt p!3!2   \\
  \tt a5    & \tt L4P3         & \tt p!4     \\
  \tt a6    & \tt LP3 RV5      & \tt p!5     \\
\end{tabular}
\end{center}

\smallskip

\noindent
If we call the argument of {\tt tst} {\tt p}, we see that the pattern
variable {\tt a1} is equivalent to {\tt p!0} so if the argument is
updated the location referenced by {\tt a1} will change. Similarly,
{\tt a41} depends on both {\tt p} and {\tt p!3}, so if either of these
change the location referenced by {\tt a41} may change. This effect
means great care is needed when defining functions which update
pattern variables during their evaluation. The function {\tt splay} is
a prime example of this kind of function and should be studied with
care. The source code can be found in {\tt BCPL/bcplprogs/patdemos/splay.b}.



\smallskip

\pagebreak
{\small
\begin{verbatim}
// Entry to:   tst        
 768: L52:
 768:      L  101
 770:    SP8  
 771:   L0P3  
 772:    K4G  207
 774:      L  102
 776:    SP8  
 777:   L1P3  
 778:    K4G  207
 780:      L  103
 782:    SP8  
 783:   L2P3  
 784:    K4G  207
 786:   L3P3  
 787:     RV  
 788:      L  201
 790:    SP8  
 791:    XCH  
 792:    K4G  207
 794:   L3P3  
 795:    RV1  
 796:     RV  
 797:     LH  301
 800:    SP8  
 801:    XCH  
 802:    K4G  207
 804:   L3P3  
 805:    RV1  
 806:    RV1  
 807:     LH  302
 810:    SP8  
 811:    XCH  
 812:    K4G  207
 814:   L3P3  
 815:    RV1  
 816:    RV2  
 817:     LH  303
 820:    SP8  
 821:    XCH  
 822:    K4G  207
 824:   L3P3  
 825:    RV2  
 826:      L  203
 828:    SP8  
 829:    XCH  
 830:    K4G  207
 832:      L  105
 834:    SP8  
 835:   L4P3  
 836:    K4G  207
 838:    LP3  
 839:    RV5  
 840:      L  106
 842:    SP8  
 843:    XCH  
 844:    K4G  207
 846:    RTN  
 848:  DATAH L21-$
 850: L54:
 850:     L0  
 851:    RTN  
\end{verbatim}
}

\smallskip

\noindent
The {\tt DATAH} statement near the end is a 16 bit relative address
resolving word for label L21 which has nothing to do with the
compilation of {\tt tst}.

\subsection{Translation of {\tt coins} and {\tt c} in {\tt patdemos/coins.b}}

The following function definitions are taken from the coins program 
{\tt coins.b}.

\smallskip

{\small
\begin{verbatim}
LET coins
: sum => c(sum,
           TABLE 200, 100, 50, 20, 10, 5, 2, 1)
AND c
: <0          => 0
: 0 | (?,[1]) => 1
: sum, t[d]   => c(sum, t+1) + c(sum-d, t)
\end{verbatim}
}      

\smallskip

\noindent
The translation of {\tt coins} is as follows.

\smallskip

{\small
\begin{verbatim}
// Entry to:   coins      
  36: L10:
  36:    LLL  L13
  38:    SP8  
  39:    XCH  
  40:     LF  L11
  42:     K4  
  43:    RTN  
  44: L12:
  44:     L0  
  45:    RTN  
  48: L13:
  48:  DATAW #x000000C8
  52:  DATAW #x00000064
  56:  DATAW #x00000032
  60:  DATAW #x00000014
  64:  DATAW #x0000000A
  68:  DATAW #x00000005
  72:  DATAW #x00000002
  76:  DATAW #x00000001
\end{verbatim}
}

\smallskip

\noindent
The only oddity here is the code labelled L12 can never be executed
since the match item pattern will always be successful.  The
translation of the function {\tt c} is as follows and is more
interesting.

\smallskip

{\small
\begin{verbatim}
// Entry to:   c        LET c          
  96: L11:
  96:   JGE0  L14       : <0
  98:     L0                 => 0
  99:    RTN  
 100: L14:

 100:    LP3            : 0 |
 101:   JEQ0  L16
 103:   L0P4                   (?,[1])
 104:     L1
 105:    JNE  L15
 107: L16:
 107:     L1                            => 1    
 108:    RTN  
 109: L15:              : sum, t[d]
 109:     L1                        => c(sum, t+1) +
 110:    AP4  
 111:    SP9  
 112:    LP3  
 113:     LF  L11
 115:     K5  
 116:    SP5  

 117:    LP3                           c(sum-d, t)
 118:   L0P4  
 119:    SUB  
 120:    LP4  
 121:   SP10  
 122:    XCH  
 123:     LF  L11
 125:     K6  

 126:    AP5  
 127:    RTN  
 128: L19:              Unnecessary code
 128:     L0  
 129:    RTN  
\end{verbatim}
}

\smallskip

\noindent
In the second call of {\tt c} it would have been better to place {\tt
  t} in P10 before evaluating {\tt sum-d}.



\subsection{Translation of {\tt rotleft} from {\tt patdemos/splay.b}}

The definition of {\tt rotleft} is:

\smallskip

{\small
\begin{verbatim}
AND rotleft    // Promote right child      p          p
: n[key, val,                         //   |          |
    np[?,?,?,npl,npr],                //   n    =>    r
    nx,                               //  / \        / \
    nr[?,?,nrp,nry[?,?,nryp,?,?],nrz] // x   r      n   z
   ] BE                               //    / \    / \
                                      //   y   z  x   y
{ LET y = nry
  // The order of the assigments was chosen with great care.

  TEST np              // Test if n has a parent.
  THEN TEST n=npl
       THEN npl := nr  // Update the parent's left branch.
       ELSE npr := nr  // Update the parent's right branch.
  ELSE root := nr      // n has no parent, so r is the new root.
  IF nry DO nryp := n  // If y exists, its parent should be n.

  nrp := np
  nry := n
  np  := nr
  nr  := y
}
\end{verbatim}
}      

\smallskip

\noindent
This function makes a simple rearrangement of the nodes close to a
given node {\tt n} in a splay tree. A splay tree of a binary tree of
key-value pairs with each node being of the form:
\verb|[key val parent left right]|. The fields {\tt parent}, {\tt
  left} and {\tt right} are pointers to other nodes but may be null.

The function has just one match item which contains a pattern that
only contains pattern variable declarations so always matches its
argument. The variable names are chosen to make it easy to tell which
variables depend on other pattern variables. For instance {\tt nryp}
depends on {\tt nrp}, {\tt nr} and {\tt n}. We therefore know that an
assignment to {\tt nryp} must typically be made before updating {\tt
  nr}.

The pattern and its declared variables are valid even when some of the
pointers are null. For instance, the variables {\tt npl} and {\tt npr}
should only be accessed when {\tt np} is known to be non null.

The Cintcode translation of {\tt rotleft} starts as follows:

\smallskip

{\small
\begin{verbatim}
// Entry to:   rotleft    
 392: L18:
 392:   L4P3               LET y = nry 
 393:    RV3  
 394:    SP4  
\end{verbatim}
}      

\smallskip

\noindent
Notice that the pattern variable {\tt nry} is accessed efficiently by
two single byte Cintcode instructions. As will be seen even deeply
nested pattern variables are accessed with reasonable efficiency.

\smallskip

{\small
\begin{verbatim}
 395:   L2P3               TEST np
 396:   JEQ0  L45
 398:    RV3               THEN TEST n=npl
 399:    LP3  
 400:    JNE  L47
 402:   L4P3                    THEN npl := nr
 403:   L2P3  
 404:    ST3  
 405:      J  L46
 407: L47:
 407:   L2P3                    ELSE npr := nr
 408:     A4  
 409:   L4P3  
 410:    XCH  
 411:     ST  
 412:      J  L46
 414: L45:
 414:   L4P3               ELSE root := nr
 415:     SG  204
 417: L46:
\end{verbatim}
}      

\smallskip

\noindent
Notice that the assignment to {\tt npr} is slightly less efficient
than the assignment to {\tt npl}. This is because Cintcode has the
instruction {\tt ST3} but not {\tt ST4}.

\smallskip

{\small
\begin{verbatim}
 417:   L4P3         IF nry
 418:    RV3  
 419:   JEQ0  L48
 421:   L4P3                DO nryp := n
 422:    RV3  
 423:    LP3  
 424:    XCH  
 425:    ST2  
 426: L48:
\end{verbatim}
}      

\smallskip

\noindent
Even though the pattern variable {\tt nryp} is deeply nested the
assignment is still reasonably efficient.

\smallskip

\begin{samepage}
{\small
\begin{verbatim}
 426:   L2P3         nrp := np
 427:   L4P3  
 428:    ST2  

 429:    LP3         nry := nr
 430:   L4P3  
 431:    ST3  

 432:   L4P3         np := nr
 433:    LP3  
 434:    ST2  

 435:    LP4         nr := y
 436:     L4  
 437:   STP3  

 438:    RTN  
\end{verbatim}
}      
\end{samepage}

\smallskip

\noindent
Note that the four assignments above are each implemented by three
single byte Cintcode instructions.







\cleardoublepage

\chapter{The BCPL Compiler}

The previous chapters have given the definition of BCPL, Ocode and
Cintcode. This chapter gives a brief outline of design of the BCPL
compiler. The reason for this chapter is the it provides a example of
how BCPL can be used to implement a reasonably significant program,
and it may help to consolidate the readers understanding of the
language.

The compiler is quite small and easy to understand partly
because BCPL is so simple and its translation into Cintcode needs
little optimisation. It is just an ordinary command with its source
code in the directory {\tt cintcode/com} which contains the source
of all the  other standard commands.

If the system has been installed in the standard way, all its files
will be in the directory {\tt distribution/BCPL} in the user's home
directory.  The directory {\tt BCPL} contains various subdirectories.
The directory {\tt g} holds header files such as {\tt libhdr.h} which
contains declarations of all the standard library functions. It also
declares library variables and constants needed by most programs.
Other header files such as {\tt sdl.h} and {\tt gl.h} provide optional
declarations of less frequently used packages, in this case the SDL
graphics library and Open GL. Some files in {\tt g} such as {\tt
  sdl.b} and {\tt gl.b} contain contain actual definitions of
functions needed by these packages. One header file of particular
relevence to the BCPL compiler is {\tt bcplfecg.h}.  This is used by
programs closely related to the compiler such as {\tt com/bcplsyn.b}
and {\tt bcplcgcin.b}.  Files in directory {\tt g} are normally
included in programs using {\tt GET} directives}.

The main source of the BCPL compiler is the file {\tt com/bcpl.b} but
this essentially just contains {\tt GET} directives to include the
three components of the compiler, namely {\tt bcplsyn.b}, {\tt
  bcpltrn.b} and {\tt bcplcgcin.b}. If run under the BCPL Cintcode
system when the current working directory is {\tt
  \~/distribution/BCPL/cintcode}, the compiler can be recompiled using
the command: {\tt c bc bcpl}. This places the compiled code in
directory {\tt cintcode/cin} which is the normal place for all
compiled standard commands. On a Raspberry Pi 5 compiling the compiler
takes less a second. The components of the compiler are briefly
described in turn.

\section{Lexical Analyser}

The lexical analyser and syntax analyser are combined in the file {\tt
  bcplsyn.b}. When the syntax analyser requires another lexical token
it calls the lexical analyser function {\tt lex()} which updates the
variable {\tt token} with a value representing the next
token. Sometimes {\tt lex} places additional information in other
variables such as {\tt wordnode} {\tt decval}, {\tt fltval}, It also
sets {\tt lineno} to hold word containing the packed file and line
number of the latest token. It sets {\tt nlpending} to {\tt TRUE} if
the latest token is the first token on an input line.

Much of the implementation of {\tt lex} is trivially simple switching
on the next character of input, normally held in the variable {\tt ch}
to decide what to do. Some characters such as spaces and tabs are just
skipped over and several others such as {\tt ';'}, {\tt ','} and {\tt
  '@'} repesent tokens directly, while others such as {\tt '<'} may
require a single character lookahead to determine whether the token is
{\tt <=}, {\tt <<} or just {\tt <}. The lexical analysis of names is
more involved since some names, such as {\tt WHILE} or {\tt ABS}, are
reserved words.  When a name in not a reserved word, {\tt token} is
set to {\tt s\_name} with {\tt wordnode} pointing to its parse tree
node. Multiple occurrences of the same name share the same name node.
This allows the equality of pointers to be used an efficient test of
whether two names are indeed the same. To implement this, a hash table
is used to hold lists of name nodes. When a name is encountered its
hash value is determined and only name nodes with the same hash value
need to be inspected.  To implement this name nodes have a link field
holding a pointer to the next node in its hash chain.  In the
translation phase when name nodes are no longer being created this
link field is used for another purpose.

The first word of every node of the parse tree identifies what what it
represents.  For name nodes this field is given the constant value
{\tt s\_name}. The use of this hash table mechanism allows the table
to be preset with nodes for all the reserved words, placing the
appropriate token values in their first words.

The hash table is also used to hold section bracket tags and the tags
used by the conditional compilation mechanism. These nodes have their
name strings starting with dollar signs to avoid confusion with
ordinary variable names and reserved words.

Parse tree nodes could be allocated using {\tt getvec} but it is more
convenient and efficient to use an alternative space allocator called
{\tt newvec}. This obtains fairly large blocks of memory as needed
using {\tt getvec} allocating the typically small parse tree nodes
from such blocks. When the parse tree is no longer needed it can be
returned efficiently to free store without having to return every
parse tree node individually.

Integer constants have their values placed in {\tt decval} and floating
point constants use {\tt fltval} to hold the floating point
value. String constants do not use the hash table but do use {\tt
  wordnode} to pass newly created string constant nodes to the syntax
analyser.

There is a vector {\tt charv} that holds a circular buffer of recent
characters of input. This is used when generating error messages
detected during lexical and syntax analysis. The vector {\tt getv} is
used in the implementation of {\tt GET} directives. It holds a stack
of items containg the current selected input stream, the current file
and line number.

\section{Syntax analyser}

The syntax analyser takes a stream of lexical tokens obtained by
successive calls of {\tt lex()}. It recognises the syntactic
constructs and creates a tree representing the parsed program in a
form that is convenient for the next phase of the compilation. The
program is easy to understand since it is a direct implementaions of
the recursive descent parser specified by the flow graphs in Appendix
\ref{syntax}. To illustrate the way these flow graphs are implemented
in BCPL we will look at the definition of {\tt rdmatchlist} which
reads sequences of match items used in {\tt MATCH} expressions and
some function definitions. This function is given the argument {\tt
  s\_yields} or {\tt s\_be} indicating whether the match list is
selecting an expression or a command. This argument is zero if the
kind of match list is not yet known. The flow graph for match lists
is as follows:

\medskip

\centerline{\includegraphics[width=101.6mm]{bfigs/b-mlist.png}}

\medskip

\noindent
The defintion of {\tt rdmatchlist} is as follows:

\medskip
{\small
\begin{verbatim}
AND rdmatchlist(sort) = VALOF
{ // Return the parse tree for the match list.
  // Return in result2 {\tt s_yields} or {\tt s_be}
  // indicating which kind of match list was found.
  LET res = rdmatchitem(sort) // Read the first match item
  LET lastitem = res
  sort := result2

  WHILE token=s_colon DO
  { LET item = rdmatchitem(sort)
    h4!lastitem := item
    lastitem := item
  }
  IF token = s_dot DO lex() // The final dot is optional
  result2 := sort
  RESULTIS res
}
\end{verbatim}
}

\smallskip
\noindent
This function calls {\tt rdmatchitem} to read match items forming them
into a list.  Match item nodes have five elements the first is the
operator {\tt s\_matchiteme} or {\tt s\_matchitemc} indicating the
kind of match item.  The {\tt h2} and {\tt h3} fields hold the item's
pattern list and expresion or command. The {\tt h4} field holds a link
to the next match item, if any, and the final field holds the packed
file and line number. The deinition of {\tt rdmatchitem} is as
follows:

\medskip
{\small
\begin{verbatim}
AND rdmatchitem(sort) = VALOF
{ // sort is either s_yields or s_be or zero if not yet known.

  // It returns a pointer to a match item with a null link, ie
  //       [ matchiteme, Plist, E, 0, ln ]
  // or    [ matchitemc, Plist, C, 0, ln ]

  // result2 is set to s_yields or s_be, as appropriate

  LET res = 0
  LET patlist = 0
  LET ln = lineno

  UNLESS token = s_colon DO
    synerr("A match item must start with a ':'")
  
  lex() // Skip over the colon

  UNLESS token=s_yields | token=s_be DO
  { // There must be a pattern if token is not => or BE 
    patlist := rpat(0)
    UNLESS token=s_yields | token=s_be DO
      synerr("token is %s when => or BE expected", opname(token))
  }
  UNLESS sort DO sort := token
  ln := lineno  // The line number of => or BE

  // Check that then defining operator in all match item are the same.
  UNLESS sort=token
    TEST sort=s_yields
    THEN paterr("*nThe defining operator in this match item should be '=>'")
    ELSE paterr("*nThe defining operator in this match item should be 'BE'")

  TEST sort=s_yields
  THEN res := mk5(s_matchiteme, patlist, rnexp(0), 0, ln)
  ELSE res := mk5(s_matchitemc, patlist, rncom(),  0, ln)

  result2 := sort
  RESULTIS res
}
\end{verbatim}
}

\smallskip

\noindent
Notice that the pattern between {\tt:} and \verb|=>| or {\tt BE}
is optional as specified by the flow graph. If a pattern is present it
is read by the call of {\tt rpat(0)} correponding to
\raisebox{-6pt}{\includegraphics[width=12.9mm]{bfigs/sym-pat0.png}}. If
after the pattern it then encounters \verb|=>| it calls {\tt rnexp(0)}
which calls {\tt lex()} before returning the result of {\tt rexp(0)},
but if it encounters {\tt BE} it calls {\tt rncom()} to read a
command.

As the syntax analyser runs it creates a parse tree of typically small
nodes. They are allocated using {\tt newvec} as used by {\tt lex} when
allocating name nodes. For convenience most tree nodes are allocated
using functions such {\tt mk5} that allocates a node of specified size
and sets its elements. Notice that the packed file and line number of
the {\tt:} at the start of the current match item was saved in {\tt ln}
and placed in the fifth element of the match item node.

Every recursive descent function, such as {\tt rdmatchitem} and {\tt
  rexp}, follow the same convention that on entry {\tt token} will be
the first token of the construct to be parsed, and on exit {\tt token}
will be the first token following the construct just read. For many
such functions it is useful to have auxiliary functions that
call {\tt lex()} before calling the recursive descent function
itself. We have already seen two examples {\tt rnpat} and {\tt rnexp}.

The function {\tt rpat} parses a pattern based on the folllowing flow graph.

\smallskip

\centerline{\includegraphics[width=131.0mm]{bfigs/b-pat.png}}

\smallskip
\noindent
It definition is as follows:

\smallskip

{\small
\begin{verbatim}
AND rpat(n) = VALOF
{ // Returns zero if token cannot start a pattern.
  // otherwise return it parse tree.

  LET pat = rspat() // Read a simple pattern not involving
                    // comma, vertical bar or juxtapositions.
  UNLESS pat RESULTIS 0

  { // Repeatedly combine pat with other simple patterns
    // separated by commas, vertical bars and juxtapositions
    // depending on the precedence n.

    SWITCHON token INTO
    { DEFAULT:
        // token is not s_comma or s_logor but
        // juxtaposition is possible.
        IF n<3 DO
        { // Juxtaposition is allowable
          LET b = rpat(3)
          IF b DO
          { pat := mk3(s_patand, pat, b)
            LOOP
          }
        }
        // Juxtaposition was not possible
        RESULTIS pat

      CASE s_comma:
        UNLESS n<1 RESULTIS pat // Comma is not allowed
        lex()
        pat := mk3(s_comma, pat, rpat(1))
        LOOP
        
      CASE s_logor:
        UNLESS n<2 RESULTIS pat // Vertical bar not allowed
        lex()
        pat := mk3(s_pator, pat, rpat(2))
        LOOP
    }
  } REPEAT        
}
\end{verbatim}
}

\medskip
\noindent
This function starts by calling {\tt rspat} to read a simple pattern
not involving commas, vertical bars or juxtapositions.  This
corresponds to the left side of the flowgraph. It then enters a loop
that combines this pattern with other simple patterns forming {\tt
  s\_comma}, {\tt s\_pator} or {\tt s\_patand} nodes, as appropriate
provided the precedence value {\tt n} is suitable.

The function that reads a simple pattern is straightforward and is as follows:

\medskip
{\small
\begin{verbatim}
AND rspat() = VALOF
{ // Attempt to read a simple basic, ie one that does not
  // include comma. vertical bar or juxtaposition at the
  // outermost level.

  // It returns zero if token cannot start a pattern.

  LET pat = 0
  LET op = token
  SWITCHON op INTO
  { DEFAULT:
    { pat := rbpat()
      UNLESS pat RESULTIS 0
      IF token=s_range | token=s_frange DO
      { LET op = token
        LET b = rnbpat()
        UNLESS b DO
          synerr("Problem with the right hand operand of a range")
        RESULTIS mk3(op, pat, b)
      }
      RESULTIS pat 
    }

    // All the tokens in relop
    CASE s_eq:    CASE s_feq:
    CASE s_ne:    CASE s_fne:
    CASE s_le:    CASE s_fle:
    CASE s_ge:    CASE s_fge:
    CASE s_ls:    CASE s_fls:
    CASE s_gr:    CASE s_fgr:
    { LET patrelop = rel2patrel(token)
      lex()
      IF token=s_lparen DO
      { pat := mk2(patrelop, rnexp(0))               // patrelop ( E )
        UNLESS token=s_rparen DO
          synerr("*n   There is a problem with the expression enclosed*n*
                 *   in parentheses following a relational operator.")
        lex() // Skip over the close parenthesis
        RESULTIS pat
      }

      { // The operand must be a bpat
        LET b = rbpat()
        UNLESS b DO
          synerr("Bad relational expression in a pattern")
        RESULTIS mk2(relop, b)
      }
    }

    // All the tokens belonging to jcom.
    CASE s_break:
    CASE s_loop:
    CASE s_endcase:
    CASE s_next:
    CASE s_exit:
    CASE s_return:
      RESULTIS rbcom()

    CASE s_lparen:
      pat := rnpat(0)                // ( P0 )
      UNLESS pat & token=s_rparen DO
        synerr("There is a problem with a pattern enclosed in parentheses")
      lex() // Skip over the close parenthesis
      RESULTIS mk2(s_patseq, pat)

    CASE s_sbra:
      pat := rnpat(0)                // [ P0 ]
      UNLESS pat & token=s_sket DO
        synerr("There is a problem with a pattern enclosed in square brackets")
      lex() // Skip over the close square bracket
      RESULTIS mk2(s_patptr, pat)

    CASE s_flt:
      // Note a name not preceeded by FLT will have been read
      // rbpat() above.
      lex()
      UNLESS token=s_name DO synerr("A name must follow FLT")
      RESULTIS mk2(s_flt, wordnode)
  }
}
\end{verbatim}
}

\medskip
As can be seen it follows precisely the parsing algorithm specified by
the flow graph. It uses {\tt rbpat} whenever it needs to read a basic
pattern. The definition of {\tt rbpat} is as follows:

\medskip

{\small
\begin{verbatim}
AND rbpat() = VALOF
{ // Attempt to read a basic pattern,
  // ie a possibly signed integer or floating point constant.
  // a character constant, TRUE, FALSE, BITSPERBCPLWORD, ?,
  // or a name not preceeded by FLT.

  SWITCHON token INTO
  { DEFAULT:
      RESULTIS 0

    CASE s_number:
    CASE s_fnum:
    CASE s_true:
    CASE s_false:
    CASE s_query:
    CASE s_name:
      RESULTIS rbexp()

    CASE s_add: CASE s_fadd:
    CASE s_sub: CASE s_fsub:
    CASE s_abs: CASE s_fabs:
    { LET op = token
      lex()
      UNLESS token=s_number | token=s_fnum DO
         synerr("A number must follow a monadic sign operator in a pattern")
      RESULTIS mk2(op=s_add  -> s_pos,   // Use the monadic version
                   op=s_fadd -> s_fpos,  // of + and -.
                   op=s_sub  -> s_neg,
                   op=s_fsub -> s_fneg,
                   op,                   // op is s_abs or s_fabs
                   rbexp())
    }
  }
}
\end{verbatim}
}

\smallskip
\noindent
Notice that dyadic operators are converted to their monadic versions
as necessary, and that the operator {\tt ABS} is treated as a sign
since it corresponds to monadic plus or minus depending on the sign of
its operand.

This completes the summary of how patterns are parsed. The parsing of
expressions, command and definitions are done using the functions {\tt
  rexp}, {\tt rcom} and {\tt rdef}. Their implementation is as easy to
understand as those that parsed patterns and so will not be described
here.

There are however some slight subtleties. One is in the treatment of
so called simultaneous assignments. In BCPL these are not simultaneous
but are executed as a sequence of simple assignments from left to
right. For instance the asignment:

{\small
\begin{verbatim}
        a, b, c := x, y, z
\end{verbatim}
}

\smallskip
\noindent
is precisely equivalent to the following:

\smallskip

{\small
\begin{verbatim}
        { a := x; b := y; c := z }
\end{verbatim}
}

\smallskip
\noindent
This tranformation is done during syntax analysis using the function
{\tt cvassign}. This became necessary when the {\tt FLT} feature was
added to the language since some of the individual assignments may be
given the {\tt FLT} tag. There is a similar transformation required in
simultaneous definitions.

One function {\tt plist} is defined in {\tt bcplsyn.b} but is not
strictly part of the syntax analyser since it is only used as a
debugging aid to output the parse tree is a readable form.  But its
definition is useful since it can be regarded as a description of the
structure of every kind of node in the parse tree. If you compile the
following program with the {\tt tree} option it will output the following
representation of the parse tree.

LET f : a, [-2, y] => a + y

OCODE size:    40/400000


\section{The translation phase}

\section{The Codegenerator}




\cleardoublepage

\chapter{The Design of Sial}

Sial is an internal intermediate assembly language designed for BCPL.
The first version was called Cial (Compact Internal Assembly Language)
was pronounced ``seal''. It was essentially an assembly language for
Cintcode with the same function code mnemonics and the same abstract
machine registers. It was soon found that rather than having a variety
of codes to load an integer constant (such as {\tt L0}, {\tt L1}, {\tt
  L2}, {\tt LM1}, {\tt LW}, {\tt LH} or {\tt L}), it was better to
have one function code to load positive integers and another for
negative ones with the values specified by operands. This form is more
convenient for translation and easier to compress. The new language is
called Sial (also pronouced ``seal'') with the S standing for smaller.
Sial therefore has fewer function codes than Cintcode and most of them
take operands but still uses the same abstract machine
registers. Although Cintcode load instructions save the value of the
{\tt A} register in {\tt B} before setting {\tt A}, Sial loads
typically do not. The current version of Sial has not yet been updated
to deal with the extended BCPL features such as floating point and
{\em op\tt:=} assignments.

As as example of the use of Sial, consider the program {\tt
  com/hello.b} which is as follows:

\medskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
GET "libhdr"

LET start() = VALOF
{ writef("Hello*n")
  RESULTIS 0
}
\end{verbatim}
}

\medskip
\noindent
This can be translated into Sial using {\tt bcpl2sial com/hello.b to
  hello.sial}. The resulting file is:
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
F104
F113 K5 C115 C116 C97 C114 C116
F111 L1
F112 M9001
F32 P3 G94
F11 K0
F77
F107 M9001 K6 C72 C101 C108 C108 C111 C10
F106 K1 G1 L1 G94
F105
\end{verbatim}
}

\medskip
\noindent
This can be converted into something slightly more readable using the
command: {\tt sial-sasm hello.sial to *} giving:
\medskip
\noindent
This can be translated into Sial using the {\tt bcpl2sial} command as follows.

\medskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
0.010> sial-sasm hello.sial to *
Converting hello.sial to *
MODSTART

//Entry to: start
ENTRY   K5 C115 C116 C97 C114 C116
LAB     L1
LSTR    M9001
KPG     P3 G94
L       K0
RTN
STRING  M9001 K6 C72 C101 C108 C108 C111 C10
GLOBAL K1
G1 L1
G94
MODEND
Conversion complete
0.000> 
\end{verbatim}
}

\medskip
\noindent
Alternatively, the Sial can be translated, statement by statement, into
the assembly language of a machine such as the Pentium as follows.

\medskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
 0.000> sial-386 hello.sial to hello.s
Converting hello.sial to hello.s
Conversion complete
0.010> type hello.s
# Code generated by sial-386

.text
.align 16
# MODSTART

# Entry to: start
# ENTRY   K5 C115 C116 C97 C114 C116
# LAB     L1

LA1:
 movl %ebp,0(%edx)
 movl %edx,%ebp
 popl %edx
 movl %edx,4(%ebp)
 movl %eax,8(%ebp)
 movl %ebx,12(%ebp)
# LSTR    M9001
 leal MA9001,%ebx
 shrl $2,%ebx
# KPG     P3 G94
 movl 376(%esi),%eax
 leal 12(%ebp),%edx
 call *%eax
# L       K0
 xorl %ebx,%ebx
# RTN
 movl 4(%ebp),%eax
 movl 0(%ebp),%ebp
 jmp *%eax
# STRING  M9001 K6 C72 C101 C108 C108 C111 C10
.data
 .align 4
MA9001:
 .byte 6
 .byte 72
 .byte 101
 .byte 108
 .byte 108
 .byte 111
 .byte 10
 .text
# GLOBAL K1

.globl prog

.globl _prog
prog:
_prog:
 movl 4(%esp),%eax
# G1 L1
 movl $LA1,4(%eax)
# G94
 ret

# MODEND
0.020> 
\end{verbatim}
}

\medskip
\noindent

Sial was designed as an experiment in the compact representation of
algorithms that can be just-in-time compiled easily into code for any
target machine. Its secondary purpose was to allow an easy way to
generate native code translations of BCPL programs giving typically a
ten fold speedup over the Cintcode interpretive version. An
experienced programmer can normally modify an existing Sial translator
to generate reasonable code for a new target in one or two days.

The following sections give a specification of Sial and an outline of
how the translator {\tt sial-686} works.

\section{\label{sial}The Sial Specification}

Sial consists of a stream of directives and instructions each starting
with an opcode followed by operands. Both opcodes and operands and
encoded using integers each prefixed by a letter specifying what kind
of value it represents. The prefixes are as follows:

\medskip
\begin{tabular}{ll}
\tt F  &  An opcode or directive\\
\tt P  &  A stack offset, 0 to \verb|#xFFFFFF|\\
\tt G  &  A global variable number, 0 to 65535\\
\tt K  &  A 24-bit unsigned constant, often small in value\\
\tt W  &  A signed integer, used for static data and large constants\\
\tt C  &  A byte in range 0 to 255\\
\tt L  &  A label generated by translation phase\\
\tt M  &  A label generated by the Sial codegenerator\\
\end{tabular}

\medskip\noindent
The instructions are for an abstract machine with the following
internal registers.

\medskip
\begin{tabular}{ll}
\tt a  &  The main accumulator, function first arg and result register\\
\tt b  &  The second accumulator used in dyadic operations\\
\tt c  &  Register used by {\tt pbyt} and {\tt xpbyt}, and possibly currupted by\\
       &  some other instructions, such as {\tt mul}, {\tt div},
          {\tt rem}, {\tt xdiv} and {\tt xrem}\\
\tt P  &  Pointer to the base of the current stack frame\\
\tt G  &  Pointer to the base of the Global Vector\\
\tt PC &  Set by jump and call instrunctions\\
\end{tabular}

\medskip\noindent
The opcodes and directives are as follows:

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
Mnemonic &  Operand(s) &  Meaning\\
\hline\\
\tt  lp     &   \tt Pn         & \verb|a := P!n|\\
\tt  lg     &   \tt Gn         & \verb|a := G!n|\\
\tt  ll     &   \tt Ln         & \verb|a := !Ln|\\ 

\tt  llp    &   \tt Pn         & \verb|a := @ P!n|\\
\tt  llg    &   \tt Gn         & \verb|a := @ G!n|\\
\tt  lll    &   \tt Ln         & \verb|a := @ !Ln|\\
\tt  lf     &   \tt Ln         & \verb|a := address of entry point Ln|\\

\tt  l      &   \tt Kn         & \verb|a := n|\\
\tt  lm     &   \tt Kn         & \verb|a := - n|\\ 
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  sp     &   \tt Pn         & \verb|P!n := a|\\
\tt  sg     &   \tt Gn         & \verb|G!n := a|\\
\tt  sl     &   \tt Ln         & \verb|!Ln := a|\\

\tt  ap     &   \tt Pn         & \verb|a := a + P!n|\\
\tt  ag     &   \tt Gn         & \verb|a := a + G!n|\\
\tt  a      &   \tt Kn         & \verb|a := a + n|\\
\tt  s      &   \tt Kn         & \verb|a := a - n|\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  lkp    &   \tt Kk Pn      & \verb|a := P!n!k|\\
\tt  lkg    &   \tt Kk Gn      & \verb|a := G!n!k|\\
\tt  rv     &                  & \verb|a := ! a|\\
\tt  rvp    &   \tt Pn         & \verb|a := P!n!a|\\
\tt  rvk    &   \tt Kn         & \verb|a := a!k|\\
\tt  st     &                  & \verb|!a := b|\\
\tt  stp    &   \tt Pn         & \verb|P!n!a := b|\\
\tt  stk    &   \tt Kn         & \verb|a!n := b|\\
\tt  stkp   &   \tt Kk Pn      & \verb|P!n!k := a|\\
\tt  skg    &   \tt Kk Gn      & \verb|G!n!k := a|\\
\tt  xst    &                  & \verb|!b := a|\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  k      &   \tt Pn         &  Call  a(b,...) incrementing P by n\\
            &                  &  leaving b in a\\
\tt  kpg    &   \tt Pn Gg      &  Call Gg(a,...) incrementing P by n\\

\tt  neg    &                  & \verb|a := - a|\\
\tt  not    &                  & \verb|a := ~ a|\\
\tt  abs    &                  & \verb|a := ABS a|\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  xdiv   &              & \verb|a := a / b;    c := ?|\\
\tt  xmod   &              & \verb|a := a MOD b;  c := ?|\\
\tt  xsub   &              & \verb|a := a - b;    c := ?|\\

\tt  mul    &              & \verb|a := b * a;    c := ?|\\
\tt  div    &              & \verb|a := b / a;    c := ?|\\
\tt  mod    &              & \verb|a := b MOD a;  c := ?|\\
\tt  add    &              & \verb|a := b + a|\\
\tt  sub    &              & \verb|a := b - a|\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  eq     &              & \verb|a := b = a|\\
\tt  ne     &              & \verb|a := b ~= a|\\
\tt  ls     &              & \verb|a := b < a|\\
\tt  gr     &              & \verb|a := b > a|\\
\tt  le     &              & \verb|a := b <= a|\\
\tt  ge     &              & \verb|a := b >= a|\\
\tt  eq0    &              & \verb|a := a = 0|\\
\tt  ne0    &              & \verb|a := a ~= 0|\\
\tt  ls0    &              & \verb|a := a < 0|\\
\tt  gr0    &              & \verb|a := a > 0|\\
\tt  le0    &              & \verb|a := a <= 0|\\
\tt  ge0    &              & \verb|a := a >= 0|\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  lsh    &              & \verb|a := b << a|\\
\tt  rsh    &              & \verb|a := b >> a|\\
\tt  and    &              & \verb|a := b & a|\\
\tt  or     &              & \verb/a := b | a/\\
\tt  xor    &              & \verb|a := b XOR a|\\
\tt  eqv    &              & \verb|a := b EQV a|\\

\tt  gbyt   &              & \verb|a := b % a|\\
\tt  xgbyt  &              & \verb|a := a % b|\\
\tt  pbyt   &              & \verb|b % a := c|\\
\tt  xpbyt  &              & \verb|a % b := c|\\

\tt  swb    &   \tt Kn Ld K1 L1 ... Kn Ln &  Binary chop switch, {\tt Ld} default\\
\tt  swl    &   \tt Kn Ld L1 ... Ln       &  Label vector switch, {\tt Ld} default\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  xch    &                  & \verb|Swap a and b|\\
\tt  atb    &                  & \verb|b := a|\\
\tt  atc    &                  & \verb|c := a|\\
\tt  bta    &                  & \verb|a := b|\\
\tt  btc    &                  & \verb|c := b|\\
\tt  atblp  &   \tt Pn         & \verb|b := a; a := P!n|\\
\tt  atblg  &   \tt Gn         & \verb|b := a; a := G!n|\\
\tt  atbl   &   \tt Kk         & \verb|b := a; a := k|\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  j      &   \tt Ln         & \verb|Jump to Ln|\\
\tt  rtn    &                  & Function or routine return\\
\tt  goto   &                  & \verb|PC := a|\\

\tt  ikp    &   \tt Kk Pn      & \verb|a := P!n + k; P!n := a|\\
\tt  ikg    &   \tt Kk Gn      & \verb|a := G!n + k; G!n := a|\\
\tt  ikl    &   \tt Kk Ln      & \verb|a := !Ln + k; !Ln := a|\\
\tt  ip     &   \tt Pn         & \verb|a := P!n + a; P!n := a|\\
\tt  ig     &   \tt Gn         & \verb|a := G!n + a; G!n := a|\\
\tt  il     &   \tt Ln         & \verb|a := !Ln + a; !Ln := a|\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  jeq    &   \tt Ln         & \verb|Jump to Ln if b = a|\\
\tt  jne    &   \tt Ln         & \verb|Jump to Ln if b ~= a|\\
\tt  jls    &   \tt Ln         & \verb|Jump to Ln if b < a|\\
\tt  jgr    &   \tt Ln         & \verb|Jump to Ln if b > a|\\
\tt  jle    &   \tt Ln         & \verb|Jump to Ln if b <= a|\\
\tt  jge    &   \tt Ln         & \verb|Jump to Ln if b >= a|\\
\tt  jeq0   &   \tt Ln         & \verb|Jump to Ln if a = 0|\\
\tt  jne0   &   \tt Ln         & \verb|Jump to Ln if a ~= 0|\\
\tt  jls0   &   \tt Ln         & \verb|Jump to Ln if a < 0|\\
\tt  jgr0   &   \tt Ln         & \verb|Jump to Ln if a > 0|\\
\tt  jle0   &   \tt Ln         & \verb|Jump to Ln if a <= 0|\\
\tt  jge0   &   \tt Ln         & \verb|Jump to Ln if a >= 0|\\
\tt  jge0m  &   \tt Mn         & \verb|Jump to Mn if a >= 0|\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  brk    &              &  Breakpoint instruction\\
\tt  nop    &              &  No operation\\
\tt  chgco  &              &  Change coroutine\\
\tt  mdiv   &              & \verb|a := muldiv(P!3, P!4, P!5)|\\
\tt  sys    &              &  System function\\
\end{tabular}

\medskip
\begin{tabular}{p{1.8cm}p{3.9cm}l}
\tt  section & \tt  Kn C1 ... Cn       &  Name of section\\
\tt  modstart&                         &  Start of module \\
\tt  modend  &                         &  End of module\\
\tt  global  & \tt  Kn G1 L1 ... Gn Ln &  Global initialisation data\\
\tt  string  & \tt  Ml Kn C1 ... Cn    &  String constant\\
\tt  const   & \tt  Mn Ww              &  Large integer constant\\
\tt  static  & \tt  Ln Kk W1 ... Wk    &  Static variable or table\\
\tt  mlab    & \tt  Mn                 &  Destination of {\tt jge0m}\\
\tt  lab     & \tt  Lm                 &  Program label\\
\tt  lstr    & \tt  Mn                 & \verb|a := Mn|   (pointer to string)\\
\tt  entry   & \tt  Kn C1 ... Cn       &  Start of a function\\
\end{tabular}

\medskip
The following Sial operators were added in August 2014 to allow native
code compilation of the floating point code. All floating point
operators may corrupt global 11 ({\tt tempval}).

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  float   &              & \verb|a := FLOAT a; b := ?|\\
\tt  fix     &              & \verb|a := FIX a; b := ?|\\
\tt  fabs    &              & \verb|a := #ABS a; b := ?|\\
\tt  fneg    &              & \verb|a := #- a; b := ?|\\
\tt  fmul    &              & \verb|a := b #* a; b := ?|\\
\tt  fdiv    &              & \verb|a := b #/ a; b := ?|\\
\tt  fmod    &              & \verb|a := b #MOD a; b := ?|\\
\tt  fadd    &              & \verb|a := b #+ a; b := ?|\\
\tt  fsub    &              & \verb|a := b #- a; b := ?|\\
\tt  feq     &              & \verb|a := b #= a; b := ?|\\
\tt  fne     &              & \verb|a := b #~= a; b := ?|\\
\tt  fls     &              & \verb|a := b #< a; b := ?|\\
\tt  fgr     &              & \verb|a := b #> a; b := ?|\\
\tt  fle     &              & \verb|a := b #<= a; b := ?|\\
\tt  fge     &              & \verb|a := b #>= a; b := ?|\\
\tt  feq0    &              & \verb|a := a #= 0; b := ?|\\
\tt  fne0    &              & \verb|a := a #~= 0; b := ?|\\
\tt  fls0    &              & \verb|a := a #< 0; b := ?|\\
\tt  fgr0    &              & \verb|a := a #> 0; b := ?|\\
\tt  fle0    &              & \verb|a := a #<= 0; b := ?|\\
\tt  fge0    &              & \verb|a := a #>= 0; b := ?|\\
\end{tabular}

\medskip
\noindent
The floating point conditional jump instructions are as follows.

\medskip
\begin{tabular}{p{1.8cm}p{4.6cm}l}
\tt  jfeq    &   \tt Ln         & \verb|Jump to Ln if b #= a; b := ?|\\
\tt  jfne    &   \tt Ln         & \verb|Jump to Ln if b #~= a; b := ?|\\
\tt  jfls    &   \tt Ln         & \verb|Jump to Ln if b #< a; b := ?|\\
\tt  jfgr    &   \tt Ln         & \verb|Jump to Ln if b #> a; b := ?|\\
\tt  jfle    &   \tt Ln         & \verb|Jump to Ln if b #<= a; b := ?|\\
\tt  jfge    &   \tt Ln         & \verb|Jump to Ln if b #>= a; b := ?|\\
\tt  jfeq0   &   \tt Ln         & \verb|Jump to Ln if a #= 0; b := ?|\\
\tt  jfne0   &   \tt Ln         & \verb|Jump to Ln if a #~= 0; b := ?|\\
\tt  jfls0   &   \tt Ln         & \verb|Jump to Ln if a #< 0; b := ?|\\
\tt  jfgr0   &   \tt Ln         & \verb|Jump to Ln if a #> 0; b := ?|\\
\tt  jfle0   &   \tt Ln         & \verb|Jump to Ln if a #<= 0; b := ?|\\
\tt  jfge0   &   \tt Ln         & \verb|Jump to Ln if a #>= 0; b := ?|\\
\end{tabular}

\medskip
Notice that all floating point instructions currently leave register
{\tt b} undefined, but this may be changed later. They may also may corrupt
global 11 ({\tt tempval}).

A second example of the use of Sial is the following program ({\tt
  com/fact.b}):

\medskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
SECTION "fact"

GET "libhdr"

LET start() = VALOF
{ FOR i = 1 TO 5 DO writef("fact(%n) = %i4*n", i, fact(i))
  RESULTIS 0
}

AND fact(n) = n=0 -> 1, n*fact(n-1)
\end{verbatim}
}

\medskip
\noindent
It translation in Sial code is as follows:

\medskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
F104
F103 K4 C102 C97 C99 C116
F113 K5 C115 C116 C97 C114 C116
F111 L1
F11 K1
F13 P3
F111 L4
F3 P3
F69
F9 L2
F31 P9
F13 P9
F3 P3
F13 P8
F112 M1
F32 P4 G94
F79 K1 P3
F75 K5
F89 L4
F11 K0
F77
F107 M1 K15 C102 C97 C99 C116 C40 C37 C110
 C41 C32 C61 C32 C37 C105 C52 C10
F113 K4 C102 C97 C99 C116
F111 L2
F92 L5
F11 K1
F77
F111 L5
F12 K1
F16 P3
F69
F9 L2
F31 P4
F73 P3
F39
F77
F106 K1 G1 L1 G94
F105
\end{verbatim}
}

\noindent
Using the {\tt sial-sasm} command we obtain the following more
readable version:

\medskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
MODSTART
SECTION K4 C102 C97 C99 C116

//Entry to: start
ENTRY   K5 C115 C116 C97 C114 C116
LAB     L1
L       K1
SP      P3
LAB     L4
LP      P3
ATB
LF      L2
K       P9
SP      P9
LP      P3
SP      P8
LSTR    M1
KPG     P4 G94
IKP     K1 P3
ATBL    K5
JLE     L4
L       K0
RTN
STRING  M1 K15 C102 C97 C99 C116 C40 C37 C110 C41 C32
        C61 C32 C37 C105 C52 C10

//Entry to: fact
ENTRY   K4 C102 C97 C99 C116
LAB     L2
JNE0    L5
L       K1
RTN
LAB     L5
LM      K1
AP      P3
ATB
LF      L2
K       P4
ATBLP   P3
MUL
RTN
GLOBAL K1
G1 L1
G94
MODEND
\end{verbatim}
}

\medskip

This can be translated into assembly language using the program {\tt
  com/sial-686.b} which is a simple program based on {\tt
  sial-sasm.b}. This version can now compile the floating point
instructions recently added to Sial. It generates the readable version
of the Sial source as comments interspersed with the corresponding
Pentium assembly code. For the example program given above, it outputs
the following assembly language.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
# Code generated by sial-686

.text
.align 16
# MODSTART
# SECTION K4 C102 C97 C99 C116

# Entry to: start
# ENTRY   K5 C115 C116 C97 C114 C116
# LAB     L1

LA1:
 movl %ebp,0(%edx)
 movl %edx,%ebp
 popl %edx
 movl %edx,4(%ebp)
 movl %eax,8(%ebp)
 movl %ebx,12(%ebp)
# L       K1
 movl $1,%ebx
# SP      P3
 movl %ebx,12(%ebp)
# LAB     L4
LA4:
# LP      P3
 movl 12(%ebp),%ebx
# ATB
 movl %ebx,%ecx
# LF      L2
 leal LA2,%ebx
# K       P9
 movl %ebx,%eax
 movl %ecx,%ebx
 leal 36(%ebp),%edx
 call *%eax
# SP      P9
 movl %ebx,36(%ebp)
# LP      P3
 movl 12(%ebp),%ebx
# SP      P8
 movl %ebx,32(%ebp)
# LSTR    M1
 leal MA1,%ebx
 shrl $2,%ebx
# KPG     P4 G94
 movl 376(%esi),%eax
 leal 16(%ebp),%edx
 call *%eax
# IKP     K1 P3
 movl 12(%ebp),%ebx
 incl %ebx
 movl %ebx,12(%ebp)
# ATBL    K5
 movl %ebx,%ecx
 movl $5,%ebx
# JLE     L4
 cmpl %ebx,%ecx
 jle LA4
# L       K0
 xorl %ebx,%ebx
# RTN
 movl 4(%ebp),%eax
 movl 0(%ebp),%ebp
 jmp *%eax
# STRING  M1 K15 C102 C97 C99 C116 C40 C37 C110 C41 C32
#         C61 C32 C37 C105 C52 C10
.data
 .align 4
MA1:
 .byte 15
 .byte 102
 .byte 97
 .byte 99
 .byte 116
 .byte 40
 .byte 37
 .byte 110
 .byte 41
 .byte 32
 .byte 61
 .byte 32
 .byte 37
 .byte 105
 .byte 52
 .byte 10
 .text

# Entry to: fact
# ENTRY   K4 C102 C97 C99 C116
# LAB     L2

LA2:
 movl %ebp,0(%edx)
 movl %edx,%ebp
 popl %edx
 movl %edx,4(%ebp)
 movl %eax,8(%ebp)
 movl %ebx,12(%ebp)
# JNE0    L5
 orl %ebx,%ebx
 jne LA5
# L       K1
 movl $1,%ebx
# RTN
 movl 4(%ebp),%eax
 movl 0(%ebp),%ebp
 jmp *%eax
# LAB     L5
LA5:
# LM      K1
 movl $-1,%ebx
# AP      P3
 addl 12(%ebp),%ebx
# ATB
 movl %ebx,%ecx
# LF      L2
 leal LA2,%ebx
# K       P4
 movl %ebx,%eax
 movl %ecx,%ebx
 leal 16(%ebp),%edx
 call *%eax
# ATBLP   P3
 movl %ebx,%ecx
 movl 12(%ebp),%ebx
# MUL
 movl %ecx,%eax
 imul %ebx
 movl %eax,%ebx
# RTN
 movl 4(%ebp),%eax
 movl 0(%ebp),%ebp
 jmp *%eax
# GLOBAL K1

.globl fact

.globl _fact
fact:
_fact:
 movl 4(%esp),%eax
# G1 L1
 movl $LA1,4(%eax)
# G94
 ret

# MODEND
\end{verbatim}
}

\medskip
When implementing {\tt sial-686} it was necessary to decide how the
Intel registers were to be used and what the BCPL calling sequence
should be. The chosen register allocation was as follows:

\medskip
\begin{tabular}{l|p{4cm}l}
Intel register & Use \\
\hline\\
\tt  \%eax & A work register\\
\tt  \%ebx & The {\tt A} register\\
\tt  \%ecx & The {\tt B} register\\
\tt  \%edx & The {\tt C} register\\
\tt  \%esi & The {\tt G} pointer\\
\tt  \%edi & A work register\\
\tt  \%ebp & The {\tt P} pointer\\
\tt  \%st(0) & The {\tt X} register used in the
             & compilation of floating point operations\\
\tt  \%sp(0) & The {\tt S} register used when transferring floating
             & point numbers between {\tt X} and {\tt A} or {\tt B}
\end{tabular}

\medskip
\noindent
The chosen BCPL calling sequence is as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
                                  # Entry address must be in %eax
                                  # The first argument must be in %ebx
leal <stack increment>(%ebp),%edx # Set %edx to the new P pointer
call *%eax                        # Subroutine jump to the entry point
\end{verbatim}
}

\noindent
The entry sequence is as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
                    # The first argument is in %ebx(=A)
                    # The new P pointer is in %edx(=C)
movl %ebp,0(%edx)   # C!0  := P
movl %edx,%ebp      # P    := C
popl %edx           # Get the return address
movl %edx,4(%ebp)   # P!1  := return address
movl %eax,8(%ebp)   # P!2  := entry address
movl %ebx,12(%ebp)  # P!3  := the first argument
\end{verbatim}
}

\noindent
The return sequence is as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
                    # The result is in %ebx(=A)
movl 4(%ebp),%eax   # Get the return address
movl 0(%ebp),%ebp   # P := the saved P pointer
jmp *%eax           # Jump to the return address
\end{verbatim}
}
\medskip

The structure of {\tt sial-686} is simple. It mainly consists of a
large switch within the function {\tt scan} that has a case for each
Sial function code and directive. For example, the case for the function
code {\tt kpg} is approximately as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
      CASE f_kpg:    cvfpg("KPG") // Call Gg(a,...) incrementing P by n
                     writef("*n movl %n(%%esi),%%eax", 4*gval)
                     writef("*n leal %n(%%ebp),%%edx", 4*pval)
                     writef("*n call **%%eax")
                     ENDCASE
\end{verbatim}
}
\medskip
\noindent

The call \verb|cvfpg("KPG")| reads the Sial statement knowing it is
of the form: {\tt KPG P}{\em k} {\tt G}{\em n}. This outputs the
statement as an assembly language comment after placing {\em k} and
{\em n} in {\tt pval} and {\tt gval}, respectively. The three {\tt
writef} calls then output the three assembly language instructions for
the {\tt KPG} operation, and {\tt ENDCASE} transfers control to where
the next Sial statement is processed. All the other cases are equally
simple.

To improve the efficiency of the floating point code, instructions
that normally load a value into {\tt A} or {\tt B} are delay until it
is known how the value is to be used. If a floating point operation is
about to be performed it is better to load the value into {\tt
  X}. Where possible, {\tt sial-686.b} remembers what value (such as
which local or global) is currently held in {\tt A}, {\tt B}, {\tt X}
and {\tt S}.

The section name of the program, which must be present, compiles into
a C callable function that initialises the BCPL global vector with the
entry points defined within this module. To complete the 686
implementation, there is a short handwritten assembly language library
{\tt natbcpl/sysasm/mlib.s} that defines the BCPL callable functions
{\tt sys}, {\tt changeco} and {\tt muldiv}. The program must be linked
the compiled versions of the BCPL library modules {\tt BLIB} and {\tt
  DLIB}, and also {\tt clib} whose source is in {\tt
  natbcpl/sysc/clib.c}.

Every section must contain the definition of a function to initialise
the global vector with the entry points of functions defined in the
section. For a section defined in BCPL, the name of the initialisation
function is the section name which must have been specified in the
BCPL source. A C program such as {\tt initprog.c} must be provided to
with a definition of a function called {\tt initsections} that calls
the initialisation function of every section of the program. The
command {\tt makeinit}, described on page~\pageref{makeinit}, can be
used to create the initialiation program. For the program {\tt prog.b}
given above, the following command:

\smallskip
{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
makeinit prog.b to initprog.c
\end{verbatim}
}
\medskip

\noindent
will create the file {\tt initprog.c} which is as follows:

\bigskip
{\label{makeinituse}\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
// Initialisation file written by makeinit version 2.0

#include "bcpl.h"

WORD stackupb=50000;
WORD gvecupb=1000;

// BCPL sections
extern BLIB(WORD *);    // file (run-time library)
extern DLIB(WORD *);    // file (system dependent library)
extern prog(WORD *);    // file prog.b

void initsections(WORD *g) {
    BLIB(g);    // file (run-time library)
    DLIB(g);    // file (system dependent library)
    prog(g);    // file prog.b

    return;
}
\end{verbatim}
}
\medskip

If needed, the runtime stack size and the size of the global vector
can be specified by arguments to {\tt makeinit}.  The compilation of
{\tt initprog} must be linked in with the object code of all the other
sections needed by {\tt prog.b} when building its executable. Assuming
the executable is placed in {\tt bin/prog}, it can be executed by the
{\tt bash} shell command {\tt ./bin/prog} or possibly just {\tt prog}
if the {\tt PATH} environment variable is suitably set.

\section{Compaction of Sial}

In order to transmit program to a device such as a mobile phone or
space probe over a slow connection it is useful to have a compact
representation of the code. Sial is both target machine independent
and can be compacted with ease. This section gives a brief overview of
an experimental compaction technique that seems to performs well.

Since the types of operands and their number depend only on the Sial
operator, an Sial stream can be split into several streams of which
the main one is the stream of Sial operators. Others are streams holding
global variable numbers, local variable offsets, program label
numbers, data labels, integer constants, character codes and a some
others. These streams can be separately compressed taking advantage of
the special properties of each. Some ideas are given below.

Local variable offsets have a very skew distribution and so are
susceptible to Huffman (or possibly arithmetic) coding after some
preprocessing to deal with large values and the implementation of a
mechanism to take advantage of the observation that, if an offset is
used once, the same offset is likely to be used again in the near
future. This might suggest the use of move-to-front buffering.

Program labels have the property that, in any section, they are each
only set once using a {\tt LAB} or {\tt ENTRY} statement. If they are
systematically renumbered so that successive label setting statements
take successive label numbers, there is no need for these statements
to take a label argument. The remaining labels in the stream are
typically nearly monotonic the compaction algorithm can take advantage
of this.

The operation code stream often contains repeated patterns that are
susceptible to the conventional techniques used to compress text, and
the same applies to the stream of characters. It might be worth
separating out the integers representing the character string lengths
from other integers and place them either in a stream of their own or
insert them into the stream of characters.

Some preliminary experiments on Sial compression can be found in the
directory {\tt bcplprogs/sial} in the standard BCPL distribution.



\cleardoublepage

\chapter{\label{mcpackage}The MC Package}

This chapter describes the MC package which provides a machine
independent way to generate and execute native machine code at
runtime. The work on this package started in January 2008 and is still
under development, however, it currently works well enough to run the
n-queens problem on i386 machines about 24 times faster than the
normal Cintcode interpretive version. MC package development is
performed in the directory {\tt BCPL/bcplprogs/mc/} and fairly stable
versions are copied to {\tt BCPL/cintcode/g/mc.h}, {\tt
BCPL/cintcode/com/mci386.b} and {\tt BCPL/cintcode/cin/mci386} which
can be used from any working directory. Currently the MC package does
not have any floating point operations. This will be rectified in due
course.

The package is based on a simple machine independent abstract machine
code called MC which is easily translated into machine instructions
for most architectures. Although native code is generated by MC calls
such as {\tt mcRDX(mc\_add, mc\_b, 20, mc\_d)}, MC has a corresponding
assembly language to assist debugging. The assembly form of the
instruction generated by the previous call is {\tt ADD B,20(D)}
meaning set register B to the sum of B and the contents of the memory
location whose address is 20 plus the value of register D. MC
instructions are fairly low level and typically translate into single
native code instructions for most architectures.  This example
translates into the i386 GNU statement: {\tt addl 20(\%edx),\%ebx}.

The first operand is the destination for any instruction that updates
a register or memory location. Thus assignments are always from right
to left as in most programming languages but unlike many assembly codes
where, for instance, {\tt movl~20(\%edx),\%ebx} updates the
second operand.

The MC machine has six registers A, B, C, D, E and F that are directly
available to the programmer, and also a program counter, stack
pointer, stack frame pointer and a condition code register, although
these cannot be accessed explicitly.

\section{MC Example}

The following program is a simple demonstration of the i386 version
of the MC package.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
GET "libhdr"
GET "mc.h"

MANIFEST {
  A=mc_a; B=mc_b; C=mc_c; D=mc_d; E=mc_e; F=mc_f
  a1=1; a2; a3
}

LET start() = VALOF
{ // Load the dynamic code generation package for i386 machines.
  LET mcseg, mcb, n = globin(loadseg("mci386")), 0, 0
  UNLESS mcseg DO
  { writef("Trouble with MC package: mci386*n")
    GOTO fin
  }
  // Create an MC instance for 10 functions with a data space
  // of 100 words and code space of 4000 words.
  mcb := mcInit(10, 100, 4000)
  UNLESS mcb DO
  { writef("Unable to create an mci386 instance*n")
    GOTO fin
  } 
  mc := 0                  // Currently no selected MC instance.
  mcSelect(mcb)            // Select the new MC instance.

  mcK(mc_debug, #b0011)    // Trace comments and MC instructions.

  mcKKK(mc_entry, 1, 3, 5) // Entry point for function 1
                           // having 3 arguments and 5 local variables

  mcK(mc_debug, #b1111)    // Trace comments, MC instructions, target
                           // instructions and the compiled code.

  mcRA(mc_mv,  A, a1)      // A := <arg 1>
  mcRA(mc_add, A, a2)      // A := A + <arg 2>

  n := mcNextlab()
  mcL(mc_lab, n)           // Ln:
  mcRA(mc_add, A, a3)      // A := A + <arg 3>
  mcR(mc_dec, A)           // A := A - 1
  mcRK(mc_cmp, A, 100)
  mcJS(mc_jlt, n)          // IF A<100 JMP Ln

  mcK(mc_debug, #b0011)    // Trace only comments and MC instructions.
  mcF(mc_rtn)              // Return from function 1 with result in A.
  mcF(mc_endfn)            // End of function 1 code.
  mcF(mc_end)              // End of dynamic code generation.

  writef("*nF1(10, 20, 30) => %n*n", mcCall(1, 10, 20, 30))
fin:
  IF mcseg DO unloadseg(mcseg)  
  RESULTIS 0
}
\end{verbatim}
}

\noindent
When this program runs it outputs the following.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
//    ENTRY 1 3 5
//    DEBUG 15
//    MV A,A1
        movl 20(%ebp), %eax
  573:  8B 45 14
//    ADD A,A2
        addl 24(%ebp), %eax
  576:  03 45 18

//    LAB L1
        lab L1
  579: L1:
//    ADD A,A3
        addl 28(%ebp), %eax
  579:  03 45 1C
//    DEC A
        decl  %eax
  582:  48
//    CMP A,$100
        cmpl $100, %eax
  583:  83 F8 64
//    JLT L1
        jl L1
  586:  7C F7
//    DEBUG 3
//    RTN
//    ENDFN
//    END

F1(10, 20, 30) => 117
\end{verbatim}
%$
}

The result of 117 (= 10+20+(30-1)*3) shows that the body of the loop
was correctly executed three times.

The header file ({\tt mc.h}) defines manifests (such as {\tt mc\_mv}
and {\tt mc\_add}) and globals (such as {\tt mcK} and {\tt mcRA})
provided by the package. The package itself must be dynamically loaded
(by {\tt globin(loadseg("mci386"))}) and then selected (by {\tt
mcSelect(mcb)}). MC instructions are compiled by calls such as {\tt
mcRA(op,...} or {\tt mcRK(op,...} where {\tt op} specifies the
instruction or directive and the letters following {\tt mc} (eg {\tt
RA} or {\tt RK}) specify the sort of operands supplied.

A register operand is denoted by {\tt R} and an integer operand by
{\tt K}. There are 9 possible kinds of memory operands denoted by {\tt
A}, {\tt V}, {\tt G}, {\tt M}, {\tt L}, {\tt D}, {\tt DX}, {\tt DXs}
and {\tt DXsB}. {\tt A} denotes an specified argument of the current
function, {\tt V} denotes a specified local variable of the current
function, {\tt G} denotes a specified BCPL global variable, {\tt M}
denotes a location in Cintcode memory specified by a BCPL pointer,
{\tt L} denotes the position within the data or code areas of the
compiled code corresponding to a given label, {\tt D} denotes a
specified absolute machine address, {\tt DX} denotes a location whose
machine address is the sum of a given byte offset and register, {\tt
DXs} is similar to {\tt DX} only the index register is scaled by a
given factor of 1, 2, 4 or 8 and finally {\tt DXsB} is like {\tt DXs}
but has a second specified register added into the effective address.

The following table summarises the MC code generation functions. The
first argument is always specifies the directive or instruction and the
remaining arguments specify the operands. The destination of any
instruction that updates a register or memory location is always the
first operand.

\medskip
\begin{tabular}{p{1.5cm}p{11.5cm}l}
Function         & Operands \\
\hline
{\tt mcF}        & No operand \\
{\tt mcK}        & One integer operand \\
{\tt mcR}        & One MC register operand \\
{\tt mcA}        & One operand specifying an argument number \\
{\tt mcV}        & One operand specifying an local variable number \\
{\tt mcG}        & One operand specifying a global variable number \\
{\tt mcM}        & One operand giving the word address of a location 
                   in Cintcode memory \\
{\tt mcL}        & One numeric label operand, defaulting to 32-bit relative \\
{\tt mcD}        & One operand giving an absolute machine address \\
{\tt mcDX}       & One memory operand specified by an offset added to
                   an index register \\
{\tt mcDXs}      & One memory operand specified by an offset added to
                   an index register scaled by {\tt s}
                   which must be 1, 2, 4 or 8\\
{\tt mcDXsB}     & One memory operand specified by an offset added to
                   a base register and an index register scaled by {\tt s}
                   which must be 1, 2, 4 or 8\\
\end{tabular}

\begin{tabular}{p{1.5cm}p{11.5cm}l}
{\tt mcJS}       & Jump instructions with near relative destinations\\
{\tt mcJL}       & Jump instructions with possibly distant relative destinations\\
{\tt mcJR}       & Jump instructions with destination given by resister\\
\end{tabular}

\begin{tabular}{p{1.5cm}p{11.5cm}l}
{\tt mcRA}       & Two operands, {\tt R} and {\tt A}\\
{\tt mcRV}       & Two operands, {\tt R} and {\tt V}\\
{\tt mcRG}       & Two operands, {\tt R} and {\tt G}\\
{\tt mcRM}       & Two operands, {\tt R} and {\tt M}\\
{\tt mcRL}       & Two operands, {\tt R} and {\tt L}\\
{\tt mcRD}       & Two operands, {\tt R} and {\tt D}\\
{\tt mcRDX}      & Two operands, {\tt R} and {\tt DX}\\
{\tt mcRDXs}     & Two operands, {\tt R} and {\tt DXs}\\
{\tt mcRDXsB}    & Two operands, {\tt R} and {\tt DXsB}\\
\end{tabular}

\begin{tabular}{p{1.5cm}p{11.5cm}l}
{\tt mcRR}       & Two operands, {\tt R} and {\tt R}\\
{\tt mcAR}       & Two operands, {\tt A} and {\tt R}\\
{\tt mcVR}       & Two operands, {\tt V} and {\tt R}\\
{\tt mcGR}       & Two operands, {\tt G} and {\tt R}\\
{\tt mcMR}       & Two operands, {\tt M} and {\tt R}\\
{\tt mcLR}       & Two operands, {\tt L} and {\tt R}\\
{\tt mcDR}       & Two operands, {\tt D} and {\tt R}\\
{\tt mcDXR}      & Two operands, {\tt DX} and {\tt R}\\
{\tt mcDXsR}     & Two operands, {\tt DXs} and {\tt R}\\
{\tt mcDXsBR}    & Two operands, {\tt DXsB} and {\tt R}\\
\end{tabular}

\begin{tabular}{p{1.5cm}p{11.5cm}l}
{\tt mcRK}       & Two operands, {\tt R} and {\tt K}\\
{\tt mcAK}       & Two operands, {\tt A} and {\tt K}\\
{\tt mcVK}       & Two operands, {\tt V} and {\tt K}\\
{\tt mcGK}       & Two operands, {\tt G} and {\tt K}\\
{\tt mcMK}       & Two operands, {\tt M} and {\tt K}\\
{\tt mcLK}       & Two operands, {\tt L} and {\tt K}\\
{\tt mcDK}       & Two operands, {\tt D} and {\tt K}\\
{\tt mcDXK}      & Two operands, {\tt DX} and {\tt K}\\
{\tt mcDXsK}     & Two operands, {\tt DXs} and {\tt K}\\
{\tt mcDXsBK}    & Two operands, {\tt DXsB} and {\tt K}\\
\end{tabular}

\begin{tabular}{p{1.5cm}p{11.5cm}l}
{\tt mcKK}       & Two integer operands \\
{\tt mcKKK}      & Three integer operands \\
{\tt mcPRF}      & One {\tt printf} format string and one register \\
\end{tabular}

\section{MC Library Functions}

\bigskip
\noindent
{\tt {\em mcb} := mcInit({\em maxfno}, {\em dsize}, {\em csize})}\\
\indent
Create an instance of the MC package, allocating space for
{\em maxfno} functions, {\em dsize} words of data space and 
{\em csize} words of code space. The MC control block is assigned to
{\em mcb}.

\bigskip
\noindent
{\tt mcSelect({\em mcb})}\\
\indent
Select an instance of the MC package by assigning {\em mcb} to the
global variable {\tt mc}. For efficiency reasons, {\tt mcSelect}
copies various field in the control block to global variables. If {\tt
mc} was non zero, the previous setting of the globals are saved in the
previously selected MC instance. It is thus important to set {\tt mc} to
zero before the first call od {\tt mcSelect}.

\bigskip
\noindent
{\tt {\em res} := mcCall({\em fno}, {\em a1}, {\em a2}, {\em a3})}\\
\indent
Call the function with number {\em fno} giving it the three
arguments {\em a1}, {\em a2}, {\em a3}. The result is assigned to
{\em res}. Function {\em fno} must have been defined to expect three
arguments.

\bigskip
\noindent
{\tt mcClose()}\\
\indent
Close the currently selected MC instance deleting all its workspace
and compiled code. It also sets {\tt mc} to zero.

\bigskip
\noindent
{\tt mcPRF(\em mess\tt, \em reg\tt)}\\
\indent
This function is an invaluable debugging aid which compiles code to
call the C function {\tt printf} with the given format string (packed
in the data area) and the value of the specified register.  All
registers, including the condition code, are preserved.  The register
argument may be omitted if the format string requires no register
argument.  Typical use of {\tt mcPRF} is as follows:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        mcRK(mc_mv, D, #x01234567)
        mcRK(mc_mv, A, #x89ABCDEF)
        mcRK(mc_mv, A, #x10000000)
        mcPRF("With  D=%8x  ",  D)
        mcPRF("A=%8x  ", A)
        mcPRF("B=%8x*n", B)
        mcR(mc_div, B)
        mcPRF("the instruction:  DIV B*n")
        mcPRF("gives D=%8x  ", D)
        mcPRF("A=%8x  ", A)
        mcPRF("B=%8x*n", B)
\end{verbatim}
}

\noindent
This causes the following output:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
With  D= 1234567  A=89abcdef  B=10000000
the instruction:  DIV B
gives D= 9abcdef  A=12345678  B=10000000
\end{verbatim}
}



\bigskip
\noindent
{\tt {\em n} := mcNextlab()}\\
\indent
Allocate the next available label assigning its number to {\em
n}. Labels are use by instructions that refer to static data and in
jump instructions. There is essentially no limit to the number of
labels that may be allocated.


\bigskip
\noindent
{\tt mcComment({\em format}, {\em a}, {\em b},\ldots, {\em k})}\\
\indent
This is a debugging aid to make the compiled code more readable using
{\tt writef} to write a message to the listing output during code
generation if the least significant bit of {\tt mcDebug} is a one.
The variable {\tt mcDebug} is set by the DEBUG directive described
below.

\bigskip
\noindent
{\em res} {\tt := mcDatap()}\\
{\em res} {\tt := mcCodep()}\\
\indent
These calls return the current positions in the data and code area
respectively.

\bigskip
\indent
All the other functions compile MC directives and instructions and are
described below.

\section{The MC Language}

The MC abstract machine language is fairly low level and is somewhat
influenced by the i386 architecture. Particularly the rather small
number of MC registers allowed, the rich variety of memory addressing
modes and the specification of the instructions for multiplication,
division and shifts.  However, it is machine independent and
reasonably easy to compile into native machine code for most
machines. Before describing the MC instructions, a few key features
will be introduced. As mentioned earlier the MC machine has six
registers named {\tt A} to {\tt F} which are typically mapped directly
onto machine registers of the target architecture. These can be used
for any purpose except for a few instructions such as {\tt MUL}, {\tt
DIV} and the shifts which may implicitly use some of them implicitly.

When an MC function is declared it has a specified number of arguments
and local variables (see the ENTRY statement below). When a function
is called by the CALL instruction, the required number of arguments
must have already been pushed onto the stack. On return these
arguments will have been automatically popped from the stack. If the
wrong number of arguments are given, the effect is undefined. By
convention, the result of a function is returned in register {\tt A}.

Numeric labels are used to refer to static data and positions in the
code. They are allocated by calls of {\tt mcNextlab}, described above.
Many architectures allow both conditional and unconditional jumps to
use short offsets (typically single bytes) to specify the relative
address of the destination.  Jump instructions automatically use short
relative addresses for backward jumps if possible, but, for forward
jumps, the programmer is required to give a hint. Jump instructions
compiled by {\tt mcJS} expect forward jumps to use short relative
addresses while {\tt mcJL} specifies that larger relative addresses
are to be used. If a short relative address proves insufficent and
error message is generated telling the programmer that {\tt mcJL}
should have been used. The function {\tt mcJR} is used when the
destination address of a jump instruction is in a register.

Conditional jump instructions inspect the condition code to determine
whether or not to jump.  The condition code is set by the {\tt CMP},
{\tt ADD}, {\tt ADDC}, {\tt SUB} and {\tt SUBC} instructions and
preserved by jump instructions ({\tt JMP} and {\tt Jcc}). All other
instructions (including {\tt INC} and {\tt DEC} leave the condition
code undefined.

All MC directives and instructions are described below in alphabetical
order. The name of the operation is given in bold caplital letters
together with the list of possible operand types. The BCPL manifest
for the operation consists of the name in lower case letters preceded
by {\tt mc\_}. For example, {\tt mc\_add} is the manifest constant for
the ADD operation, and since {\tt RDXs} appears in its list of operand
types, it can be compiled by, for instance, {\tt
mcRDXs(mc\_add,~mc\_a,~20,~mc\_d,~4)}.

\bigskip
\noindent
{\bf ADD}\hfill     {\tt RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Add the second operand into the first and set the condition code
appropriately. For example, {\tt mcRG(mc\_add,~mc\_d,~150)} will
compile code to add global 150 in register {\tt D}.

\bigskip
\noindent
{\bf ADDC}\hfill    {\tt RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Add the condition code carry bit and the second operand into the first
and set the condition code appropriately. Adding 1 into the 64-bit
value held in {\tt B:A} can be done by the code generated by:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
mcRK( mc_add,  mc_a, 1)  // Don't use INC here!
mcRK( mc_addc, mc_b, 0)
\end{verbatim}
}

\bigskip
\noindent
{\bf ALIGNC}\hfill {\tt  K}\\
\indent
Align the next instruction to an address which is a multiple of {\tt
k} which must be 2, 4 or 8.

\bigskip
\noindent
{\bf ALIGND}\hfill {\tt  K}\\
\indent
Align the next item of data to an address which is a multiple of {\tt
k} which must be 2, 4 or 8.

\bigskip
\noindent
{\bf AND}\hfill  {\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Perform the bit wise AND of the second operand into the first.

\bigskip
\noindent
{\bf CALL}\hfill {\tt  KK}\\
\indent
Call the function who number is the first argument with {\tt n}
arguments that have already been pushed onto the stack when {\tt n} is
the second operand. On return these arguments will have been popped
and, by convention, the result will be in register {\tt A}.

\bigskip
\noindent
{\bf CDQ}\hfill {\tt  F}\\
\indent
Sign extend register {\tt A} into {\tt D}. That is, if {\tt A} is
positive set {\tt D} to zero, otherwise it is to {\tt \#xFFFFFFFF}.
This is normally used in conjuction with DIV.

\bigskip
\noindent
{\bf CMP}\hfill  {\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Set the condition code to difference between the first operand and the
second. The condition code is used by conditional jumps and
conditional setting instructions. For example,

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
mcRK(mc_cmp, mc_b, 100)
mcJL(mc_jle, 25)
\end{verbatim}
}

\noindent
will compile code to jump the label {\tt L25} is {\tt B<=100}, using
signed arithmetic.


\bigskip
\noindent
{\bf DATAB}\hfill {\tt  K}\\
\indent
Assemble one byte of data with the specified value.

\bigskip
\noindent
{\bf DATAK}\hfill {\tt  K}\\
\indent
Assemble one aligned word of data with the specified value.

\bigskip
\noindent
{\bf DATAL}\hfill {\tt  L}\\
\indent
Assemble one aligned word of data initialised with the absolute address
of code or data specified by the given label.

\bigskip
\noindent
{\bf DEBUG}\hfill {\tt  K}\\
\indent
Set the debug tracing level ({\tt mcDebug}) to the specified value. The
least significant four bits of {\tt mcDebug} control the level of
tracing as follows.

\bigskip
\begin{tabular}{ll}
{\tt \#b0001} & Output any {\tt mcComment} comments.\\
{\tt \#b0010} & Output the MC instructions.\\
{\tt \#b0100} & Output the target machine instructions.\\
{\tt \#b1000} & Output the compiled binary code.\\
\end{tabular}

\bigskip
\noindent
{\bf DEC}\hfill {\tt  R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Decrement the specified register or memory word by 1, leaving the
condition code undefined.

\bigskip
\noindent
{\bf DIV}\hfill {\tt  K  R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Divide the double length value in {\tt D:A} by the specified operand.
The result is left in {\tt A} and the remainder in {\tt D}. The DIV
instruction performs signed arithmetic.

\bigskip
\noindent
{\bf DLAB}\hfill {\tt  L}\\
\indent
Set the specified label to the absolute address of the next available
byte in the data area.

\bigskip
\noindent
{\bf ENDFN}\hfill {\tt  F}\\
\indent
This marks the end of the body of the current function.

\bigskip
\noindent
{\bf END}\hfill {\tt  F}\\
\indent
This directive specifies that no more code generation will be
done. The system will free all temporary work space only preseving the
MC control block, the function dispatch table, and the data and code
areas.

\bigskip
\noindent
{\bf ENTRY}\hfill {\tt KKK}\\
\indent
This specifies the entry point of the function whose number is given
by the first operand. The second operand specifies how many arguments
the function takes and the third specified how many local variables
the function may use. Calls to this function must have the required
number of arguments pushed onto the stack, and on return this number
of values will be automatically popped from the stack. Functions
called directly from BCPL using {\tt mcCall} always take three
arguments, but functions called using the CALL instruction can take
any number of arguments.

\bigskip
\noindent
{\bf INC}\hfill  {\tt   R A V G M L D DX DXs DXsB}\\
\indent
Increment the specified register or word of memory by one, leaving the
condition code undefined.

\bigskip
\noindent
{\bf JEQ}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was equal to its second operand.

\bigskip
\noindent
{\bf JGE}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was greater than or equal to its second operand using
signed arithmetic.

\bigskip
\noindent
{\bf JGT}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was greater than its second operand using signed
arithemetic.

\bigskip
\noindent
{\bf JLE}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was less than or equal to its second operand using
signed arithmetic.

\bigskip
\noindent
{\bf JLT}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was less than its second operand using signed
arithmetic.

\bigskip
\noindent
{\bf JMP}\hfill {\tt  JS JL JR}\\
\indent
Unconditionally jump to the specified location.

\bigskip
\noindent
{\bf JNE}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was not equal to its second operand.

\bigskip
\noindent
{\bf LAB}\hfill {\tt  L}\\
\indent
Set the specified label to the machine address of the current position
in the code area.

\bigskip
\noindent
{\bf MV}\hfill   {\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Move the second operand into the first.

\bigskip
\noindent
{\bf MVB}\hfill  {\tt AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Move the least significant byte of the second operand into the memory
byte location specified by the first.

\bigskip
\noindent
{\bf MVH}\hfill  {\tt AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Move the least significant 16 bits of the second operand into the
16-bit memory location specified by the first.

\bigskip
\noindent
{\bf MVSXB}\hfill{\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Move the sign extended byte value specified by the second operand into
the first.

\bigskip
\noindent
{\bf MVSXH}\hfill{\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Move the sign extended 16-bit value specified by the second operand
into the first.

\bigskip
\noindent
{\bf MVZXB}\hfill{\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Move the zero extended byte value specified by the second operand into
the first.

\bigskip
\noindent
{\bf MVZXH}\hfill{\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Move the zero extended 16-bit value specified by the second operand
into the first.

\bigskip
\noindent
{\bf LEA}\hfill  {\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\indent
Load the register specified by the first operand with the absolute
address of the memory location specified by the second operand.

\bigskip
\noindent
{\bf LSH}\hfill  {\tt RK RR}\\
\indent
Shift to the left the value in the register specified by the first
operand by the amount specified by the second operand.  If the second
operand is a register is must be {\tt C}. Vacated positions are filled
with zeros. The effect is undefined if the shift distance is not in
the range 0 to 31.

\bigskip
\noindent
{\bf MUL}\hfill {\tt  K  R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Multiply register {\tt A} by the operand placing the double length
result in {\tt D:A}. Signed arithmetic is used.  Unsigned arithmetic
is used.  Immediate ({\tt K}) operands may sometimes be packed in the
data area.

\bigskip
\noindent
{\bf NEG}\hfill {\tt     R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Negate the value specified by the operand.

\bigskip
\noindent
{\bf NOP}\hfill {\tt   F}\\
\indent
Performs no operation.

\bigskip
\noindent
{\bf NOT}\hfill {\tt     R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Perform the bitwise complement of the value specified by the operand.

\bigskip
\noindent
{\bf OR}\hfill   {\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Perform the bitwise OR of the second operand into the first.


\bigskip
\noindent
{\bf POP}\hfill {\tt     R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Pop one word off the stack placing it in the specified register or
memory location.

\bigskip
\noindent
{\bf PUSH}\hfill {\tt  K  R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Push the specified constant, register or memory location onto
the stack.

\bigskip
\noindent
{\bf RSH}\hfill  {\tt RR RK}\\
Shift to the right the value in the register specified by the first
operand by the amount specified by the second operand.  If the second
operand is a register is must be {\tt C}. Vacated positions are filled
with zeros. The effect is undefined if the shift distance is not in
the range 0 to 31.

\bigskip
\noindent
{\bf RTN}\hfill {\tt  F}\\
\indent
This causes a return from the current function. The result, if any,
should be in {\tt A}.

\bigskip
\noindent
{\bf SEQ}\hfill {\tt     R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was equal to its second operand, otherwise set
it to zero.


\bigskip
\noindent
{\bf SGE}\hfill {\tt     R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was greater than or equal to its second operand
using signed arithmetic, otherwise set it to zero.

\bigskip
\noindent
{\bf SGT}\hfill {\tt     R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was greater than its second operand using signed
arithmetic, otherwise set it to zero.

\bigskip
\noindent
{\bf SLE}\hfill {\tt     R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was less than or equal to its second operand
using signed arithmetic, otherwise set it to zero.

\bigskip
\noindent
{\bf SLT}\hfill {\tt     R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was less than its second operand using signed
arithmetic, otherwise set it to zero.


\bigskip
\noindent
{\bf SNE}\hfill {\tt     R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was not equal to its second operand, otherwise
set it to zero.

\bigskip
\noindent
{\bf SUB}\hfill  {\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Subtract the second operand from the first, and set the condition code
appropriately.

\bigskip
\noindent
{\bf SUBC}\hfill {\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Subtract the condition code carry bit and the second operand from the
first, and set the condition code appropriately. Subtracting 1 from
the 64-bit value held in {\tt B:A} can be done by the code generated
by:

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
mcRK( mc_sub,  mc_a, 1)  // Don't use DEC here!!
mcRK( mc_subc, mc_b, 0)
\end{verbatim}
}


\bigskip
\noindent
{\bf UDIV}\hfill {\tt  K  R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Divide the double length value in {\tt D:A} by the specified operand.
The result is left in {\tt A} and the remainder in {\tt D}. The UDIV
instruction performs unsigned arithmetic.

\bigskip
\noindent
{\bf UJGE}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was greater than or equal to its second operand using
unsigned arithmetic.

\bigskip
\noindent
{\bf UJGT}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was greater than its second operand using unsigned
arithmetic.

\bigskip
\noindent
{\bf UJLE}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was less than or equal to its second operand using
unsigned arithmetic.

\bigskip
\noindent
{\bf UJLT}\hfill {\tt  JS JL JR}\\
\indent
Jump to the specified location if the first operand of a previous {\tt
CMP} instruction was less than its second operand using unsigned
arithmetic.

\bigskip
\noindent
{\bf UMUL}\hfill {\tt  K  R  A  V  G  M  L  D  DX  DXs  DXsB}\\
\indent
Multiply register {\tt A} by the operand placing the double length
result in {\tt D:A}. Unsigned arithmetic is used.  Immediate ({\tt K})
operands may sometimes be packed in the data area.

\bigskip
\noindent
{\bf USGE}\hfill {\tt R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was greater than or equal to its second operand
using unsigned arithmetic, otherwise set it to zero.

\bigskip
\noindent
{\bf USGT}\hfill {\tt R}\\
\indent
Set the specified register or memory word to one if the first operand
of a previous {\tt CMP} instruction was greater than its second
operand using unsigned arithmetic, otherwise set it to zero.

\bigskip
\noindent
{\bf USLE}\hfill {\tt R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was less than or equal to its second operand
using unsigned arithmetic, otherwise set it to zero.

\bigskip
\noindent
{\bf USLT}\hfill {\tt R}\\
\indent
Set the specified register to one if the first operand of a previous
{\tt CMP} instruction was less than its second operand using unsigned
arithmetic, otherwise set it to zero.

\bigskip
\noindent
{\bf XCHG}\hfill {\tt     RR RA RV RG RM RL RD RDX RDXs RDXsB}\\
\indent
Exchange the values specified by the two operands.

\bigskip
\noindent
{\bf XOR}\hfill  {\tt    RA RV RG RM RL RD RDX RDXs RDXsB}\\
\rightline       {\tt RR AR VR GR MR LR DR DXR DXsR DXsBR}\\
\rightline       {\tt RK AK VK GK MK LK DK DXK DXsK DXsBK}\\
\indent
Exclusive OR the second operand into the first.

\section{MC Debugging Aids}

The primary debugging aid is to inspect the generated code and the is
controlled by the DEBUG directive which sets the tracing level held in
the global variable {\tt mcDebug}. Assuming {\em bimc} are the least
significant four bit of {\tt mcDebug}, if $c=1$, print comments
compiled by {\tt mcComment}.  If $m=1$, print MC instructions and
directives. If $i=1$, print the corresponding target instruction(s)
and if $b=1$, print the resulting binary code in hexadecimal. To fully
understand this output it is, of course, necessary to have a good
understanding of the target architecture being used.

A second important debugging aid is provided by the {\tt mcPRF}
function which compiler code to output the value of a specified
register using a given {\tt printf} format string.  On return all
registers including the condition code are preserved. A typical call
of {\tt mcPRF} is as follows.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        mcPRF("The value of register A is %8x*n", mc_a)
\end{verbatim}
}

As an aid to debugging MC packages themselves, there is a test program
called {\tt bcplprogs/mc/mcsystest.b} which systematically tests all
MC instructions, directives and addressing modes generating error
messages for each error found. Each such error message includes a test
number which helps to locate the source of the of the problem. If {\tt
mcsystest} is given a test number as argument, it provides a detailed
compilation trace of the specified test. This should provide
sufficient information to locate the error in the package.

\section{The n-queens Demonstration}

This section shows how the algorithm to solve the n-queens problem
as described in Section~\ref{queens} on page~\pageref{queens} can be
reimplemented using the MC package. The MC version of the program
is as follows.

{\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
GET "libhdr"
GET "mc.h"

MANIFEST {
 // Register mnemonics
 ld    = mc_a
 col   = mc_b
 rd    = mc_c
 poss  = mc_d
 p     = mc_e
 count = mc_f
}

LET start() = VALOF
{ // Load the dynamic code generation package
  LET argv = VEC 50
  LET lo, hi, dlevel = 1, 16, #x0000
  LET mcname = "mci386" // Default setting
  LET mcseg = 0
  LET mcb = 0

  UNLESS rdargs("mc,lo/n,hi/n,-c/s,-m/s,-a/s,-b/s", argv, 50) DO
  { writef("Bad arguments for mcqueens*n")
    RESULTIS 0
  }

  IF argv!0 DO mcname := argv!0           // mc
  IF argv!1 DO lo := !argv!1              // lo/n
  IF argv!2 DO hi := !argv!2              // hi/n
  IF argv!3 DO dlevel := dlevel | #b0001  // -c/s   comments
  IF argv!4 DO dlevel := dlevel | #b0010  // -m/s   mc instructions
  IF argv!5 DO dlevel := dlevel | #b0100  // -a/s   assembler
  IF argv!6 DO dlevel := dlevel | #b1000  // -b/s   binary

  mcseg := globin(loadseg(mcname))

  UNLESS mcseg DO
  { writef("Trouble with MC package: mci386*n")
    GOTO fin
  }

  // Create an MC instance for hi functions with a data space
  // of 10 words and code space of 4000
  mcb := mcInit(hi, 10, 40000)

  UNLESS mcb DO
  { writef("Unable to create an mci386 instance*n")
    GOTO fin
  } 

  mc := 0          // Currently no selected MC instance
  mcSelect(mcb)

  mcK(mc_debug, dlevel)

  FOR n = lo TO hi DO
  { mcComment("*n*n// Code for a %nx%n board*n", n, n)
    gencode(n) // Compile the code for an nxn board
  }

  mcF(mc_end)

  writef("Code generation complete*n")

  FOR n = lo TO hi DO
  { LET k = 0
    writef("Calling mcCall(%n)*n", n)
    k := mcCall(n)
    writef("Number of solutions to %i2-queens is %i9*n", n, k)
  }

fin:
  IF mc    DO mcClose()
  IF mcseg DO unloadseg(mcseg)  

  writef("*n*nEnd of run*n")
}

AND gencode(n) BE
{ LET all = (1<<n) - 1
  mcKKK(mc_entry, n, 3, 0)

  mcRK(mc_mv, ld,    0)
  mcRK(mc_mv, col,   0)
  mcRK(mc_mv, rd,    0)
  mcRK(mc_mv, count, 0)

  cmpltry(1, n, all)        // Compile the outermost call of try

  mcRR(mc_mv, mc_a, count)  // return count
  mcF(mc_rtn)
  mcF(mc_endfn)
}

AND cmpltry(i, n, all) BE
{ LET L = mcNextlab()

  mcComment("*n// Start of code from try(%n, %n, %n)*n", i, n, all)

  mcRR(mc_mv,  poss, ld)         // LET poss = (~(ld | col | rd)) & all
  mcRR(mc_or,  poss, col)
  mcRR(mc_or,  poss, rd)
  mcR (mc_not, poss)
  mcRK(mc_and, poss, all)

  mcRK(mc_cmp, poss, 0)          // IF poss DO
  TEST n-i<=2
  THEN mcJS(mc_jeq, L)           // (use a short jump if near the last row)
  ELSE mcJL(mc_jeq, L)

  TEST i=n
  THEN { // We can place a queen in the final row.
         mcR(mc_inc,  count)     //   count := count+1
       }
  ELSE { // We can place queen(s) in a non final row.
         LET M = mcNextlab()

         mcL (mc_lab,  M)        // { Start of REPEATWHILE loop

         mcRR(mc_mv,   p, poss)  //   LET p = poss & -poss
         mcR (mc_neg,  p)
         mcRR(mc_and,  p, poss)  //   // p is a valid queens position
         mcRR(mc_sub,  poss, p)  //   poss := poss - p


         mcR (mc_push, ld)       //   Save current state
         mcR (mc_push, col)
         mcR (mc_push, rd)
         mcR (mc_push, poss)
                                 //   Call try((ld+p)<<1, col+p, (rd+p)>>1)
         mcRR(mc_add,  ld,  p)
         mcRK(mc_lsh,  ld,  1)   //   ld  := (ld+p)<<1
         mcRR(mc_add,  col, p)   //   col := col+p
         mcRR(mc_add,  rd,  p)
         mcRK(mc_rsh,  rd,  1)   //   rd  := (rd+p)>>1

         cmpltry(i+1, n, all)    //   Compile code for row i+1

         mcR (mc_pop,  poss)     //   Restore the state
         mcR (mc_pop,  rd)
         mcR (mc_pop,  col)
         mcR (mc_pop,  ld)

         mcRK(mc_cmp,  poss, 0)
         mcJL(mc_jne, M)         // } REPEATWHILE poss
       }

       mcL(mc_lab, L)
       mcComment("// End   of code from try(%n, %n, %n)*n*n",
                 i, n, all)
}
\end{verbatim}
}

\bigskip
In this implementation all the working variables are held in registers
and all recursive calls are unwound knowing that the depth of recursion
will be limited, in this case to no more than 16. The stack is used to
save the state at the moment when a recursive call would have been
made in the original program. An optimisation is done based on the
knowledge that if a queen can be placed on the $n$th row of $n\times
n$ board then the solution count can be incremented.

When running on a Pentium IV this implementation executes
approximately 24 times faster than the normal interpretive Cintcode
version and 25\% faster than the corresponding optimised C version of
the algorithm.



\cleardoublepage

\chapter{\label{installation}Installation}

The implementation of BCPL described in this report is freely
available via my Home Page~\cite{MyHomePage} to individuals for
private use and to academic institutions. If you install the system,
please send me an email (to {\tt mr10@cl.cam.ac.uk}) so I can keep a
record of who is interested in it.

This implementation is designed to be machine independent being based
on an interpreter written in C. There are, however, hand written
assembly language versions of the interpreter for several
architectures (including i386, MIPS, ALPHA and Hitachi SH3), although
these are now little used and are no longer maintained.  For Windows
XP and Windows 10 there are precompiled {\tt .exe} files such as {\tt
  wincintsys.exe} and {\tt winrastsys.exe}. These were constructed
under Windows XP using Visual Studio an have not been updated since I
moved to Windos 10 and so may no longer work. To try them, these files
should be copied into the appropriate {\tt bin} directory and renamed
as {\tt cintsys.exe} and {\tt rastsys.exe}.

For all the other architectures it is necessary to rebuild the system,
but this is reasonably easy to do. The simplest installation is for 32
and 64-bit Linux machines which will be covered in detail here. Both
the single threaded BCPL Cintcode System called {\tt cintsys} and the
Cintcode version of the Tripos Portable Operating System called {\tt
  cintpos} can be constructed providing a BCPL word length of 32 or 64
bits. BCPL continues to change including the addition of floating
points operations, the FLT feature and more recently the MCPL style
pattern matching features. I have recently updated the syntax
specification of BCPL using the new transition diagrams given in the
Appendix of this manual, and there is now a program ({\tt checksyn.b}
to test whether BCPL programs conform to this new syntax
specification. In due course this program will be modified to attempt
to find minimum cost syntactic corrections to erroneous programs. Such
corrections are unlikely to produce semantically correct programs but
should provide better syntactic error messages.

I repeatedly test the {\tt cintsys} and {\tt cintpos} systems on the
machines I currently own, and maintain a log of these tests in the
files {\tt CintsysTestLog.txt} in the BCPL distribution and {\tt
  CintposTestLog.txt} in the Cintpos distribution.


\section{Linux Installation} 

This section describes how to install the BCPL Cintcode System on a
Linux machine using an Intel 386 or later Intel processors. It can be
installed on both 32 and 64 bit architectures, and the size of the
BCPL word can be either 32 or 64 bits. To rebuild the BCPL Cintcode
system perform the followwing steps.

First create a directory typically named {\tt distribution} in your
home directory (\verb|$HOME|) and extract the BCPL distribution files
in {\tt bcpl.tgz} by, typically, typing the commands:

\smallskip
{\small
\begin{verbatim}
ch $HOME/distribution
tar zxvf ../Downloads/bcpl.tgz
\end{verbatim}
}
\smallskip

\noindent
This creates the directory {\tt BCPL} containing all the files needed
to rebuild the system. Next enter the {\tt cintcode} directory by
typing the following command.

\smallskip
{\small
\begin{verbatim}
cd BCPL/cintcode
\end{verbatim}
}
\smallskip

\noindent

You are now ready to rebuild the system, but first you must ensure
that the environment variables {\tt BCPLROOT}, {\tt BCPLHDRS}, {\tt
  BCPLPATH}, {\tt BCPLSCRIPTS} are properly defined. For convenience,
there is a {\tt bash} shell script in {\tt os/Linux/setbcplenv}. This
script also adds the directory {\tt cintcode/bin} to the {\tt PATH}
variable.  To set all the variables run the following command.

\smallskip
{\small
\begin{verbatim}
. $(HOME)/distribution/BCPL/cintcode/os/linux/setbcplenv
\end{verbatim}
}
\smallskip

\noindent
It is probably even better to place this line near the end of
\verb|~/.bashrc| so that the environment variables are setup every
time a new shell window is created.

You are now ready to rebuild the BCPL system by typing the following
commands.

\smallskip
{\small
\begin{verbatim}
cd $(HOME)/distribution/BCPL/cintcode
make clean
make
\end{verbatim}
}
\smallskip

\noindent
This should recompile all the C and BCPL code required by the BCPL
system and leave it waiting for the user to type a BCPL Cmmand
Language ({\tt CLI}) command. To test it
type the following commands.

\smallskip
{\small
\begin{verbatim}
type com/hello.b
c bc hello
hello
bcpl com/bcpl.b to junk
junk com/bcpl.b to junk
c bc bcpl
bench100
c bc cmpltest
cmpltest
\end{verbatim}
}
\smallskip

What the {\tt make} command did perhaps needs some
explanation. Without arguments {\tt make} reads the file {\tt Makefile}
from the current directory and performs the first action it finds in
this file. This first causes {\tt bin/cintsys} to be created by
compiling and linking all the source files needed to build {\tt
  cintsys}. But before doing this it creates the \verb|#include|
file {\tt sysc/INT.h} by compiling and running {\tt
  sysc/mkint-h.c}. {\tt INT.h} contains several \verb|#define| macros
that that allow the C programs to determine important properties of
the host machine, such as the C types for signed and unsigned
characters. The C source files for {\tt cintsys} are all in the
directory {\tt sysc/} and are:
{\tt cintsys.c},
{\tt cinterp.c},
{\tt kblib.c},
{\tt cfuncs.c},
{\tt joyfn.c},
{\tt sdlfn.c},
{\tt glfn.c} and
{\tt extfn.c}.

Although {\tt cintsys} can now be called, it will only work if precompiled
Cintcode compilations of
{\tt sysb/boot.b},
{\tt sysb/blib.b},
{\tt sysb/dlib.b},
{\tt sysb/cli.b},
are placed in the directorie {\tt cin/syscin/}. The hand written Cintcode
file {\tt syslib} must also be placed there for the (trivial) definitions
of the functions {\tt sys}, {\tt changeco} and {\tt muldiv}.
Compiled versions of the commands
{\tt abort},
{\tt c},
{\tt echo} and
{\tt bcpl} are then placed in {\tt cin/}.
Finally several scripts such as
{\tt b},
{\tt bc} and
{\tt bs} are placed in {\tt cintcode/}.
Most of these files have different versions depending on whether the
host is a big or little ender machine.

Finally, {\tt make} causes the command \verb|c compall| to be executed
on the newly created system. This compiles all the resident system
components contained in {\tt sysb} and the standard commands in {\tt
  com/}. The system is then ready for use.


You will notice that directory {\tt BCPL} contains {\tt
  BCPL/cintcode}, {\tt BCPL/bcplprogs} and {\tt BCPL/natbcpl}. The
directory {\tt BCPL/cintcode} contains all the source files of the
BCPL Cintcode System, {\tt BCPL/bcplprogs} contains a collection of
directories holding demonstration programs, and {\tt BCPL/natbcpl}
contains a version of BCPL that compiles into native code (for Intel
and ALPHA machines) using a mechanism based on the Sial abstract
machine code.

Once the system hase been built it is normally entered using the
command {\tt cintsys} which can be called when in any directory. If
anything has gone wrong various debugging aids can be turned on using either

\smallskip
{\small
\begin{verbatim} 
cintsys -f -v
\end{verbatim}
}

or 

{\small
\begin{verbatim} 
cintsys -f -vv
\end{verbatim}
}

\noindent
The output should be studied in conjunction with {\tt sysc/cintsys.c}
and {\tt sysb/boot.b}. Hopefully, there will be enough information
there to diagnose and correct the problem. It includes, in particular,
a trace of all uses of the shell environment variables which are a
common source of trouble.



Read the documentation in {\tt cintcode/doc/} and any {\tt README}
files you can find.  A log of recent changes can be found in {\tt
  cintcode/doc/changes}. A log of recent tests under different
machines and operating systems can be found in {\tt
  cintcode/CintsysTestsLog.txt}.  The current version of this BCPL
manual is available from my home page as a {\tt .pdf} file. There is
an extensive demonstration script of commands in {\tt
  cintcode/doc/notes}.


To create the 64-bit version of Cintcode BCPL, type the following.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        make clean64
        make sys64
        cintsys64
\end{verbatim}
\end{samepage}

\noindent
The resulting system is almost identical to the standard 32-bit
Cintcode BCPL system but uses a BCPL word length of 64 bits rather
that the normal 32.

Other versions of the system that can be created using other
make files, for instance:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        make -f MakefileSDL clean
        make -f MakefileSDL
\end{verbatim}
\end{samepage}

\noindent
This will provide a version with an interface to the SDL graphics
library.  An interface to the OpenGL graphics library is provided if
{\tt MakefileGL} is used. The GL version can be demonstrated by the
follow sequence of commands.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
cd $(HOME)
cd ../bcplprogs/raspi
cintsys
sysinfo
c b engine
engine
c b dragon
dragon
c b bucket
bucket
c b gltst
gltst
\end{verbatim}
\end{samepage}

\smallskip

When you enter {\tt cintsys} you can choose one of two Cintcode
interpreters. These can be selected by the commands {\tt fast} and
{\tt slow}. The slow interpreter performs more runtime checks and has
mode debugging aids than the fast interpreter and is thus somewhat
slower. Both interpreters are compilations of the same source file
{\tt sysc/cinterp.c} with the differences controlled by conditional
compilation statements such as \verb|#ifdef FASTERPyes|.

The {\tt make} command actually creates {\tt rastsys} in addition to
{\tt cintsys}. This is a verion of the system that allows the user to
generate raster data that can be used to make graphs such as the one
in Figure~\ref{bcpleps} on page~\pageref{bcpleps} showing memory
references during the compilation of a BCPL compiler. This version is
built from the same the source programs in C using conditional
compilation statements such as \verb|#ifdef RASTERPyes|.

There is a different but related system called {\tt cintpos} that is
closely related to {\tt cintsys}. It is a Cintcode based
implementation of the Tripos Portable Operating System originally
implemented at Cambridge in the late 1970s. This system allows the
user to create tasks which in modern terminology would be called
threads since they all use the same address space. Information can be
sent from one task to another using the call {\tt qpkt(pkt)}. This
appends the packet on the end of a work queue belonging to the
destination task. A task can extract the first packet on its work
queue using a call of {\tt taskwait()}. If the work queue is empty the
task becomes suspended. Every task has a distinct integer priority and
there is a scheduler that ensures the highest priority task that can
run is given control. As with the BCPL distribution, Cintpos has its
own directory \verb|~/distribution/Cintpos| and all its files are
contained in {\tt cintpos.tgz}. Two of the main programs of Cintpos
are called {\tt cintpos.c} and {\tt cinterp.c}. These have much in
common with {\tt cintsys.c} and {\tt cinterp.c} of the BCPL
distribution and the plan is make the C programs in Cintpos identical
to the corresponding ones in the BCPL distribution with the the
differences controlled by conditional compilation statements such as
\verb|#ifdef CINTSYSyes| and \verb|#ifdef CINTPOSyes|. This change is
still under development.


\section{\label{comlineargs}Command Line Arguments}

The commands {\tt cintsys}, {\tt cintsys64} and {\tt cintpos} that
invoke the Cintcode interpreter can be given various arguments.  These
are:

\bigskip
\begin{tabular}{ll}
 {\tt-m} $n$     & Set the Cintcode memory size to $n$ words.\\
 {\tt-t} $n$     & Set the tally vector size to $n$ words.\\
 {\tt-s}         & Enter the Cintcode system giving the name of this\\
                 & file as the command for the CLI to run.\\
 {\tt-q}         & Set quiet mode. This stops the resident system from\\
                 & outputting text other than error or debugging messages.\\
                 & It also stops the CLI from outputting prompts or \\
                 & echoing standard input (normally the keyboard).\\
 {\tt-c} {\em text}  & Enter cintsys with standard input\\
                 & setup to read the characters from {\em text} followed by\\
                 & an end-of-stream character.\\
 {\tt--} {\em text}  & Enter cintsys with standard input\\
                 & setup to read the characters in text followed by\\
                 & the characters of the old standard input.\\
 {\tt-f}         & Trace the use of environment variables in pathinput\\
 {\tt-v}         & Trace the bootstrapping process\\
 {\tt-vv}        & As -v, but also include some Cincode level tracing\\
 {\tt-h}         & Output some help information.
\end{tabular}

\bigskip
\noindent
The rastering versions of the interpreter {\tt rastsys}, {\tt
  rastsys64} can receive the same arguments.

\section{Installation on Other Machines}

Carry out steps 1 to 4 above.  In the directory {\tt
BCPL/cintcode/sysasm} you will find directories for different
architectures, e.g. ALPHA, MIPS, SUN4, SPARC, MSDOS, MAC, OS2, BC4,
Win32, CYGWIN32 and shWinCE. These contain files that are architecture
(or compiler) dependent, typically including {\tt cintasm.s} (or {\tt
cintasm.asm}).  For some old versions of Linux, it is necessary to
change \verb|_dosys| to \verb|dosys| (or vice-versa) in the file
{\tt sysasm/LINUX/cintasm.s}.

Edit Makefile (typically by adding and removing comment symbols) as
necessary for your system/machine and then execute {\tt make} in the
{\tt cintcode} directory, e.g:

{\small
\begin{verbatim}
       make
\end{verbatim}
}

\noindent
Variants of the above should work for the other architectures
running Unix.

\section{Installation for Windows XP}

The files {\tt wincintsys.exe} and {\tt winrastsys.exe} are included
in the standard distribution and should work under many versions of
the Windows operating systems (such as Windows XP) just by typing the
command:

{\small
\begin{verbatim}
        wincintsys
\end{verbatim}
}

It may be more convenient to move them into a different directory and
rename them as {\tt cintsys.exe} and {\tt rastsys.exe}.

I have recently upgraded the Windows version of BCPL so that it can be
compiled and run using the freely available Microsoft C compiler and
libraries. On a new PC I installed the freely available .NET Framework
3.5 and the corresponding SDK 3.5. This provided amongst many other things
a C compiler and all the relevant libraries.

I then created a shortcut on the desktop with

\begin{verbatim}
Target: %SystemRoot%\system32\cmd.exe /q /k os\windows\VC8env.bat
\end{verbatim}

\noindent
and

\begin{verbatim}
Start in: E:\distribution\BCPL\cintcode
\end{verbatim}

Double clicking on this shortcut opens a Shell window with the
required environment variable all set up C compilation and the BCPL
running environment. If they are not correct you may have to edit
{\tt VC8env.bat}. The BCPL system was then rebuilt by the commands:

\begin{verbatim}
nmake /f os/windows/MakefileVC clean
nmake /f os/windows/MakefileVC
\end{verbatim}

This should recompile and link all the C code of the BCPL Cintcode
system and then recompile all the standard BCPL system programs and
commands. For good measure, once the BCPL Cintcode system has been
entered, recompile all the BCPL code again by typing:

\begin{verbatim}
c compall
\end{verbatim}


\section{Installation using Cygwin}

I recommend using the GNU development tools and utilities for Windows
that are available from
{\tt
http://sourceware.cygnus.com/cygwin/}.

Edit the {\tt cintcode/Makefile} to comment out the LINUX version

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        CC = gcc -O9 -DforLINUX -DSOUND -DCALLC -lm
        SYSM = ../cintcode/sysasm/linux
\end{verbatim}
\end{samepage}

\noindent
and enable the CYGWIN32 version

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        CC = gcc -O9 -DforCYGWIN32 -DSOUND -DCALLC -lm
        SYSM = ../cintcode/sysasm/CYGWIN32
\end{verbatim}
\end{samepage}

Then type:

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        make
\end{verbatim}
\end{samepage}

This should recompile the system and create the executable
{\tt cintsys.exe}.

Remember to include the {\tt cintcode} directory in your {\tt PATH}
and {\tt BCPLPATH} shell variables, so that the cintsys can be run in
any directory.

Careful inspection of the Makefile and directories in {\tt cintcode/sysasm}
will show that versions also exist that use Microsoft C++ 5.0 and
Borland C4.0, but these are likely to be out of date and their
use is not recommended.

\section{Installation for Windows CE2.0}

A version of the BCPL Cintcode System is available for handheld
machines running Windows CE version 2.0. For installation details see
the README file in {\tt sysasm/shwince}. This system provides a
scrollable window for interaction with the CLI. It also provides a
simple graphical facilities using a graphics window. The system has
only been tested on an HP 620LX handheld machine.


\section{\label{native}The Native Code Version}

A BCPL native mode system for 686/Pentium based machines is in
directory {\tt BCPL/natbcpl}. It can be re-built and tested by
changing to the directory {\tt BCPL/natbcpl} and running {\tt make}.
If you have the SDL libraries installed (see {\tt bcpl4raspi.pdf}),
you could try

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        make -f MakefileSDL clean
        make -f MakefileSDL bucket
        ./bucket
\end{verbatim}
\end{samepage}


A version (64 bit) for the DEC Alpha is also available but is now out
of date and has not been tested recently. To re-build it, it is
necessary to comment out the lines for Linux and uncomment the lines
for the ALPHA in {\tt Makefile}, before running {\tt make}.

Recently, a version for the ARM processor has been added, particularly
for the Raspberry Pi machine. In directory {\tt BCPL/natbcpl} on the
Raspberry Pi, try typing

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        make -f MakefileRaspi clean
        make -f MakefileRaspi
\end{verbatim}
\end{samepage}

\noindent
If you have the SDL libraries installed (see {\tt bcpl4raspi.pdf}),
you could try

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
        make -f MakefileRaspiSDL clean
        make -f MakefileRaspiSDL bucket
        ./bucket
\end{verbatim}
\end{samepage}

\medskip
It is useful to know how the make commands such as those above
work. Here is a brief explanation.

The command {\tt make clean} just deletes all previously built
executables together with all files in the directories {\tt obj}, {\tt
  sial}, {\tt temps} and {\tt tempc} since these can easily be
recreated.

The call {\tt make prog} causes the required BCPL programs to be
compiled, if necessary, into Pentium assembly language by executing
the following CLI commands. This also ensures the C program {\tt
  tempc/initprog.c} is up to date.

\medskip

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
bcpl2sial ./prog.b to sial/prog.sial noselst
sial-686 -t  sial/prog.sial to temps/prog.s

bcpl2sial sysb/blib.b to sial/blib.sial noselst
sial-686 -t  sial/blib.sial to temps/blib.s

bcpl2sial ../cintcode/sysb/dlib.b to sial/dlib.sial noselst
sial-686 -t  sial/dlib.sial to temps/dlib.s

makeinit prog.b to tempc/initprog.c
\end{verbatim}
\end{samepage}

\medskip

If necessary {\tt make prog} also updates the header file {\tt
  tempc/INT.h} needed by {\tt clib.c} using the following {\tt bash}
commands.
 
\medskip

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
gcc -o mkint-h sysc/mkint-h.c
./mkint-h >sysc/INT.h
rm -f mkint-h
cp sysc/INT.h tempc
cp sysc/bcpl.h tempc
\end{verbatim}
\end{samepage}

\medskip
 
Finally it updates the executable {\tt prog}, if necessary, by
compiling and linking all the required C and assembly language
programs.

\medskip

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
gcc -O9 -DforLINUX -o obj/initprog.o -c tempc/initprog.c
gcc -O9 -DforLINUX -o obj/clib.o     -c sysc/clib.c
gcc -O9 -DforLINUX -o obj/kblib.o    -c sysc/kblib.c
gcc -O9 -DforLINUX -o obj/sdlfn.o    -c sysc/sdlfn.c

gcc -O9 -DforLINUX -o obj/prog.o     -c temps/prog.s
gcc -O9 -DforLINUX -o obj/blib.o     -c temps/blib.s
gcc -O9 -DforLINUX -o obj/dlib.o     -c temps/dlib.s
gcc -O9 -DforLINUX -o obj/mlib.o     -c i386/mlib.s

gcc -O9 -DforLINUX -o prog
          obj/initprog.o obj/prog.o
          obj/mlib.o     obj/clib.o  obj/blib.o
          obj/dlib.o     obj/kblib.o obj/sdlfn.o -lm
\end{verbatim}
\end{samepage}

\medskip
 
The native code program can now be executed in a {\tt bash} shell
using the command {\tt prog} or possibly {\tt ./prog}.

\pagebreak[0]

\cleardoublepage

\chapter{Example Programs}

\section{Coins}

The following program prints out how many different ways a sum of
money can be composed from coins of various denominations.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
GET "libhdr"
 
LET coins(sum) = c(sum, (TABLE 200, 100, 50, 20, 10, 5, 2, 1, 0))
 
AND c(sum, t) = sum<0 -> 0,
                sum=0 -> 1,
                !t=0  -> 0,
                c(sum, t+1) + c(sum-!t, t)
 
LET start() = VALOF
{ writes("Coins problem*n")
  t(0); t(1); t(2); t(5); t(21); t(100); t(200)
  RESULTIS 0
}
 
AND t(n) BE writef("Sum = %i3  number of ways = %i6*n", n, coins(n))
\end{verbatim}
\end{samepage}

\section{Primes}

The following program prints out a table of all primes less
than 1000, using the sieve method.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
GET "libhdr"
 
GLOBAL { count: ug  }
 
MANIFEST { upb = 999  }
 
LET start() = VALOF
{ LET isprime = getvec(upb)
   count := 0
   FOR i = 2 TO upb DO isprime!i := TRUE  // Until proved otherwise.
 
   FOR p = 2 TO upb IF isprime!p DO
   { LET i = p*p
      UNTIL i>upb DO { isprime!i := FALSE; i := i + p }
      out(p)
   }
 
   writes("*nend of output*n")
   freevec(isprime)
   RESULTIS 0
}
 
AND out(n) BE
{ IF count MOD 10 = 0 DO newline()
   writef(" %i3", n)
   count := count + 1
}
\end{verbatim}
\end{samepage}
\pagebreak[0]
\section{\label{queens}Queens}

The following program calculates the number of ways $n$ queens can be
placed on a $n\times n$ chess board without any two occupying the same
row, column or diagonal.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
GET "libhdr"
 
GLOBAL { count:200; all:201  }
 
LET try(ld, col, rd) BE TEST col=all

                        THEN count := count + 1

                        ELSE { LET poss = all & ~(ld | col | rd)
                               UNTIL poss=0 DO
                               { LET p = poss & -poss
                                 poss := poss - p
                                 try(ld+p << 1, col+p, rd+p >> 1)
                               }
                             }
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET start() = VALOF
{ all := 1
  
  FOR i = 1 TO 16 DO
  { count := 0
    try(0, 0, 0)
    writef("Number of solutions to %i2-queens is %i9*n", i, count)
    all := 2*all + 1
  }

  RESULTIS 0
}
\end{verbatim}
\end{samepage}


\section{Fridays}

The following program prints a table of how often the 13$^{th}$ day
of the month lies on each day of the week over a 400 year period.
Since there are an exact number of weeks in 4 centuries, program
shows that the $13^{th}$ is most of a Friday!

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
GET "libhdr"

MANIFEST { mon=0; sun=6; jan=0; feb=1; dec=11 }

LET start() = VALOF
{ LET count       = TABLE 0, 0, 0, 0, 0, 0, 0
   LET daysinmonth = TABLE 31,  ?, 31, 30, 31, 30,
                           31, 31, 30, 31, 30, 31
   LET days = 0
      
   FOR year = 1973 TO 1973+399 DO
   { daysinmonth!feb := febdays(year)
      FOR month = jan TO dec DO
      { LET day13 = (days+12) MOD 7
         count!day13 := count!day13 + 1
         days := days + daysinmonth!month
      }
   }
   FOR day = mon TO sun DO
     writef("%i3 %sdays*n",
            count!day,
            select(day,
                  "Mon","Tues","Wednes","Thurs","Fri","Sat","Sun")
           )
   RESULTIS 0
}

AND febdays(year) = year MOD 400 = 0 -> 29,
                    year MOD 100 = 0 -> 28,
                    year MOD 4   = 0 -> 29,
                    28

AND select(n, a0, a1, a2, a3, a4, a5, a6) = n!@a0
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 

\end{verbatim}
\end{samepage}

\section{Lambda Evaluator}

The following program is a simple parser and evaluator for lambda
expressions.

\medskip
\begin{samepage}
\renewcommand{\baselinestretch}{0.75}\small
\begin{verbatim} 
GET "libhdr"

MANIFEST {
// selectors
H1=0; H2; H3; H4

// Expression operators and tokens
Id=1; Num; Pos; Neg; Mul; Div;Add; Sub
Eq; Cond; Lam; Ap; Y
Lparen; Rparen; Comma; Eof
}

GLOBAL {
space:200; str; strp; strt; ch; token; lexval
}

LET lookup(bv, e) = VALOF
{ WHILE e DO { IF bv=H1!e RESULTIS H2!e
               e := H3!e
             }
  writef("Undeclared name %c*n", H2!bv)
  RESULTIS 0
}

AND eval(x, e) = VALOF SWITCHON H1!x INTO
{ DEFAULT:     writef("Bad exppression, Op=%n*n", H1!x)
               RESULTIS 0
  CASE Id:     RESULTIS lookup(H2!x, e)
  CASE Num:    RESULTIS H2!x
  CASE Pos:    RESULTIS eval(H2!x, e)
  CASE Neg:    RESULTIS - eval(H2!x, e)
  CASE Add:    RESULTIS eval(H2!x, e) + eval(H3!x, e)
  CASE Sub:    RESULTIS eval(H2!x, e) - eval(H3!x, e)
  CASE Mul:    RESULTIS eval(H2!x, e) * eval(H3!x, e)
  CASE Div:    RESULTIS eval(H2!x, e) / eval(H3!x, e)
  CASE Eq:     RESULTIS eval(H2!x, e) = eval(H3!x, e)
  CASE Cond:   RESULTIS eval(H2!x, e) -> eval(H3!x, e), eval(H4!x, e)
  CASE Lam:    RESULTIS mk3(H2!x, H3!x, e)

  CASE Ap:   { LET f, a = eval(H2!x, e), eval(H3!x, e)
               LET bv, body, env = H1!f, H2!f, H3!f
               RESULTIS eval(body, mk3(bv, a, env))
             }
  CASE Y:    { LET bigf   = eval(H2!x, e)
               // bigf should be a closure whose body is an
               // abstraction eg Lf Ln n=0 -> 1, n*f(n-1)
               LET bv, body, env = H1!bigf, H2!bigf, H3!bigf
               // Make a closure with a missing environment
               LET yf  = mk3(H2!body, H3!body, ?)
               // Make a new environment including an item for bv
               LET ne  = mk3(bv, yf, env)
               H3!yf := ne // Now fill in the environment component
               RESULTIS yf // and return the closure
             }
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
// ***************  Syntax analyser ***********************

// Construct       Corresponding Tree

// a ,.., z   -->  [Id, 'a'] ,..,  [Id, 'z']
// dddd       -->  [Num, dddd]
// x y        -->  [Ap, x, y]
// Y x        -->  [Y, x]
// x * y      -->  [Times, x, y]
// x / y      -->  [Div, x, y]
// x + y      -->  [Plus, x, y]
// x - y      -->  [Minus, x, y]
// x = y      -->  [Eq, x, y]
// b -> x, y  -->  [Cond, b, x, y]
// Li y       -->  [Lam, i, y]

LET mk1(x) = VALOF { space := space-1; !space := x; RESULTIS space }

AND mk2(x,y) = VALOF { mk1(y); RESULTIS mk1(x)  }

AND mk3(x,y,z) = VALOF { mk2(y,z); RESULTIS mk1(x)  }

AND mk4(x,y,z,t) = VALOF { mk3(y,z,t); RESULTIS mk1(x)  }

AND rch() BE
{ ch := Eof
  IF strp>=strt RETURN
  strp := strp+1
  ch := str%strp
}

AND parse(s) = VALOF
{ str, strp, strt := s, 0, s%0
  rch()
  RESULTIS nexp(0)
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND lex() BE SWITCHON ch INTO
{ DEFAULT:   writef("Bad ch in lex: %c*n", ch)
  CASE Eof:  token := Eof
             RETURN
  CASE ' ':
  CASE '*n' :rch(); lex(); RETURN

  CASE 'a':CASE 'b':CASE 'c':CASE 'd':CASE 'e':
  CASE 'f':CASE 'g':CASE 'h':CASE 'i':CASE 'j':
  CASE 'k':CASE 'l':CASE 'm':CASE 'n':CASE 'o':
  CASE 'p':CASE 'q':CASE 'r':CASE 's':CASE 't':
  CASE 'u':CASE 'v':CASE 'w':CASE 'x':CASE 'y':
  CASE 'z':
             token := Id; lexval := ch; rch(); RETURN

  CASE '0':CASE '1':CASE '2':CASE '3':CASE '4':
  CASE '5':CASE '6':CASE '7':CASE '8':CASE '9':
             token, lexval := Num, 0
             WHILE '0'<=ch<='9' DO
             { lexval := 10*lexval + ch - '0'
               rch()
             }
             RETURN

  CASE '-':  rch()
             IF ch='>' DO { token := Cond; rch(); RETURN }
             token := Sub
             RETURN
  CASE '+':  token := Add;    rch(); RETURN
  CASE '(':  token := Lparen; rch(); RETURN
  CASE ')':  token := Rparen; rch(); RETURN
  CASE '**': token := Mul;    rch(); RETURN
  CASE '/':  token := Div;    rch(); RETURN
  CASE 'L':  token := Lam;    rch(); RETURN
  CASE 'Y':  token := Y;      rch(); RETURN
  CASE '=':  token := Eq;     rch(); RETURN
  CASE ',':  token := Comma;  rch(); RETURN
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND prim() = VALOF
{ LET a = TABLE Num, 0
  SWITCHON token INTO
  { DEFAULT:     writef("Bad expression*n");    ENDCASE
    CASE Id:     a := mk2(Id, lexval);          ENDCASE
    CASE Num:    a := mk2(Num, lexval);         ENDCASE
    CASE Y:      RESULTIS mk2(Y, nexp(6))
    CASE Lam:    lex()
                 UNLESS token=Id DO writes("Id expected*n")
                 a := lexval
                 RESULTIS mk3(Lam, a, nexp(0))
    CASE Lparen: a := nexp(0)
                 UNLESS token=Rparen DO writef("')' expected*n")
                 lex()
                 RESULTIS a
    CASE Add:    RESULTIS mk2(Pos, nexp(3))
    CASE Sub:    RESULTIS mk2(Neg, nexp(3))
  }
  lex()
  RESULTIS a
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND nexp(n) = VALOF { lex(); RESULTIS exp(n) }

AND exp(n) = VALOF
{ LET a, b = prim(), ?

  { SWITCHON token INTO
    { DEFAULT:  BREAK
      CASE Lparen:
      CASE Num:
      CASE Id:   UNLESS n<6 BREAK
                 a := mk3(Ap,  a, exp(6));  LOOP
      CASE Mul:  UNLESS n<5 BREAK
                 a := mk3(Mul, a, nexp(5)); LOOP
      CASE Div:  UNLESS n<5 BREAK
                 a := mk3(Div, a, nexp(5)); LOOP
      CASE Add:  UNLESS n<4 BREAK
                 a := mk3(Add, a, nexp(4)); LOOP
      CASE Sub:  UNLESS n<4 BREAK
                 a := mk3(Sub, a, nexp(4)); LOOP
      CASE Eq:   UNLESS n<3 BREAK
                 a := mk3(Eq,  a, nexp(3)); LOOP
      CASE Cond: UNLESS n<1 BREAK
                 b := nexp(0)
                 UNLESS token=Comma DO writes("Comma expected*n")
                 a := mk4(Cond, a, b, nexp(0)); LOOP 
    }
  } REPEAT
  RESULTIS a
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND try(expr) BE
{ LET v = VEC 2000 
  space := v+2000
  writef("Trying %s*n", expr)
  writef("Answer: %n*n", eval(parse(expr), 0))
}

AND start() = VALOF
{ try("(Lx x+1) 2")
  try("(Lx x) (Ly y) 99")
  try("(Ls Lk s k k) (Lf Lg Lx  f x (g x)) (Lx Ly x) (Lx x) 1234")
  try("(Y (Lf Ln n=0->1,n**f(n-1))) 5")
  RESULTIS 0
}
\end{verbatim}
\end{samepage}

\section{Fast Fourier Transform}

The following program is a simple demonstration of the algorithm
for the fast fourier transform.  Instead of using complex numbers, it
uses integer arithmetic modulo 65537 with an appropriate N$^{th}$ 
root of unity.

\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
GET "libhdr"

MANIFEST {
modulus = #x10001  // 2**16 + 1

$$ln10  // Set condition compilation flag to select data size
//$$walsh

$<ln16 omega = #x00003; ln = 16 $>ln16  // omega**(2**16) = 1
$<ln12 omega = #x0ADF3; ln = 12 $>ln12  // omega**(2**12) = 1
$<ln10 omega = #x096ED; ln = 10 $>ln10  // omega**(2**10) = 1
$<ln4  omega = #x08000; ln = 4  $>ln4   // omega**(2**4)  = 1
$<ln3  omega = #x0FFF1; ln = 3  $>ln3   // omega**(2**3)  = 1

$<walsh  omega=1   $>walsh    // The Walsh transform                               

N       = 1<<ln    // N is a power of 2
upb     = N-1
}

STATIC   { data=0  }
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
LET start() = VALOF
{  writef("fft with N = %n and omega = %n modulus = %n*n*n",
                    N,         omega,     modulus)

   data := getvec(upb)

   UNLESS omega=1 DO   // Unless doing Walsh tranform
     check(omega, N)   //   check that omega and N are consistent

   FOR i = 0 TO upb DO data!i := i
   pr(data, 7)
// prints  -- Original data
//     0     1     2     3     4     5     6     7

   fft(data, ln, omega)
   pr(data, 7)
// prints   -- Transformed data
// 65017 26645 38448 37467 30114 19936 15550 42679

   fft(data, ln, ovr(1,omega))
   FOR i = 0 TO upb DO data!i := ovr(data!i, N)
   pr(data, 7)
// prints  -- Restored data
//     0     1     2     3     4     5     6     7
   RESULTIS 0
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND fft(v, ln, w) BE  // ln = log2 n    w = nth root of unity
{ LET n = 1<<ln
  LET vn = v+n
  LET n2 = n>>1

  // First do the perfect shuffle
  reorder(v, n)

  // Then do all the butterfly operations
  FOR s = 1 TO ln DO
  { LET m = 1<<s
    LET m2 = m>>1
    LET wk, wkfac = 1, w
    FOR i = s+1 TO ln DO wkfac := mul(wkfac, wkfac)
    FOR j = 0 TO m2-1 DO
    { LET p = v+j
      WHILE p<vn DO { butterfly(p, p+m2, wk); p := p+m }
      wk := mul(wk, wkfac)
    }
  }
}

AND butterfly(p, q, wk) BE { LET a, b = !p, mul(!q, wk)
                             !p, !q := add(a, b), sub(a, b)
                           }
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND reorder(v, n) BE
{ LET j = 0
  FOR i = 0 TO n-2 DO
  { LET k = n>>1
    // j is i with its bits is reverse order
    IF i<j DO { LET t = v!j; v!j := v!i; v!i := t }
    // k  =  100..00       10..0000..00
    // j  =  0xx..xx       11..10xx..xx
    // j' =  1xx..xx       00..01xx..xx
    // k' =  100..00       00..0100..00
    WHILE k<=j DO { j := j-k; k := k>>1 } //) "increment" j
    j := j+k                              //)
  }
}

AND check(w, n) BE
{ // Check that w is a principal nth root of unity
  LET x = 1
  FOR i = 1 TO n-1 DO { x := mul(x, w)
                        IF x=1 DO writef("omega****%n = 1*n", i)
                      }
  UNLESS mul(x, w)=1 DO writef("Bad omega**%n should be  1*n", n)
}

AND pr(v, max) BE
{ FOR i = 0 TO max DO { writef("%I5 ", v!i)
                        IF i MOD 8 = 7 DO newline()
                      }
  newline()
}
\end{verbatim}
\end{samepage}
\pagebreak[0]\vspace{-5mm}
\begin{samepage}
\renewcommand{\baselinestretch}{0.8}\small
\begin{verbatim} 
AND dv(a, m, b, n) = a=1 -> m,
                     a=0 -> m-n,
                     a<b -> dv(a, m, b MOD a, m*(b/a)+n),
                     dv(a MOD b, m+n*(a/b), b, n)


AND inv(x) = dv(x, 1, modulus-x, 1)

AND add(x, y) = VALOF
{ LET a = x+y
  IF a<modulus RESULTIS a
  RESULTIS a-modulus
}

AND sub(x, y) = add(x, neg(y))

AND neg(x)    = modulus-x

AND mul(x, y) = x=0 -> 0,
                (x&1)=0 -> mul(x>>1, add(y,y)),
                add(y, mul(x>>1, add(y,y)))

AND ovr(x, y) = mul(x, inv(y))

\end{verbatim}
\end{samepage}

%\pagebreak[0]\vspace{-5mm}
%\begin{samepage}
%\renewcommand{\baselinestretch}{0.8}\small
%\begin{verbatim}
%\end{verbatim}
%\end{samepage}



\cleardoublepage
\addcontentsline{toc}{chapter}{Bibliography}
\markboth{BIBLIOGRAPHY}{BIBLIOGRAPHY}
\bibliography{bibdatabase}

\appendix

\cleardoublepage

\chapter{BCPL Syntax Diagrams\label{syntax}}

This appendix gives the precise syntax of BCPL as it is now, at
least in February 2022. It includes the floating point operators,
the {\tt FLT} feature and the newly added pattern matching constructs.
It also contains some constructs from older versions of BCPL to make
compilation of older BCPL programs easier.

The syntax of programming languages is often specified using Backus
Naur Form or BNF.  Mathematicians like BNF notation because of its
simplicity, power and interesting properties, while language designers
like it because the rules just confirm their understanding of the
language grammar they are designing.  For users, understanding a
grammar from its BNF specification is harder.  There are typically a
hundreds of syntactic categories, many with artificial names,
and a greater number of rules. Understanding the rules is hard because
they mostly depend on each other.  There is also sometimes a problem
noticing whether a BNF grammar is ambiguous. Indeed it is not
possible, in general, to write a program that can determine whether a
BNF grammar is ambiguous, and it is also not always easy to write a
parser that precisely agrees with the BNF specification. 

The BCPL syntax is given using the diagrams shown in figures
\ref{b-prog}, \ref{b-decl}, \ref{b-mlist}, \ref{b-pat}, \ref{b-com},
\ref{b-bexp} and \ref{b-exp}
for the syntactic categories {\tt Prog},
{\tt D}, {\tt Mlist}, {\tt Pn}, {\tt C}, {\tt Bexp} and {\tt En}.
In the diagrams these categories are represented by the rounded
boxes:

\noindent
\raisebox{-6pt}{\includegraphics[width=16.9mm]{bfigs/sym-prog.png}},
\raisebox{-6pt}{\includegraphics[width=10.6mm]{bfigs/sym-decl.png}},
\raisebox{-6pt}{\includegraphics[width=19.1mm]{bfigs/sym-mlist.png}},
\raisebox{-6pt}{\includegraphics[width=12.9mm]{bfigs/sym-pat.png}},
\raisebox{-6pt}{\includegraphics[width=10.6mm]{bfigs/sym-com.png}},
\raisebox{-6pt}{\includegraphics[width=16.9mm]{bfigs/sym-bexp.png}},
and
\raisebox{-6pt}{\includegraphics[width=12.9mm]{bfigs/sym-exp.png}}.

A rectangular boxes are called a test boxes and may contain a terminal
symbols as in
\raisebox{-6pt}{\includegraphics[width=19.1mm]{bfigs/sym-while.png}}
or
\raisebox{-6pt}{\includegraphics[width=12.9mm]{bfigs/sym-lshift.png}},
or a label representing a set of terminal symbols or some other
condition. These test box labels are specified in the following table.

\smallskip

\bigskip
\begin{tabular}{l|l}
  Label         & Possible symbols or condition \\
  \hline
  {\tt name}    & A name not preceded by {\tt FLT} \\
  {\tt fname}   & A name possibly preceded by {\tt FLT} \\
  {\tt number}  & Integer or floating point constant \\
  {\tt bpat}    & Possibly signed integer or floating point constant, \\
                & character constant, {\tt TRUE}, {\tt FALSE}, {\tt ?}, \\
                & or a name not preceded by {\tt FLT} \\
  {\tt string}  & A string constant \\
  {\tt mulop}   & \verb|* / MOD #* #/ #MOD| \\
  {\tt posop}   & \verb|+ - ABS #+ #- #ABS| \\
  {\tt addop}   & \verb|+ - #+ #-| \\
  {\tt relop}   & \verb| =  ~=  <  <=  >  >=| \\
                & \verb|#= #~= #< #<= #> #>=| \\
  {\tt fcond}   & \verb|->  #->| \\
  {\tt range}   & \verb|..  #..| \\
  {\tt jcom}    & \verb|NEXT EXIT BREAK LOOP ENDCASE| \\
  {\tt assop}   & \verb| :=    *:=   /:=   MOD:=    +:=    -:=| \\
                & \verb|#:=   #*:=  #/:=  #MOD:=   #+:=   #-:=| \\
                & \verb!<<:=  >>:=  &:=      |:=  EQV:=  XOR:=! \\
  {\tt iscall}  & This is only satisfied if the most recent construct \\
                & was a function, routine or method call \\
  {\tt isname}  & This is only satisfied if the most recent construct \\
                & was a name not enclosed in parentheses\\
  {\tt nonl}    & This is only satisfied if the previous and current \\
                & tokens are on the same line\\
  {\tt defop}   & This is satisfied when reading a {\tt GLOBAL}\\
                & declaration if the current token is {\tt :}\\
                & This is also satisfied when reading a {\tt MANIFEST}\\
                & or {\tt STATIC} declaration if the current token is {\tt =}\\
  {\tt eof}     & This is only satisfied if the program file is exhausted\\
\end{tabular}

\bigskip
\noindent


\medskip
For compatibility with older versions of BCPL some terminal symbols have
synonyms as follow.

\medskip
\begin{tabular}{l|l}
  Symbol & Possible synonyms \\
  \hline
  \verb|{| & \verb|$(|, possibly tagged \\
  \verb|}| & \verb|$)|, possibly tagged \\
  \verb|DO| & \verb|THEN| \\
  \verb|THEN| & \verb|DO| \\
  \verb|MOD| & \verb|REM| \\
  \verb|NOT| & \verb|~| \\
  \verb|OF| & \verb|::| \\
  \verb|= ~=| & \verb|EQ NE| \\
  \verb|< <=| & \verb|LS LE| \\
  \verb|> >=| & \verb|GR GE| \\
  \verb|<< >>| & \verb|LSHIFT RSHIFT| \\
  \verb/& |/ & \verb|LOGAND LOGOR| \\
  \verb|XOR| & \verb|NEQV| \\
  
\end{tabular}

\smallskip

%\begin{figure}[tbh!]
%\leftline{\includegraphics[width=230.0mm]{bfigs/sym-scaletst.png}}
%\caption{The definition of scaletst}
%\end{figure}


\begin{figure}[tbh!]
\centerline{\includegraphics[width=184.0mm]{bfigs/b-prog.png}}
\caption{\label{b-prog}The definition of
\raisebox{-6pt}{\includegraphics[width=16.9mm]{bfigs/sym-prog.png}}}
\end{figure}


\begin{figure}[tbh!]
\centerline{\includegraphics[width=149.7mm]{bfigs/b-decl.png}}
\caption{\label{b-decl}The definition of
\raisebox{-6pt}{\includegraphics[width=10.6mm]{bfigs/sym-decl.png}}}
\end{figure}


                                         
\begin{figure}[tbh!]
\centerline{\includegraphics[width=101.6mm]{bfigs/b-mlist.png}}
\caption{\label{b-mlist}The definition of
\raisebox{-6pt}{\includegraphics[width=19.1mm]{bfigs/sym-mlist.png}}}
\end{figure}


\begin{figure}[tbh!]
\centerline{\includegraphics[width=131.0mm]{bfigs/b-pat.png}}
\caption{\label{b-pat}The definition of
\raisebox{-6pt}{\includegraphics[width=12.9mm]{bfigs/sym-pat.png}}}
\end{figure}



\begin{figure}[tbh!]
\centerline{\includegraphics[width=193.0mm]{bfigs/b-com.png}}
\caption{\label{b-com}The definition of
\raisebox{-6pt}{\includegraphics[width=10.6mm]{bfigs/sym-com.png}}}
\end{figure}


\begin{figure}[tbh!]
\centerline{\includegraphics[width=126.5mm]{bfigs/b-bexp.png}}
\caption{\label{b-bexp}The definition of
\raisebox{-6pt}{\includegraphics[width=16.9mm]{bfigs/sym-bexp.png}}}
\end{figure}


\begin{figure}[tbh!]
\centerline{\includegraphics[width=140.3mm]{bfigs/b-exp.png}}
\caption{\label{b-exp}The definition of
\raisebox{-6pt}{\includegraphics[width=12.9mm]{bfigs/sym-exp.png}}}
\end{figure}


%\cleardoublepage

\chapter{The Syntax of Lexical Tokens}}

{\em This appendix is currently under construction}
  
The previous appendix specifies the syntax of BCPL based on a stream
of lexical tokens. This appendix given a precise description of the
compiler function {\tt lex} which reads the source characters of a
BCPL program creating the corresponding sequence of lexical
tokens. Each call returns the next lexical token. The syntax of lextical
token is specified by flow graphs similar to thos in Appendix A but
are based on a stream of input characters rather the tokens.

As in the previous appendix, rectangular boxes are called a test
boxes. Each can contain the specification of one or more characters
that must match the current input. For instance,
\raisebox{-6pt}{\includegraphics[width=15.1mm]{bfigs/lx-assign.png}}
will succeed if the next two input characters are ':' followed by '='
advancing the input stream appropriately. On failure input is not
advanced.
The testbox
\raisebox{-6pt}{\includegraphics[width=21.3mm]{bfigs/lx-isassign.png}}
is similar to
\raisebox{-6pt}{\includegraphics[width=15.1mm]{bfigs/lx-assign.png}}
but does not advance the input when successful.
A testbox can contain choices seperated by spaces such as
\raisebox{-6pt}{\includegraphics[width=16.9mm]{bfigs/lx-xorX.png}}.
This will match an upper or lowercase {\tt X}
A testbox can contain ranges of characters as in
\raisebox{-6pt}{\includegraphics[width=33.8mm]{bfigs/lx-hex.png}} which
will match a hexadecimal digit.
A testbox may contain a label representing a set of terminal symbols
or some other condition. These test box labels are specified in the
following table.

\smallskip

\bigskip
\begin{tabular}{l|l}
  Label         & Possible symbols or condition \\
  \hline
  {\tt[white space]}& Skip over spaces and tabs but not nelines \\
                    & or newpage characters. \\
  {\tt[skip to eol }& Skip over all characters upto but not including \\
                    & the next newline or newpage character. \\
  {\tt[letter]}     & This is successful if the next character is \\
                    & an upper or lower case letter. \\
  {\tt[rdtag]}      & This read zero or more tag characters, namely \\
                    & letters, decimal digits, an underscores and dots, \\
                    & but two consecutive dots are not permitted. \\
  {\tt[is text]}    & This is successful if the input matches the \\
                    & specified text, but the input is not advanced. \\
  {\tt[rtn number]} & This causes the function to return with \\
                    &  an integer or floatin gpoint constant. \\
  {\tt[rtn token]}  &  This causes the function to return with \\
                    &  the specified token. \\
  {\tt[deal with dot]}  & If reading a GET file, it resumes the previous \\
                        & input, otherwise it returns a dot. \\
  {\tt[deal with \$tag]} & If skiptag=0 and the value of tag \\
                        & is false, set skiptag to tag and skip \\
                        & tokens until a matching {\tt\$>tag} is found, \\
                        & or eof or end of a section is encountered. \\
  {\tt[deal with \$~tag]} & If skiptag=0 and the value of tag \\
                         & is true set skiptag to tag and skip \\
                         & tokens until a matching {\tt\$>tag} is found,\\
                         & or eof or end of a section is encountered. \\
  {\tt[deal with \$>tag]} & If skiptag=tag set skiptag=0 to indicate \\
                         & that tokens are no longer being skipped \\
                         & and read another token. \\
  {\tt[deal with \$\$tag]} & If not skipping, complement the value of \\
                         & tag and read another token. \\
  {\tt[eof]}    & This is only satisfied if the input stream is \\
                & exhausted. \\
\end{tabular}

\bigskip
\noindent

Underscores are permitted before any digit in an integer or floating
point constant but may not be the first digit has been
encountered. Similarly underscores are allowed before binary, octal
and hexadecimal digits in bit pattern constants starting with {\tt\#}.
Note that no floating point operator starts with {\tt\#B}, {\tt\#O},
{\tt\#X}.

Several lexical tokens have reserved word synonyms. These are:

\medskip

{\small
\begin{verbatim}
    =  >= > <= <    &     |     <<     >>    MOD  !
\end{verbatim}
}
\smallskip
\noindent
and their reserved words are:
\smallskip

{\small
\begin{verbatim}
   EQ GE GR LE LS LOGAND LOGOR LSHIFT RSHIFT REM RV
\end{verbatim}
}

\smallskip
\noindent
The reserved words can occur in composite tokens such as:
{\tt LS:=} or {\tt\#GE} which represent {\tt <:=} and {\tt\#>=}.
These synonyms are in the language because BCPL originally ran on
machines with very restricted character sets.

\begin{figure}[tbh!]
\centerline{\includegraphics[width=199.6mm]{bfigs/lx-part1.png}}
\caption{\label{lx-part1}The syntax of tokens starting with
 a digit, {\tt'.'} of {\tt\#} }
\end{figure}

\medskip

\begin{figure}[tbh!]
\centerline{\includegraphics[width=130.1mm]{bfigs/lx-part2.png}}
\caption{\label{lx-part2}The syntax of the other lexical tokens}
\end{figure}

\medskip

\begin{figure}[tbh!]
\centerline{\includegraphics[width=114.9mm]{bfigs/lx-part3.png}}
\caption{\label{lx-part3}The specification of 
\raisebox{-6pt}{\includegraphics[width=38.3mm]{bfigs/lx-dealwithword.png}}}
\end{figure}

\medskip

\begin{figure}[tbh!]
\centerline{\includegraphics[width=113.6mm]{bfigs/lx-part4.png}}
\caption{\label{lx-part4}The specification of
\raisebox{-6pt}{\includegraphics[width=27.6mm]{bfigs/lx-stringch.png}}}
\end{figure}

\medskip

%\include{finalpages}

\end{document}

