User guide
4.2. BOOTSTRAPPING CINTPOS 103
startroot is entered by the recursive call of interpret from BOOT with a new
stack and a different global vector from that used by BOOT. If the interpreter sub-
sequently detects a fault it returns to BOOT’s running envi r onme nt 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 startroot has three formal parameters fn, size and c, it was entered
in a non standard way and these have not been given values. However, the base of
startroot’s stack is at @fn-3. This points to the zeroth e l e me nt hol di ng the stack size
with all other elements are already set by BOOT to stackword (#xABCD1234). This
stack is tur ne d into a coroutine stack by updating its bottom six eleme nts appropriately.
Care is taken to ensure that the code that performs this initialisation i s not itself using
the stack locations that it is updating. This is one of the reasons why startroot was
given three parameters.
The function rootcode is now called to create the Cintpos resi de nt structures. At
this moment the base of the global vector is at @globsize (=Global 0), all its elements
are filled with words of the form globword+n (=#8F8F0000+n), except for globsize
which holds the upper bound of the global vector, sys which holds the entry point
of the sys function, rootnode which points to the rootnode, an d currco and colist
which both point to the newly cr eat ed coroutine stack. The other globals are now
initialised by two calls of sys(Sys_globin,...).
Cintpos has two vectors tasktab and 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 -1,
-2 and -3 corresponding t o the clock, t he keyboard and the screen. Most Cintsys
devices are implemented usi ng separate threads of the underlying operating system.
Such device s have device control blocks (DCBs) held their entries in devtab. A DCB
has fields used for communic at i on 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 devtab points to a DCB. Devices not using the polli ng 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 ar e
the keyboard and TCP devices. Device threads are created using the kernel function
createdev defined in sysb/klib.b, and the C code for the resident dev i c e threads can
be found in sysc/devices.c.
The Cintcode abstr ac t machine can receive interrupts. The mechanism is as follows.
If a device wi s he s to interrupt the interpre t er it sets the var i abl e irq to TRUE, and just
before the interpreter starts to execute an instruction, if the Ci ntp os 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 isrregs. The interrupt
service routine has it s own stack but shares the same global vector a the Cintpos kernel.