|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 207360 (0x32a00)
Types: TextFile
Names: »D99«
└─⟦5dbd6b396⟧ Bits:30005867/disk12.imd Dokumenter (RCSL m.m.)
└─⟦this⟧ »D99«
zone convert(10,1,stderror); integer array ia(1:20); getzone6
open(convert,0,<:dummy:',0);
repeat
write(convert,<<ddd.dd>dd', the number to be converted,false,2);
comment the partial word has been forced into the buffer by the
2 null characters;
getzone6(convert,ia);
ia(12):= 1; ia(14):= ia(19); ia(16):= 40;
setzone6(convert,ia);
comment Now the record contains the number in character form.
record base and partial word are ready for converting the
next number;
x1:= long convert(1); x2:= long convert(2); ...
until ...;
comment the zone convert must n_o_t_ be closed;
E_x_a_m_p_l_e_ _3_: improved setposition:
The procedures getposition, setposition do only
enable a device to be positioned at the beginning
of a block. You may resume reading from the middle
of a block on magnetic tape or backing storage in
this way:
begin
zone z(...), z1(...);
integer array ia(1:20);
integer pos1, pos2, pos3, pos4, c;
integer field paritial _word, record _base, used _share,
no _of _shares, base _buf _area, buf _length;
partial _word := 12*2;
record _base := 14*2;
used _share := 17*2;
no _of _shares := 18*2;
base _buf _area := 19*2;
buf _length := 20*2;
\f
comment generalised getposition;getzone6
read (z, ...);
getposition (z, pos1, pos2);
getzone6 (z, ia);
pos3:= ia.record _base - ia.base _buf _area -
ia.buf _length*4//ia.no _of _shares *
(ia.used share-1);
<*pos3 is the relative position within the used share*'
pos4:= ia.partial _word;
comment generalised setposition, perhaps with the
device connected to another zone;
setposition (z1, pos1, pos2);
readchar (z1, c);
<* now the device is positioned and the first
block is read into the first share *'
getzone6 (z1, ia);
ia.record _base:= pos3 + ia.base _buf _area;
ia.partial _word:= pos4;
setzone6 (z1, ia);
read (z1, ...);
\f
F_ 2_._5_9_ _ _ _ _ _ _g_o_t_o_ 2.59 goto
This delimiter, which is a sequential operator, can be used to
change the program flow.
S_y_n_t_a_x_: goto <designational expression'
S_e_m_a_n_t_i_c_: A goto statement interrupts the normal
sequence of operations. The next statement to
be executed will be the one having this value
as its label.
A jump (by a goto statement) out of an activity or
a disable statement is not allowed. This will give
the run time alarm "goto" (alarmcause = -14).
A jump (by a goto statement) into a for-, repeat-,
or while- statement is also forbidden. This will
give the error message "for label" during the
compilation.
E_x_a_m_p_l_e_ _1_: a:= q;
if a ' p then goto lab;
....
lab:
b:= a + 17;
\f
F_2_._6_0_ _ _ _ _ _ _g_r_e_a_t_e_r_ _t_h_a_n_ _(_'_)_ 2.60 greater than
This delimiter, which is a relational operator, yields the value
true or false.
S_y_n_t_a_x_: <operand1' ' <operand2'
P_r_i_o_r_i_t_y_: 5
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real.
R_e_s_u_l_t_ _t_y_p_e_s_: always boolean.
S_e_m_a_n_t_i_c_: The relation takes on the value true whenever the
corresponding relation is satisfied for the
expressions involved, otherwise false.
In case one of the operands is different from type
integer the relation is executed as a subtraction.
Thus you must be prepared for overflow, underflow,
or spill (see example 3 of monitor).
E_x_a_m_p_l_e_ _1_: a:= b ' c;
if d ' q then ... else ...;
while k ' l do ...;
\f
F_2_._6_1_ _ _ _ _ _ _g_r_e_a_t_e_r_ _t_h_a_n_ _o_r_ _e_q_u_a_l_ _(_'_=_)_ 2.61 greater than
or equal
This delimiter, which is a relational operator, yields the value
true or false.
S_y_n_t_a_x_: <operand1' '= <operand2'
P_r_i_o_r_i_t_y_: 5
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real.
R_e_s_u_l_t_ _t_y_p_e_: always boolean.
S_e_m_a_n_t_i_c_: The relation takes on the value true whenever the
corresponding relation is satisfied for the
expressions involved, otherwise false.
The relation is always executed as a subtrac-
tion. Thus, you must be prepared for overflow,
underflow, or spill.
E_x_a_m_p_l_e_ _1_: q:= a '= c;
if d '= k then ... else ...;
while x '= y do ...;
\f
F_ 2_._6_2_ _ _ _ _ _ _i_m_p_l_i_c_a_t_i_o_n_ _(_=_'_)_ 2.62 implication
This delimiter, which is a logical operator, yields the logical
implication of the two operands.
S_y_n_t_a_x_: <operand1' =' <operand2'
P_r_i_o_r_i_t_y_: 9
O_p_e_r_a_n_d_ _t_y_p_e_s_: boolean
R_e_s_u_l_t_ _t_y_p_e_: boolean.
S_e_m_a_n_t_i_c_: The truth value is determined according to the
following rule:
right
left true false
true true false
false true true
\f
F_ 2_._6_3_ _ _ _ _ _ _i_n_ 2.63 in
This standard identifier is a preopened z_o_n_e_ available for input
on character level. The actual file connected to the zone is
determined by the file processor command which started the pro-
gram (see ref. 15).
The call <program' will let >in> be connected to the current
input file of the file processor.
The call <program' <text file' will let >in> be connected to the
file <text file', if the program is not translated with the pa-
rameter connect.no.
The call <program' <integer' makes >in> and the file processor
unavailable (but frees some space in the job area), if the
program is translated with the parameter fp.no.
When the program terminates, the latest operation on >in> must
have been a call of a character reading procedure.
E_x_a_m_p_l_e_ _1_: read (in,a,b,c);
readchar (in,char);
E_x_a_m_p_l_e_ _2_: prog= algol connect.no ...
prog param ; the program will n_o_t_ use param
; as input text file.
E_x_a_m_p_l_e_ _3_: prog= algol fp.no ...
prog 7; in/out fp are removed from the process
\f
F_ 2_._6_4_ _ _ _ _ _ _i_n_c_r_e_a_s_e_ 2.64 increase
This integer standard procedure is used in connection with a
variable text as parameter to write, open etc.
C_a_l_l_: increase (i)
increase (return value, integer). The
procedure performs:
increase:= i; i:= i + 1;
but i is only evaluated once.
i (call and return value, integer).
E_x_a_m_p_l_e_ _1_: This procedure could be used in a procedure call,
where the formal parameter is a string, but the
actual parameter is a real array, when the par-
ameter is referenced only once.
The zonerecord in zone z contains a text from
element 4. This text can be written out by:
i:= 4;
write (out, string z (increase(i));
\f
F_ 2_._6_5_ _ _ _ _ _ _i_n_i_t_k_e_y_ 2.65 initkey
This standard procedure generates a piece of code for comparison
of two records in a zone. Succeeding calls of the procedure
newsort, outsort, and lifesort with the zone as parameter will
cause this code to be used, provided the second parameter in the
calls is omitted (see procedure newsort).
This procedure is the A_L_G_O_L_5_ version of changekey6, and must not
be used if the sorting was initiated by startsort6.
C_a_l_l_: initkey (z, keydescr, n)
z (call and return value, zone). The
name of the zone used for sorting.
keydescr (call value, array). A real array
holding information about types and
relative locations of the key field
in a record (see below).
n (call value, integer). Number of key
fields (number of rows in keydescr).
K_e_y_ _d_e_s_c_r_i_p_t_i_o_n_: The array keydescr must be declared as:
array keydescr(1:n, 1:2);
with the restriction:
1 <= n <= 4 * max. record length
Each row in the array holds a description of a
key field in the records to be sorted. The
priority of the key decreases with increasing
row number of their description, so the highest
priority key is described in the first row, and
so on.
\f
Column one holds information about key field initkey
type and rule of sequencing. For the key field
type the following conventions hold:
v_a_l_u_e_ k_e_y_ _f_i_e_l_d_ _t_y_p_e_
+_1 12-bit integer
+_2 24-bit integer
+_4 48-bit real
A long field or a 12-bit unsigned integer
cannot be specified as a key field.
The sign of the type descriptor indicates the
rule of sequencing: plus for ascending, minus
for descending.
Column two is the relative location of the
described field within a record. The meaning of
this location is related to the key field type
as follows (r stands for record length):
k_e_y_ _f_i_e_l_d_ _t_y_p_e_ p_o_s_s_i_b_l_e_ _r_e_l_a_t_i_v_e_ _l_o_c_a_t_i_o_n_s_
48-bit real 1,2,3,...,r-1,r
24-bit integer 1,1.5,2,2.5,...,r,r+0.5
12-bit integer 1,1.25,1.5,1.75,2,...,r,r+0.25,
r+0.5,r+0.75
This means that the relative location of a key
field is counted in fractions of reals.
Z_o_n_e_ _s_t_a_t_e_: The zone state must be 9, in sort, i.e.
initsort must have been called. The state is
not changed by the procedure.
\f
E_x_a_m_p_l_e_ _1_: A certain sort key consists of an integer, two initkey
halfwords and a real stored in this order in
double words 2 and 3 of a record. The following
sequence is wanted:
1. ascending on the real.
2. descending on the first halfword.
3. descending on the integer.
4. ascending on the second halfword.
The following program will generate a proper
code for comparison of two records.
begin zone z(size, 1, error);
real array crit(1:4, 1:2);
crit(1,1):= 4; crit(1,2):= 3;
crit(2,1):= -1; crit(2,2):= 2.5;
crit(3,1):= -2; crit(3,2):= 2;
crit(4,1):= 1; crit(4,2):= 2.75
initsort(z, length); initkey(z, crit, 4);
.....
end; \f
F_2_._6_6_ _ _ _ _ _ _i_n_i_t_s_o_r_t_ 2.66 initsort
This standard procedure initiates a sorting process in a zone, so
that the procedures newsort, outsort, deadsort, and lifesort can
be used with that zone as a parameter.
This procedure is the A_L_G_O_L_5_ version of startsort6, and must not
be used together with changekey6. A call of initsort followed by
a call of initkey is analoguos to a call of startsort6.
C_a_l_l_: initsort (z, length)
z (call and return value, zone). The name of
the zone used for sorting.
length (call value, integer). Max. length in
double words of the records to enter the
sorting process.
Z_o_n_e_ A sort zone capable of holding N records at the
d_e_c_l_a_r_a_t_i_o_n_: same time must be declared as follows:
zone z((N+9)*(length+1), 1, error)
where length is max. record length. The
declaration has the same form as a zone
declaration for input/output use with buffer
length = (N+9)*(length+1) and no. of shares = 1.
The error procedure must be supplied by the user,
as described in startsort6.
Z_o_n_e_ _s_t_a_t_e_: The zone must be in state 4, after declaration.
The state becomes 9, in sort.
\f
F_ 2_._6_7_ _ _ _ _ _ _i_n_i_t_z_o_n_e_s_ 2.67 initzones
This procedure changes the buffersize and number of shares of
each zone in a zone array.
C_a_l_l_: initzones (za, bufsize, shares)
za (call and return value, zone array). The
buffersize and number of shares are
changed for all zones:
za(1), za(2), ... za(no. of zones). The
zone states must be 4 (after declara-
tion) for all za(i).
bufsize (call value, integer array). Bufsize(i)
specifies the number of elements of 4
halfwords each in the bufferarea to be
allocated to the zone za(i).
shares (call value, integer array). Shares(i)
specifies the number of shares to be
assigned to za(i).
N_o_t_e_: The sum of all bufsize(i), 1 <= i <= no _of _zones,
must not exceed the original total buffer size for
the zone array za, as determinated by the declara-
tion. Obviously bufsize(i) and shares(i) must be
positive integers.
Z_o_n_e_ _s_t_a_t_e_: All zones of the zone array must be in state 4,
after declaration. The zone state is not changed
by the procedure.
\f
E_x_a_m_p_l_e_ _1_: The procedure can be used in a program where a num- initzones
ber of files are handled by means of a logical file
number, but the files use different block lengths:
begin
zone array za(n, total _bufsize//n, shares, stderror);
integer array buf, sh(1:n);
<* blocklength, no _of _shares*'
buf(1):= 128; sh(1):= 1; <*file1: 1 1 *'
buf(2):= 128*2; sh(2):= 2; <*file2: 1 2 *'
buf(3):= 128*4; sh(3):= 1; <*file3: 4 1 *'
...
initzones (za, buf, sh);
...
open(z(i), ...);
invar(z(i)); <* read from file no. i *'
\f
F_ 2_._6_8_ _ _ _ _ _ _i_n_r_e_c_ 2.68 inrec
This integer standard procedure is the A_L_G_O_L_5_ version of inrec6.
Inrec gets a sequence of elements of 4 halfwords each from a
document and makes them available as a zone record.
C_a_l_l_: inrec (z, length)
inrec (return value, integer). The number of
elements each of 4 halfwords in the
present block for further calls of
inrec.
z (call and return value, zone). The name
of the record. Determines further the
document, the buffering, and the
position of the document.
length (call value, integer, long, or real).
The number of elements of 4 halfwords
each in the new record. Length must be
'= 0.
For further description see inrec6.
Inrec may be used with advantage, if the do-
cument is considered to contain reals.
E_x_a_m_p_l_e_ _1_: Records of variable length may be handled in
the Algol 5-way by means of inrec and outrec,
but you should be careful: For magnetic tapes
the record length should be checked in the
block procedure to make sure that they match
the block length. For backing storage areas
the unused elements at the block end must be
skipped (outrec clears them).
Suppose the record length is stored as the
first element of the record. The record may
then be fetched in this way for all devices:
\f
for remaining:= inrec(z,1) while z(1)<= 0 do inrec
inrec(z,remaining);
comment unused elements are skipped;
inrec(z, z(1) - 1);
Another solution is to call the block procedure
after all normal answers and let it adjust or
check the z(1). N_o_t_e_ that the relation z(1) = 0
instead of z(1) <= 0 would not work because a
backing storage area is filled up with binary
zeroes.
\f
F_ 2_._6_9_ _ _ _ _ _ _i_n_r_e_c_6_ 2.69 inrec6
This integer standard procedure gets a sequence of halfwords
from a document and makes them available as a zone record.
The document may be scanned sequentially by means of inrec6,
because the next call of inrec6 gets the elements just after
those got now.
C_a_l_l_: inrec6 (z, length)
inrec6 (return value, integer). The number of
halfwords left in the present block for
further calls of inrec6.
z (call and return value, zone). The name
of the record. Determines further the
document, the buffering, and the position
of the document (see ref. 15).
length (call value, integer, long, or real).
The number of halfwords in the new
record. Length must be '= 0. If length
is odd, 1 is added to the call value.
Z_o_n_e_ _s_t_a_t_e_: The zone z must be open and ready for record input
(state 0 or 5, i.e. the zone must only have been
used by inrec6, invar or the like since the latest
call of open or setposition). To make sense, the
document should be an internal process, a backing
storage area, a typewriter, a paper tape reader, a
card reader, or a magnetic tape. In the latter case
setposition(z,...) must have been called after the
call of open(z,...).
B_l_o_c_k_i_n_g_: Inrec6 must be thought of as transferring the half-
words just after the current logical position of
the document and changing the logical position to
after the last halfword of the record. \f
However, all halfwords of the record are taken inrec6
from the same block, so if the record cannot be
taken from the current block, the block is changed
as described in ref. 15. Then the record becomes
the first halfwords of that block, but if it still
cannot hold the record the run is terminated
(empty blocks are completely disregarded).
Records of length 0 need a special explanation: if
not even a single word is left in the block, the
block is changed and the logical position points
to just before the first word of the new block.
At end of document the standard error action will
simulate an "end block" containing one word of
three end medium characters. So the call b:=
inrec6(z,0) will in this case give the result b=2,
and the "end block" may be read by inrec6(z,2).
(This is not valid for inrec, as inrec cannot read
less than 4 halfwords).
Note that inrec6 changes the blocks in such a way
that a portion at the end of a block may be skip-
ped. So be careful to read a backing storage area
with the same share length as that with which is
was written, otherwise, wrong portions might be
skipped at reading.
E_x_a_m_p_l_e_ _1_: A simple scan of a file on a magnetic tape in dou-
ble buffer mode may be programmed in this way (all
records are assumed to be of 20 halfwords):
\f
begin inrec6
zone file(2*128,2,endfile);
boolean in _file;
integer i;
procedure endfile(z,s,b); zone z; integer s,b;
if s extract 1 = 1 then stderror(z,s,b) else
if b ' 0 or s shift (-18) extract 1 = 1
then in _file:= false;
open(file,18,<:mt600304:',
1 shift 18 + 1 shift 16);
setposition (file,1,0);
comment skip the label in file 0,
in _file:= true;
for i:= inrec6 (file, 20) while in _file do
begin
...
end;
close(file,true);
The scan is terminated by the procedure end-
file which is called at tape mark (1 shift
16), end of tape (1 shift 18), and all hard
errors. After the positioning (but before the
first input operation) endfile may be called
with tape mark indication. In this case howe-
ver, b = 0, while b ' 0 after input of a tape
mark.
The same piece of code would work for an area
on the backing store if the file was genera-
ted with a share length of 128 elements of 4
halfwords and if the second and third parame-
ter to open were changed.
E_x_a_m_p_l_e_ _2_: Two files of 100 halfwords records on magne-
tic tape are arranged in ascending order
(sorted with respect to the key indicated by
the integer field keyf). They may be merged
into one file in this way:
\f
begin zone result(2*256,2,stderror); inrec6
zone array inp(2,2*256,2,endfile);
procedure endfile(z,s,b); zone z; integer s,b;
if s extract 1 ' 0 then stderror(z,s,b) else
begin
b:= 100; z.keyf:= large;
comment the procedure simulates the presence of a
record with a very large key;
end;
open(inp(1),...,1 shift 16); open (inp(2),...
setposition ... setposition ...
large:= (-1) shift (-1);
inrec6(inp(1),100); inrec6(inp(2),100);
for k:= if inp(1).keyf < inp(2).keyf then 1 else 2
while inp(k).keyf < large do
begin
outrec6(result,100);
tofrom(result,inp(k),100);
inrec6(inp(k),100);
end;
close(result, ...);
E_x_a_m_p_l_e_ _3_: You may read a magnetic tape file or backing
storage area block by block in this way:
for b:= inrec6(z,0) while b ' 2 do
begin
comment b is now the block length in halfwords,
the standard actions simulate one word containing
<:<25'<25'<25':' at end of document;
inrec6(z,b);
comment the block is now available as one record;
... ;
end;
comment check that the last record is
the simulated end block;
inrec6(z,2);
if z.firstword <'
long <:<25'<25'<25':' shift (-24) extract 24
then error; \f
F_ 2_._7_0_ _ _ _ _ _ _i_n_t_a_b_l_e_ 2.70 intable
This standard procedure exchanges the current input alphabet used
by all the read procedures on character level.
C_a_l_l_: intable (alpha) or
intable (0)
alpha (call value, integer array of one dimension).
Contains the character class and the value of
each character in the new input alphabet as
described below.
0 (call value, integer). A zero signals that
the standard alphabet is to be used.
i_n_t_a_b_l_e_ _(_a_l_p_h_a_)_:
The actual contents of alpha are used in all calls of read proce-
dures, until another array or the standard alphabet is selected.
This means that any change in the contents of alpha may have ef-
fects on the character reading. If a read procedure is called at
a place where alpha is undeclared, an undefined alphabet is used.
To each character >c> delivered by the peripheral device is
associated a C_l_a_s_s_ and a V_a_l_u_e_, determined by the read procedures
in this way:
alpha(c+tableindex) = Class shift 12 + Value extract 12
Class is an integer 0 <= Class <= 4095. Value is an integer,
-2048 <= Value <= 2047. The character >c> is an integer, 0 <= c <=
255. The ISO characters utilize only half of this interval. The
standard integer >tableindex> is normally 0, but you may use it
to modify the alphabet.
The class determines how the value corresponding to a character
is handled:
\f
Class = 0, blind: The character is skipped by all read proce- intable
dures.
Class = 1, shift character: The value is assigned to tableindex
and the character is looked up again in the alphabet
to determine Class and Value.
Class = 2, digits: The character is a decimal digit the value of
which is Value - 48. To make sense, 48 <= Value <= 57
should be fulfilled.
Class = 3, signs: The character is the sign of a decimal number.
Value = 43 means +, Value = 45 means -.
Class = 4, decimal point: The character may be used as a decimal
point.
Class = 5, exponent mark: The character may be used as the > of
Algol.
Class = 6, letters: The character may be used as part of a text
but not as part of a number.
Class = 7, delimiter: The character cannot be part of a text or
a number.
Class = 8, terminator: The character is a delimiter as class 7,
but it will terminate a call of readall. If value is
25, it will immediately terminate a call of read or
readstring.
Class ' 8, other delimiters: The character is handled as class 7.
The elements 0:127 of alpha may be initialized with the ISO al-
phabet by a call of the standard procedure isotable.
i_n_t_a_b_l_e_ _(_0_)_:
The standard alphabet given in ref. 14 is used until a new
alphabet is selected. The value of tableindex has no influence on
the alphabet. When the run starts, the standard alphabet is
selected automatically.
You should not hesitate to use a special alphabet table: The
character reading will be speeded up compared to what you could
do in algol with the standard alphabet, and the input algorithm
becomes clearer.
The table takes space, but remember that 2*128 integers
correspond to one segment of a program (10 to 20 lines), and that
much is easily saved in the central loop of the input program. \f
E_x_a_m_p_l_e_ _1_: N_u_m_b_e_r_ _v_a_r_i_a_n_t_s_ intable
Assume you want to read numbers coded in ISO but
with space regarded as blind information and
without exponent part. You may then proceed like
this:
isotable(table);
table(32):= 0; table(39):= 7 shift 12 + 39; ...
comment define space, apostrophe, and other
special characters;
intable(table); tableindex:= 0;
read(z,...);
E_x_a_m_p_l_e_ _2_: F_l_e_x_o_w_r_i_t_e_r_ _c_o_n_v_e_r_s_i_o_n_
It is possible to use the read procedure for input
represented in flexowriter code if the underlining may
be disregarded. The shift characters, class 1, may take
care of the case shift characters. An alphabet table of
2*128 elements is required. One way of initialising the
table goes like this:
for i:= 0 step 1 until 255 do table(i):=
(case i+1 of (0,2,2,2,2, 2,2,2,2,2,
0,8,8,6,0, 0,2,7,6,6,
...) shift 12 +
(case i+1 of (32,49,50,51,52, 53,54,55,56,57,
0,12,25,125,0, 0,48,60,115,116,
... ));
Upper case and Lower case require
table(60):= 1 shift 12 + 128;
table(60 + 128):= 0;
table(58 + 128):= 1 shift 12 + 0;
table(58):= 0;
\f
Note, that if the input was flexowriter paper intable
tapes which were read in ISO-mode, the parity hole
would not be the flexowriter parity hole, and as a
consequence a different alphabet table would be
needed.
E_x_a_m_p_l_e_ _3_: begin
....
begin
integer array table (0:127);
<* an alphabet is initialised in table *'
table (32):= ...
intable (table); tableindex:= 0;
....
intable (0);
<* if you forget returning to the standard
alphabet before leaving the block where
table is declared, an undefined alphabet
will be used *'
end block;
...
end program
E_x_a_m_p_l_e_ _4_: See example 3 of readall.
\f
F_ 2_._7_1_ _ _ _ _ _ _i_n_t_e_g_e_r_ 2.71 integer
This delimiter, which is a declarator, is used in declaration and
specifications of variables of type integer.
S_y_n_t_a_x_: integer <namelist'
S_e_m_a_n_t_i_c_: The variables in namelist will all be of type
integer, and occupy 24 bits in the storage
area.
The value of an integer is in the interval:
-8388608 <= value <= 8388607
E_x_a_m_p_l_e_ _1_: integer i1;
integer i2, yes, no, price;
procedure pip (a);
integer a;
\f
F_ 2_._7_2_ _ _ _ _ _ _i_n_t_e_g_e_r_ _d_i_v_i_d_e_ _(_/_/_)_ 2.72 integer divide
This delimiter, which is an arithmetic operator, performs an
integer division.
S_y_n_t_a_x_: <operand1' // <operand2'
P_r_i_o_r_i_t_y_: 3
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer or long
R_e_s_u_l_t_ _t_y_p_e_: When both operands are of type integer the
result is of type integer, otherwise the
result is of type long.
S_e_m_a_n_t_i_c_: The result of the operator is defined as
follows:
a//b = sign (a/b)* entier(abs (a/b))
E_x_a_m_p_l_e_ _1_: a:= 35//12; <* a has the value 2 *'
b:= -13//3; <* b has the value -4 *'
\f
F_2_._7_3_ _ _ _ _ _ _i_n_v_a_r_ 2.73 invar
This standard integer procedure together with outvar, changevar,
and checkvar are intended for easy handling of records of vari-
able length. Every record must contain its own length in half-
words in its first word, the l_e_n_g_t_h_ _w_o_r_d_. Invar makes the next
record written by means of outvar available as a zone record. A
record checksum in the second word may be checked, and the number
of records are counted in the so called free parameter in the
zone descriptor (see getzone6). This procedure may call the block
procedure with the status 1 shift 11, checksum error, if the
record length wanted is < 4 or ' remaining halfwords in the block
or odd or if the checksum is calculated and not equal to the
value of the second word in the record.
C_a_l_l_: invar (z)
invar (return value, integer). The number of
halfwords left in the present block.
z (call and return value, zone). The name
of the record. Determines the document,
the buffering, and the position of the
document.
Z_o_n_e_ _s_t_a_t_e_: The zone z must be open and ready for record
input (state 0 or 5), i.e. the zone must only
have been used by invar or the like since the
latest call of open or setposition.
F_r_e_e_ _p_a_r_a_m_e_t_e_r_:The free parameter in the zone descriptor is used
to count the number of records accepted by invar.
The value of this parameter is interpreted as
check _wanted shift 23 + record _count where
check _wanted = 1 means that a checksum is calcula-
ted by invar and checked against the second word
in the record. The free parameter could be set in
the program by:
getzone6(z,ia); ia(11):= 1 shift 23;
setzone6(z,ia);
See below for further details.
\f
B_l_o_c_k_i_n_g_: You may think of invar in the way that the procedure invar
tests the value of the first word just after the cur-
rent logical position of the document. Now invar ex-
poses as many halfwords as the length word indicates,
including the two halfwords of this word.
However all halfwords must be taken from the same
block. If this is not possible, the block procedure
of the zone is called. See further on length errors
below.
If the length word is null, it is skipped and the
next word from the document is tried as length word.
When there are no more in a block, the block is
changed. This covers skipping of blank block tails
that may be generated by outvar when the kind of the
document is backing storage (see outvar).
L_e_n_g_t_h_ _e_r_r_o_r_s_._ _C_h_e_c_k_s_u_m_:
If the length word is <' 0, it is expected to be
even, '= 4 and <= the number of halfwords remaining
in the present block. If not all three conditions are
fulfilled, invar will give up and call the block pro-
cedure (see below).
When the length word has passed the tests above, the
contents of the second word may be tested as a check
sum of the record (see example 2 below). If check is
wanted (see free parameter above), invar tests if the
sum of all words in the record taken modulo 2**24 is
equal to -3. If not, invar calls the block procedure.
B_l_o_c_k_ _p_r_o_c_e_d_u_r_e_,_ _c_a_l_l_ _c_o_n_d_i_t_i_o_n_s_:
Invar may call the block procedure in two diffe-
rent situations:
\f
a) The length word is not sensible (see above). invar
b) Record sumcheck is wanted, and the sum is not
ok (see above).
The call conditions for the parameters to the
block procedure are:
z: The zone state is after record input. The defect
record is not counted in the free parameter. The
record starts just before the length word and
depends on the length word like this:
record _length:=
if length _word < 4 or length _word ' remaining
then remaining else
if record _length is odd then length _word + 1
else length _word.
Remaining means the number of halfwords remaining
in the present block including the length word.
The terms zonestate, free parameter, and record
length are explained in getzone6.
s: The status word parameter has the value 1 shift 11.
b: The halfwords transferred parameter is equal to the
record length, described above.
After return from the block procedure, invar re-
starts its algorithm by fetching the next logical
record. A defect record will thus be skipped if
the block procedure simply ignores the call, (see
example 2).
\f
E_x_a_m_p_l_e_ _1_: Your block procedure may test whether situation invar
a) or situation b) above has caused the block
procedure to be called. This may be done as follows:
procedure blpr(z,s,b); zone z; integer s,b;
begin
.....
if s = 1 shift 11 then
begin integer field lengthword; lengthword:= 2;
if b < 4 then
begin comment end of documment; ...
end
else
if b <' z.lengthword then
begin comment length error; ...
end
else
begin comment checksum error; ...
end;
end
.....
end;
E_x_a_m_p_l_e_ _2_: A_t_t_e_m_p_t_ _t_o_ _r_e_p_a_i_r_ _a_ _d_e_f_e_c_t_ _r_e_c_o_r_d_.
When you read a file from magnetic tape written
by means of outvar, you may try to make sense of
blocks with parity error and where the standard
actions have given up.
This will only be waste of machine power if all
records are needed in a run. In such case it is
better to give up once status errors occur. It
must be recognized, however, that problems exist
where it is essential to make as much sense out
of a file as possible in one run and then try to
pick up the defect records in a later run.
\f
A block procedure which counts the number of wrong invar
>records> and only gives up when this number is too
large may look something like this:
procedure after _parity (z,s,b);
zone z; integer s, b;
begin
own integer faults; integer field length;
integer array ia (1:20);
procedure drop;
write (out, <:record dropped, expected::', z.length,
<: dropped::', b, <: halfwords<10':');
length:= 2;
if s shift (-18) extract 1 = 1 or
s shift (-16) extract 1 = 1 then
begin comment end of document or tapemark, simulate
a dummy record and switch off the sum check,
in order to prevent invar from calling the
block procedure again;
z.length:= b:= min _length;
end _medium:= true;
getzone6(z, ia); ia(11):= ia(11) extract 23;
setzone6(z, ia);
end
else
if s = 1 shift 11 then
begin
faults:= faults + 1;
if faults ' max then stderror (z,s,b);
if b <' z.length then drop
else
begin comment maybe only checksum error;
if b<min _length or b'max _length then drop
else
\f
begin invar
comment now check the contents of the possible
record. If it does not seem sensible then drop
it, else set a mark that it may be erroneous;
....
checkvar (z);
changerec6 (z,0);
comment force a new checksum into the record and
regret the record so that invar may take it
once more;
end;
end;
end s = 1 shift 11
else
if logand (s, -1 - (1 shift 22 <*parity error*' +
1 shift 15 <*writing enabled*' +
1 shift 1 <*normal answer*' +
1 shift 0 <*hard error*' ))
<' 0 then stderror (z,s,b);
comment give up if hard error, except in connection
with parity error, ring indication, and/or normal
answer;
end after _parity;
When the zone with this block procedure is opened,
the give up mask should contain the tapemark bit (or
end document bit if reading from backing storage), as
standard action would simulate a dummy block of 2
halfwords, which invar would consider a length error.
On the other hand the give up mask should not contain
the parity error bit, as the standard action, 5
readings, is wanted for parity error. The bit for
checksum wanted should be set in the free zone
parameter (see getzone6):
\f
open(z,18,<:...:', 1 shift 18 + 1 shift 16); invar
setposition(z,1,0);
getzone6(z,ia); ia(11):= 1 shift 23;
setzone6(z,ia);
repeat
invar(z);
..... handle the record, note the error-mark;
until end _medium;
E_x_a_m_p_l_e_ _3_: See example of changevar.
\f
F_ 2_._7_4_ _ _ _ _ _ _i_s_o_t_a_b_l_e_ 2.74 isotable
This standard procedure initializes an array with the ISO
character table for use in intable or outtable.
C_a_l_l_: isotable (alpha)
alpha (return value, integer array of one
dimension). The elements alpha (0:127)
of the array are initialized with
class shift 12 + value
of the ISO characters, as
defined in ref. 14.
E_x_a_m_p_l_e_ _1_: See example 1 of intable.
\f
F_2_._7_5_ _ _ _ _ _ _l_e_s_s_ _t_h_a_n_ _(_<_)_ 2.75 less than
This delimiter, which is a relational operator, yields the value
true or false.
S_y_n_t_a_x_: <operand1' < <operand2'
P_r_i_o_r_i_t_y_: 5
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real.
R_e_s_u_l_t_ _t_y_p_e_: always boolean
S_e_m_a_n_t_i_c_: The relation takes on the value true whenever the
corresponding relation is satisfied for the ex-
pressions involved, otherwise false.
In case one of the operands is different from type
integer the relation is executed as a subtraction.
Thus, you may be prepared for overflow, underflow,
or spill.
E_x_a_m_p_l_e_ _1_: a:= b < c;
if d < q then .... else ...;
while k < l do ...;
\f
F_ 2_._7_6_ _ _ _ _ _ _l_e_s_s_ _t_h_a_n_ _o_r_ _e_q_u_a_l_ _(_<_=_)_ 2.76 less than
or equal
This delimiter, which is a relational operator, yields the value
true or false.
S_y_n_t_a_x_: <operand1' <= <operand2'
P_r_i_o_r_i_t_y_: 5
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real.
R_e_s_u_l_t_ _t_y_p_e_: always boolean.
S_e_m_a_n_t_i_c_: The relation takes on the value true whenever the
corresponding relation is satisfied for the
expressions involved, otherwise false.
The relation is always executed as a subtraction.
Thus, you may be prepared for overflow, underflow,
or spill (see example 3 of monitor).
E_x_a_m_p_l_e_ _1_: q:= a <= c;
if d <= k then ... else ...;
while x <= y do ...;
\f
F_ 2_._7_7_ _ _ _ _ _ _l_i_f_e_s_o_r_t_ 2.77 lifesort
This standard procedure makes available that zone record which is
to be the next record in a sorted string of records from a zone.
The winning record is selected among the active and inactive
records in the zone, and at the same time all inactive records
are activated.
The user is supposed to move the record away from the zone before
next call of any sorting procedure.
C_a_l_l_: lifesort (z, key) or liftsort (z)
z (call and return value, zone). The name
of the selected record.
key (call value, integer procedure or
empty). The name of a procedure for
comparison of two records (see procedure
newsort).
The key parameter is omitted if standard
sequencing is used (see procedure startsort6).
Z_o_n_e_ _s_t_a_t_e_: The zone state must be 9, in sort, i.e. startsort6
(or initsort) must have been called. The state is
not changed by the procedure.
E_x_a_m_p_l_e_ _1_: See example 1 of newsort for a user specified key
procedure.
E_x_a_m_p_l_e_ _2_: See example 2 of deadsort.
\f
F_2_._7_8_ _ _ _ _ _ _l_n_ 2.78 ln
This real standard procedure performs the mathematical function
ln.
C_a_l_l_: ln (r)
ln (return value, real). The Napierian
logarithm of r. r ' 0.
r (call value, real, long, or integer).
A_c_c_u_r_a_c_y_: r = 1 gives ln = 0
0.5 <= r < 2 gives absolute error below 2.2>-10
0.25 <= r < 0.5 or
2 <= r < 4 gives relative error below 1.8>-10
r < 0.25 or 4 <= r gives relative error below 1.2>-10
A_l_a_r_m_: The run is terminated if r <= 0.
E_x_a_m_p_l_e_ _1_: A procedure which gives the decimal logarithm
may look like this:
real procedure log(x);
value x; real x;
log:= ln(x) / ln(10);
\f
F_2_._7_9_ _ _ _ _ _ _l_o_c_k_ 2.79 lock
This standard procedure transfers immediately a number of program
segments to core and locks them: i.e. they are not released later
on caused by some request for space for other segments.
M_ *
C_a_l_l_: lock ( <pair of parameters' )
P_ 1
<pair of <label expression',<label expression'
parameters' ::= <integer expression',<integer expression'
<procedure identifier',<integer expression'
Each pair of parameters is evaluated, and a locking
process is performed depending on the parameter
pair:
<_l_a_b_e_l_ _e_x_p_r_e_s_s_i_o_n_'_,_<_l_a_b_e_l_ _e_x_p_r_e_s_s_i_o_n_'_
The values of the two label expressions define two points in
the program. All program segments between (and inclusive)
the two points are locked.
<_i_n_t_e_g_e_r_ _e_x_p_r_e_s_s_i_o_n_'_,_<_i_n_t_e_g_e_r_ _e_x_p_r_e_s_s_i_o_n_'_
The values of the two integer expressions define two segment
numbers in the program. All segments in the program between
(and inclusive) those segments are locked.
Segment numbers of first segment of the main program and all
external procedures included in the program may be obtained from
a compilation with survey.yes specified (see ref. 15 and ref.
10). This parameter pair is intended for locking segments of the
run time system. The run time system consists of 11 segments:
\f
segment 0 : alarm segment 0, c_a_n_n_o_t_ be locked lock
segment 1-5 : resident part of RS, c_a_n_n_o_t_ be locked
segment 6 : long division and multiplication, stderror
segment 7 : alarm segment 1, used by run time alarms
segment 8 : declaration of zones, exponentiation: **
segment 9 : RS block segment (i.e. inblock, outblock etc.)
segment 10 : RS error segment (i.e. special handl. of status)
<_p_r_o_c_e_d_u_r_e_ _i_d_e_n_t_i_f_i_e_r_'_,_<_i_n_t_e_g_e_r_ _e_x_p_r_e_s_s_i_o_n_'_
The value of integer expression defines a number of consecutive
segments - starting with the entry segment of the procedure - to be
locked.
E_x_a_m_p_l_e_ _1_: If we want to lock in primary store segment 6 (long
division and multiplication), two segments containing
procedure readin, and one or more segments surround-
ing label seglock1 to label seglock2, this could be
done by the call:
lock(6,6, readin, 2, seglock1, seglock2);
\f
F_2_._8_0_ _ _ _ _ _ _l_o_c_k_e_d_ 2.80 locked
This integer standard procedure transfers the segment numbers
(0,1,...) of the segments, which are locked for the moment, to an
integer array parameter.
C_a_l_l_: locked (ia)
locked (return value, integer). Number of segments
locked at the moment.
ia (return value, integer array). ia(1), ia(2),...
ia(locked) is the list of segment numbers
for the segments locked at the moment.
E_x_a_m_p_l_e_ _1_: If the call
locked (ia);
is used after the call shown in example 1 under
lock, the results could be:
ia(1) = 6
ia(2) = 24
ia(3) = 25
ia(4) = 32
ia(5) = 33
ia(6) = 34
\f
F_2_._8_1_ _ _ _ _ _ _l_o_g_a_n_d_ 2.81 logand
This long standard procedure performs the function logical and
(logical multiplication) on two 48 bit entities a and b. If the
type length of a and/or b is smaller than 48 bits, they are ex-
tended by repetition of the sign bit.
C_a_l_l_: logand (a, b)
logand (return value, long). Bitpattern equal
to (a and b) performed bit by bit after
a possible extension of the parameters a
and b.
a,b (call values, short string (text portion),
real, long, integer, or boolean). The two
parameters do not have to be of the same
kind. They are - if necessary - extended
and they are handled as described below.
H_a_n_d_l_i_n_g_ _o_f_ _a_ _a_n_d_ _b_ _a_c_c_o_r_d_i_n_g_ _t_o_ _k_i_n_d_:
String: It is tested that a string parameter describes a
text portion or a short string (see ref. 15).
This is a 48 bit entity.
Real: A real is represented by 48 bits. No conversion.
Long: A long is represented by 48 bits. No conversion.
Integer: An integer is extended to a long as if the
operator extend had been applied.
Boolean: A boolean is considered as a short integer. The
12 bit boolean is extended to a 48 bit long
according to the algorithm:
int:= boo extract 12;
if int ' 2047 then int:= int - 4096;
param:= extend int;
\f
The rules for extension imply that actual parameters with the logand
values true, -1, and extend (-1) are equivalent. Note that the
rules also imply that the effect of an integer with the value
2048 differs from the effect of a boolean with the value false
add 2048.
E_x_a_m_p_l_e_ _1_: See example 2 of invar.
E_x_a_m_p_l_e_ _2_: I_n_f_o_r_m_a_t_i_o_n_ _r_e_t_r_i_e_v_a_l_
Each record is a certain file has an element inf
that contains binary information in each binary
position (sex, salary on hour basis or not, ...).
A statement that writes out the identification for
each record that fulfil all the criteria in a
read search element, could look like this:
for i:= inrec6 (z, length) while z.ident <' endident
do
if logand (searchcrit, z.inf) = searchcrit then
write (out, "nl", 1, z.ident); \f
2_._8_2_ _ _ _ _ _ _l_o_g_o_r_ 2.82 logor
This long standard procedure performs logical or (logical addi-
tion) on two 48 bit entities a and b. If the type length of a
and/or b is smaller than 48 bits, they are extended by repetition
of the sign bit.
C_a_l_l_: logor (a, b)
logor (return value, long). Bit pattern equal
to (a or b) performed bit by bit after a
possible extension of the parameters.
a,b (call values, short string (text
position), real, long, integer, or
boolean). The two parameters do not have
to be of the same kind. They are - if
necessary - extended and they are
handled as described for logand.
E_x_a_m_p_l_e_ _1_: About the same as example 2 for logand, but you
are now searching for records that are not in con-
flict with the search criteria i.e. each found
record should only contain all, some or none of
the information found in the search criteria.
This could be done by replacing logand (searchrit,
z.inf) = searchrit by:
logor (searchrit, z.inf) = z.inf
\f
F_ 2_._8_3_ _ _ _ _ _ _l_o_n_g_ 2.83 long
This delimiter, which is a declarator, is used in declarations
and specifications of variables of type long.
S_y_n_t_a_x_: long <namelist'
S_e_m_a_n_t_i_c_: The variables in namelist will all be of type
long, and occupy 48 bits in the storage area.
The value of a long is in the interval:
-140 737 488 355 328 <= value <= 140 737 488 355 327.
All values can be assigned to the variable by use of
shift and the like, but if you assign by constants
or character reading procedures you are confined to
th range:
-140 737 488 355 327 <= value <= 140 737 488 355 327
E_x_a_m_p_l_e_ _1_: long l1;
long l2, yes, no, price;
procedure pip(a);
long a;
E_x_a_m_p_l_e_ _2_: The greatest possible positive and negative long
values can be assigned by the statements:
max _pos:= extend (-1) shift (-1);
max _neg:= extend 1 shift 47;
\f
2_._8_4_ _ _ _ _ _ _l_o_n_g_ 2.84 long
This delimiter, which is a transfer operator, changes the type
string and real to type long.
S_y_n_t_a_x_: long <operand'
P_r_i_o_r_i_t_y_: 1
O_p_e_r_a_n_d_ _t_y_p_e_: real or string.
R_e_s_u_l_t_ _t_y_p_e_: long.
S_e_m_a_t_i_c_: Changes the type of a string or a real to type
long. The binary pattern of the operand is
unchanged. The binary pattern of a string and a
real is described in ref. 14.
N_o_t_e_: This use of the delimiter long is totally
different from its use in a declaration or
specification.
E_x_a_m_p_l_e_ _1_: l:= long <:abcde:' add >f>;
E_x_a_m_p_l_e_ _2_: See the examples in real and replace real with
long where real is used as a transfer operator.
E_x_a_m_p_l_e_ _3_: See example 1 of swoprec6.
\f
F_ 2_._8_5_ _ _ _ _ _ _m_e_s_s_a_g_e_ 2.85 message
This delimiter, which is a compiler directive, may print a mes-
sage during the translation of a program. Messages follow the
same rules as comment.
S_y_n_s_t_a_x_: ; message <text no containing ";"' ;
may replace any ; (semicolon)
begin message <text not containing ";"' ;
may replace any begin
S_e_m_a_n_t_i_c_: The text between message and semicolon is printed on
current output if the program is translated with the
parameter message.yes.
E_x_a_m_p_l_e_ _1_: You can spare the listing of a long algol program and
still keep track of the line numbers. Put 1 or 2
messages on each page of the program (for instance as
page head) and translate it with: algol message.yes
(the default value). The messages are then printed
with their line numbers attached and you can easily
find any other line given its line number.
\f
F_ 2_._8_6_ _ _ _ _ _ _m_i_n_u_s_ _(_-_)_ 2.86 minus
This delimiter, which is an arithmetic operator, can be used both
as a dyadic and as a monadic operator.
1_._ _D_y_a_d_i_c_:
S_y_n_t_a_x_: <operand1' - <operand2'
P_r_i_o_r_i_t_y_: 4
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long or real.
R_e_s_u_l_t_ _t_y_p_e_: <integer' - <integer' is of type integer
<integer' - <long' - - - long
<integer' - <real' - - - real
<long' - <integer' - - - long
<long' - <long' - - - long
<long' - <real' - - - real
<real' - <integer' - - - real
<real' - <long' - - - real
<real' - <real' - - - real
S_e_m_a_n_t_i_c_: This operator yields the normal arithmetic
difference of the expressions involved.
2_._ _M_o_n_a_d_i_c_:
S_y_n_t_a_x_: - <operand'
P_r_i_o_r_i_t_y_: 4
O_p_e_r_a_n_d_ _t_y_p_e_: integer, long, or real.
R_e_s_u_l_t_ _t_y_p_e_: - <integer' is of type integer
- <long' - - - long
- <real' - - - real
\f
S_e_m_a_n_t_i_c_: This monadic operator yields the "opposite" minus
value of the operand.
E_x_a_m_p_l_e_ _1_: 5-7
a-q
-5-a
s shift (-11)
(-1) shift (-1)
\f
F_ 2_._8_7_ _ _ _ _ _ _m_o_d_ 2.87 mod
This delimiter, which is an arithmetic operator, yields the
remainder corresponding to an integer division.
S_y_n_t_a_x_: <operand1' mod <operand2'
P_r_i_o_r_i_t_y_: 3
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer or long.
R_e_s_u_l_t_ _t_y_p_e_: When both operands are of type integer, the result
is of type integer, otherwise the result is of
type long.
S_e_m_a_n_t_i_c_: The value of i mod j is defined as
i - i//j*j
The sign of i mod j is the same as the sign
of i.
E_x_a_m_p_l_e_ _1_: C_y_c_l_i_c_a_l_ _c_o_u_n_t_i_n_g_
Counting i = 1,2,3,1,2,3,1,... may be done in this way:
i:= i mod 3 + 1;
A longer but slightly faster version is:
i:= if i = 3 then 1 else i + 1;
\f
F_2_._8_8_ _ _ _ _ _ _m_o_n_i_t_o_r_ 2.88 monitor
This integer standard procedure is the algol equivalent of the
monitor procedures. You may use it to handle peripheral devices
in a non-standard way and to program operating systems and exe-
cutive functions in algol.
In most cases the algol procedure will only transform the para-
meters to the form required by the monitor, and the description
below describes mainly this transformation. You will have to
consult the Monitor manuals (ref. 1 and 2) for the details and
the ideas behind each entry.
Be aware that the monitor tables have halfword addresses.
C_a_l_l_: monitor (fnc, z, i, ia)
monitor (return value, integer). In most cases the
result of the corresponding call of a monitor
procedure, the meaning of which is found in
the Monitor manual, part 2 (ref. 2).
fnc (call value, integer). A function code speci-
fying the monitor procedure to be called.
z (call and return value, zone). The zone des-
criptor contains in most cases the name of
the process or catalog entry concerned.
i (call and return value, integer). Used for
various purposes, e.g. device number, message
buffer address.
ia (call and return value, integer array). Used
for various purposes, e.g. tail of catalog
entry, contents of answer. Various lengths of
ia are required in the various cases.
N_o_t_e_: Fielding has no influence on the addressing of ia as
the procedure always uses the array from the first
element and on.
In most cases only some of the last 3 parameters are actually
used by the procedure. The value of fnc determines the function\f
as follows: monitor
f_n_c_ _=_ _4_,_ _p_r_o_c_e_s_s_ _d_e_s_c_r_i_p_t_i_o_n_:
monitor result, i.e. process description address, 0 if the
process does not exist.
z (call value). Contains the process name.
i dummy
ia dummy
f_n_c_ _=_ _6_,_ _i_n_i_t_i_a_l_i_s_e_ _p_r_o_c_e_s_s_:
monitor result, i.e. 0 means process initialised, 1,2,3
means not initialised.
z (call value). Contains the process name.
i dummy
ia dummy
f_n_c_ _=_ _8_,_ _r_e_s_e_r_v_e_ _p_r_o_c_e_s_s_:
monitor result, i.e. 0 means process reserved, 1,2,3
means not reserved.
z (call value). Contains the process name.
i dummy
ia dummy
f_n_c_ _=_ _1_0_,_ _r_e_l_e_a_s_e_ _p_r_o_c_e_s_s_:
monitor result dummy
z (call value). Contains the process name.
i dummy
ia dummy
f_n_c_ _=_ _1_2_,_ _i_n_c_l_u_d_e_ _u_s_e_r_:
monitor result, i.e. 0 means included, 2,3,4 means not
included.
z (call value). Contains the process name.
i (call value). Device number.
ia dummy
\f
f_n_c_ _=_ _1_4_,_ _e_x_c_l_u_d_e_ _u_s_e_r_: monitor
monitor result, i.e. 0 means excluded, 2,3,4 means not
excluded.
z (call value). Contains the process name.
i (call value). Device number.
ia dummy
The format of messages and answers used in the following 5
functions can be found in the Monitor manual, part 2 and 3, (ref.
2-3) and in the description of getshare6.
f_n_c_ _=_ _1_6_,_ _s_e_n_d_ _m_e_s_s_a_g_e_:
monitor buffer address, 0 if the buffer claim is
exceeded.
z (call value). Contains the process name of the
receiving process.
i (call value). The number of a share within z. The
share state must at call time be 0 or 1, at return
time it is the buffer address. The message sent is
given in the share descriptor. (See getshare6).
Note that you may change the message in the share
by means of the procedure setshare6.
ia dummy.
The value of "current activity no" is used as mes-
sage identification. This is stored in the message
buffer (buffer address - 2), which later (f.ex. in
wait event) may supply the number of the sending
activity (see ref. 19, concurrent i/o transfers).
\f
f_n_c_ _=_ _1_8_,_ _w_a_i_t_ _a_n_s_w_e_r_:monitor
monitor result, i.e. 1 means a normal answer, 2,3,4,5
means dummy answers.
z (call value). Determines together with >i> the
buffer address.
i (call value). The number of a share within z. The
share state must be the buffer address at call
time, at return time it is 0.
ia (return value, length '= 8). The answer is stored
here.
If the program is in activity mode, and the give
up mask in the zone includes 1 shift 9, this
function will execute an implicit passivate
statement just before call of the monitor
procedure.
f_n_c_ _=_ _2_0_,_ _w_a_i_t_ _m_e_s_s_a_g_e_:
monitor result, i.e. process description address of the
sender, positive for a normal message, negative
for a message from a removed process, or 0 if the
buffer claim is exceeded.
z (return value). The process name is stored here.
i (return value). Buffer address.
ia (return value, length '= 8). The message is stored
here.
f_n_c_ _=_ _2_2_,_ _s_e_n_d_ _a_n_s_w_e_r_:
monitor result dummy
z dummy
i (call value). Buffer address.
ia (call value, length '= 9). The first 8 elements
contain the answer, the 9th element contains the
result, which is 1 for a normal answer, 2,3,4,5,
for a dummy answer.
\f
f_n_c_ _=_ _2_4_,_ _w_a_i_t_ _e_v_e_n_t_: monitor
monitor result, i.e. 0 for a message, 1 for an answer.
z (return value). The name of the sending process is
stored here if a message was received.
i (call and return value). Last and next buffer
address.
ia (return value, length '= 8). If a message is
received, it is stored here. The value of ia(1)
which is loaded from the message buffer (buffer
address - 2), indicates:
ia(1)'0: the activity number of the activity,
which sent the message
ia(1)=0: the message was sent in monitor or
neutral mode
ia(1)<0: the message was sent in disable mode.
If an answer is received, ia is dummy. In this
case the buffer address returned in i corresponds
to a message buffer address in the share state of
some zone (see getshare6).
f_n_c_ _=_ _2_6_,_ _g_e_t_ _e_v_e_n_t_:
monitor result dummy
z dummy
i (call value). Buffer address pointing to a
message. An answer must not be released in this
way - use wait answer (or procedure check) instead.
ia dummy
The format of the catalog entry tails used in the following 3
functions is described in the File Processor manual, part 1 (ref.
6).
\f
f_n_c_ _=_ _4_0_,_ _c_r_e_a_t_e_ _e_n_t_r_y_: monitor
monitor result, i.e. 0 means entry created, 2,3,4,5,6,7
means entry not created.
z (call value). Contains the entry name.
i dummy
ia (call value, length '= 10). Contains the tail of
the entry.
f_n_c_ _=_ _4_2_,_ _l_o_o_k_u_p_ _e_n_t_r_y_:
monitor result, i.e. 0 means entry looked up, 2,3,6,7
means not looked up.
z (call value). Contains the entry name.
i dummy
ia (return value, length '= 10). The tail of the
entry is stored here.
f_n_c_ _=_ _4_4_,_ _c_h_a_n_g_e_ _e_n_t_r_y_:
monitor result, i.e. 0 means changed, 2,3,4,5,6,7 means
entry not changed.
z (call value). Contains the entry name.
i dummy
ia (call value, length '= 10). Contains the new tail
of the entry.
f_n_c_ _=_ _4_6_,_ _r_e_n_a_m_e_ _e_n_t_r_y_:
monitor result, i.e. 0 means entry renamed, 2,3,4,5,6,7
means entry not renamed.
z (call value). Contains the present entry name.
i dummy
ia (call value, length '= 4). Contains the new entry
name.
\f
f_n_c_ _=_ _4_8_,_ _r_e_m_o_v_e_ _e_n_t_r_y_: monitor
monitor result, i.e. 0 means entry removed, 2,3,4,5,6,7
means entry did not exist or entry is not
removed.
z (call value). Contains the entry name.
i dummy
ia dummy
f_n_c_ _=_ _5_0_,_ _p_e_r_m_a_n_e_n_t_ _e_n_t_r_y_:
monitor result, i.e. 0 means entry made permanent, 2,3,4,
5,6,7 means entry not permanent.
z (call value). Contains the entry name.
i (call value). Catalog key.
ia dummy
f_n_c_ _=_ _5_2_,_ _c_r_e_a_t_e_ _a_r_e_a_ _p_r_o_c_e_s_s_:
monitor result, i.e. 0 means area process created,
1,2,3,4,5,6 means process not created.
z (call value). Contains the process name.
i dummy
ia dummy
f_n_c_ _=_ _5_4_,_ _c_r_e_a_t_e_ _p_e_r_i_p_h_e_r_a_l_ _p_r_o_c_e_s_s_:
monitor result, i.e. 0 means process created, 1,2,3,4,5,6
means process not created.
z (call value). Contains the process name.
i (call value). Device number.
ia dummy
\f
f_n_c_ _=_ _5_6_,_ _c_r_e_a_t_e_ _i_n_t_e_r_n_a_l_ _p_r_o_c_e_s_s_: monitor
monitor result, i.e. 0 means process created, 1,2,3,6
means process not created.
z (call value). Contains the process name. The
process will be created in the buffer area of z.
i dummy
ia (call value, length '= 9). Contains the parameters
in this way:
ia(1) buffer index for start of process
ia(2) buffer index for last of process
ia(3) buffer claim shift 12 + area claim
ia(4) internal claim shift 12 + function mask
ia(5) priority of the process
ia(6) lower limit of max base
ia(7) upper limit of max base
ia(8) lower limit of std base
ia(9) upper limit of std base
f_n_c_ _=_ _5_8_,_ _s_t_a_r_t_ _i_n_t_e_r_n_a_l_ _p_r_o_c_e_s_s_:
monitor result, i.e. 0 means process started, 2,3,6 means
process not started.
z (call value). Contains the process name. The
process must have been created inside the zone
buffer.
i (call value). The number of a share within z. The
share state must at call time be 0 or 1, at return
time it is - process description address.
ia dummy
\f
f_n_c_ _=_ _6_0_,_ _s_t_o_p_ _i_n_t_e_r_n_a_l_ _p_r_o_c_e_s_s_: monitor
monitor result, i.e. 0 means stop initiated, 3,6 means
stop not allowed.
z (call value). Determines together with i the
process.
i (call value). The number of a share within z. The
share state must at call time be - process des-
cription address. At return time it is the buffer
address. Notice that the process name in z is ir-
relevant.
ia dummy
f_n_c_ _=_ _6_2_,_ _m_o_d_i_f_y_ _i_n_t_e_r_n_a_l_ _p_r_o_c_e_s_s_:
monitor result, i.e. 0 means process modified, 2,3,6 means
modification not allowed.
z (call value). Contains the process name.
i dummy
ia (call value, length '= 6). Contains the modified
registers.
f_n_c_ _=_ _6_4_,_ _r_e_m_o_v_e_ _p_r_o_c_e_s_s_:
monitor result, i.e. 0 means process removed, 1,2,3,5,6
means removal not allowed.
z (call value). Contains the process name.
i dummy
ia dummy
f_n_c_ _=_ _6_6_,_ _t_e_s_t_ _e_v_e_n_t_:
monitor result, i.e. 0 when the first event is a message,
1 when the first event is an answer, and -1 when
the event queue in the call moment is empty.
z as for fnc= 24, wait event
i - - - - -
ia - - - - -
\f
Works as monitor (24, ...), wait event, except monitor
that no waiting takes place.
f_n_c_ _=_ _6_8_,_ _g_e_n_e_r_a_t_e_ _n_a_m_e_:
monitor result, i.e. 0 means name generated, 2 means name
not generated.
z (return value). The generated name is stored
here.
i dummy
ia dummy
f_n_c_ _=_ _7_0_,_ _c_o_p_y_ _c_o_r_e_ _a_r_e_a_:
monitor result of the copying, 0 meaning area copied, 2 or
3 area not copied.
z (call value). Contains the area to or from which
the copying will take place. The limits of the
copying are given by the zone parameters record
base and last halfword.
i (call value). The buffer address of the input or
output message defining sender>s copy area.
ia (return value, length '= 9). Contains information
about the copying almost ready to be used by send
answer (see ref. 3):
ia(1) should then be set by the user
ia(2) if result <' 0 then 0 else halfwords copied
ia(3) if result <' 0 then 0 else chars copied
ia(9) if result = 3 then 3 else 1.
\f
f_n_c_ _=_ _7_2_,_ _s_e_t_ _c_a_t_a_l_o_g_ _b_a_s_e_: monitor
monitor result, 0 means catalog base set, 2,3,4,6 means
catalog bas not set.
z (call value). Contains the name of a child process
or a null-name, meaning own process.
i dummy
ia (call value, length '= 2). Contains the base to be
set.
ia(1) lower limit of the base
ia(2) upper limit of the base
f_n_c_ _=_ _7_4_,_ _s_e_t_ _e_n_t_r_y_ _b_a_s_e_:
monitor result, 0 means entry base set, 2,3,4,5,6,7 means
entry base not set.
z (call value). Contains the entry name.
i dummy
ia (call value, length '= 2). Contains the entry base
to be set, as for the fnc = 72, set catalog base.
f_n_c_ _=_ _7_6_,_ _l_o_o_k_u_p_ _h_e_a_d_ _a_n_d_ _t_a_i_l_:
monitor result, 0 means entry looked up, 2,3,6,7 means
entry not look up.
z (call value). Contains the entry name.
i dummy
ia (return value, length '= 17). The head and tail of
the entry is stored here. (The format is described
in ref. 2).
\f
f_n_c_ _=_ _7_8_,_ _s_e_t_ _b_a_c_k_i_n_g_ _s_t_o_r_a_g_e_ _c_l_a_i_m_s_: monitor
monitor result, 0 means claims set, 1,2,3,6 means claims
not set.
z (call value). Contains the name of a child
process.
i dummy
ia (call value, length '= 4 + 2*no of keys). The
first 4 elements contain the name of the bs
document
ia(5) entry claim, key 0
ia(6) segment claim, key 0
.......
ia(5+2*max key) entry claim, max key
ia(6+2*max key) segment claim, max key
f_n_c_ _=_ _8_0_,_ _c_r_e_a_t_e_ _p_s_e_u_d_o_ _p_r_o_c_e_s_s_:
monitor result, 0 means pseudo process created, 1,2,3,6
means pseudo process not created.
z (call value). Contains the name of the pseudo
process.
i dummy
ia dummy
f_n_c_ _=_ _8_2_,_ _r_e_g_r_e_t_ _m_e_s_s_a_g_e_:
monitor no result from this operation. Misuse will give
break 6.
z (call value). Determines together with >i> the
buffer address of the message to be regretted.
i (call value). The number of a share within z. The
share state must be the buffer address at call
time. At return it is 0.
ia dummy
\f
f_n_c_ _=_ _9_0_,_ _p_e_r_m_a_n_e_n_t_ _e_n_t_r_y_ _i_n_ _a_u_x_i_l_i_a_r_y_ _c_a_t_a_l_o_g_: monitor
monitor result, 0 means entry made permanent, 2,3,4,5,6,7
means entry not made permanent.
z (call value). Contains the entry name.
i (call value). The catalog key.
ia (call value, length '= 4). Contains the name of
the bs document.
f_n_c_ _=_ _1_0_2_,_ _p_r_e_p_a_r_e_ _b_a_c_k_i_n_g_ _s_t_o_r_a_g_e_
monitor result, i.e. 0 means chaintable allocated,
1,2,3,4,5,6,7 means chaintable not allocated.
z (call value), the zone record holds the
chainhead.
i dummy
ia dummy
f_n_c_ _=_ _1_0_4_,_ _i_n_s_e_r_t_ _e_n_t_r_y_
monitor result, i.e. 0 means entry inserted in maincata-
log, 1,2,3,4,5,6,7 means entry not inserted in
maincatalog.
z (call value), the zone record holds the
chainhead.
i dummy
ia (call value, length '= 17), contains head and tail
of the entry.
f_n_c_ _=_ _1_0_6_,_ _i_n_s_e_r_t_ _b_a_c_k_i_n_g_ _s_t_o_r_a_g_e_
monitor result, i.e. 0 means document included, 1,2,4,6
means document not included.
z dummy
i dummy
ia (call value, length '= 21), contains the document
name in word 18,19,20, and 21.
\f
f_n_c_ _=_ _1_0_8_,_ _d_e_l_e_t_e_ _b_a_c_k_i_n_g_ _s_t_o_r_a_g_e_ monitor
monitor result, i.e. 0 means document removed, 1,2,4,5,6
means document not removed.
z dummy
i dummy
ia (call value, length'=21), contains the document
name in word 18,19,20, and 21.
f_n_c_ _=_ _1_1_0_,_ _d_e_l_e_t_e_ _e_n_t_r_i_e_s_
monitor result, i.e. 0 means entries deleted, 1,2,3,4,6
means not deleted.
z dummy
i dummy
ia (call value, length '= 21) contains the document
name in word 18,19,20, and 21.
f_n_c_ _=_ _1_1_2_,_ _c_o_n_n_e_c_t_ _m_a_i_n_ _c_a_t_a_l_o_g_
monitor result, i.e. 0 means catalog connected,
1,2,3,4,5,6,7 means catalog not connected.
z (call value), zone record holds the chainhead.
i dummy
ia (call value, length '= 4), contains the catalog
name.
f_n_c_ _=_ _1_1_4_,_ _r_e_m_o_v_e_ _m_a_i_n_ _c_a_t_a_l_o_g_
monitor result, i.e. 0 means main catalog removed, 7 means
main catalog not removed.
z dummy
i dummy
ia dummy
\f
f_n_c_ _=_ _1_2_0_,_ _c_r_e_a_t_e_ _a_u_x_ _e_n_t_r_y_ _a_n_d_ _a_r_e_a_ _p_r_o_c_e_s_s_ monitor
monitor result, i.e. 0 means entry and area process
created, 1,2,3,4,5,6 means entry and area process
not created.
z (call value), contains the area process name.
i dummy
ia (call value), length '= 21), contains head and
tail in word 1 to 17, and the document name in
word 18 to 21.
f_n_c_ _=_ _1_2_2_,_ _r_e_m_o_v_e_ _a_u_x_ _e_n_t_r_y_
monitor result, i.e. 0 means entry removed, 1,2,3,6 means
entry not removed.
z dummy
i dummy
ia (call value, length '= 21), contains head and tail
in word 1 to 17 and the document name in word 18
to 21.
If the requirements stated above are not fulfilled, or if the
situation termed >parameter error> in ref. 2 occurs, the run will
be terminated with an alarm. Values of fnc not mentioned above
will also terminate the run.
E_x_a_m_p_l_e_ _1_: C_r_e_a_t_e_ _a_ _b_a_c_k_i_n_g_ _s_t_o_r_a_g_e_ _a_r_e_a_
A backing storage area sldata3 of s segments
may be created and then used like this:
\f
begin zone z(512,1,stderror); monitor
integer array tail(1:10);
integer i;
open(z,4,<:sldata3:',0);
<* The zone contains now the document name. The
document is not initialized in case of kind=4*'
tail(1):= s;
tail(2):= 1; <*preferably a disc area*'
for i:= 3 step 1 until 10 do tail(i) := 0;
tail(6):= systime (7,0, 0.0); <*shortclock*'
if monitor(40<*create _entry*',z,0,tail) ' 0 then
error(1);
outrec(z,...);
E_x_a_m_p_l_e_ _2_: S_c_o_p_e_ _u_s_e_r_ _o_f_ _a_n_ _a_r_e_a_:
The scope user function consists of 2 steps. First
the area is made permanent with catalog key 3.
Now, as key is '= min global key (see ref. 2), the
entry base may be set to the user base of the
process.
Let the zone z be opened to the area to be
scoped.
system(11)bases:(i,ia);
ia(1):= ia(5); ia(2):= ia(6); <* fetch the user base;*'
if monitor(50)permanent entry:(z,3,ia) <' 0 then error(1)
else
if monitor(74)set _base:(z,0,ia) <' 0 then error(2)
else ...
E_x_a_m_p_l_e_ _3_: F_i_n_d_ _s_c_o_p_e_ _o_f_ _a_n_ _e_n_t_r_y_:
As the catalog base of an internal process and of
a catalog entry may use almost the full integer
range they must be handled as longs when relations
of type <= or '= between them are calculated, in
order to prevent overflow.
\f
system(11)bases:(i,bases); monitor
monitor(76 <*head _and _tail*', z,0,entry) <' 0
then goto error;
case entry(1) extract 3 + 1 of
begin
<*key 0, maybe temp *'
if entry(2) = bases(3) and
entry(3) = bases(4)
then scope:= 1 <*temp*'
else scope:= 6; <*undef*'
<*key 1 *'
scope:= 6; <*undef*'
<*key 2, maybe login *'
if entry(2) = bases(3) and
entry(3) = bases(4)
then scope:= 2 <*login*'
else scope:= 6; <*undef*'
<*key 3, user, project, or system *'
begin
l1:= entry(2); l2:= entry(3);
if l1 = bases(5) and
l2 = bases(6) then scope:= 3 <*user*'
else
if l1 = bases(7) and
12 = bases(8) then scope:= 4 <*project*'
else
if l1 <= extend bases(7) and
l2 '= extend bases(8) then scope:= 5 <*system*'
else scope:= 6; <*undef*'
end
end case;
write(out,<:the scope is: :',case scope of(
<:temp:',<:login:',<:user:',
<:project:',<:system:',<:***, i.e. undef:'));
\f
E_x_a_m_p_l_e_ _4_: monitor
G_e_t_ _t_h_e_ _c_l_a_i_m_s_ _o_f_ _a_ _p_r_o_c_e_s_s_ _o_n_ _a_ _g_i_v_e_n_ _b_s_-_d_e_v_i_c_e_
boolean procedure claimproc
(keyno,bsno,bsname,entries,segm,slicelength);
value keyno;
integer keyno,bsno,entries,segm,slicelength;
long array bsname;
<*
claimproc (return, boolean) true if bsno'=-1 and bsno <= max _bsno and
keyno is legal else false. If claimproc is false then
all return parameters are zero.
keyno (call, integer) 0=temp
2=login
3=user/project
bsno (call/return, integer) if call value is -1 then return
value is main bsdevice number, else bsno is unchanged
bsname (return, long array 1:2) name of called device
entries (return, integer) no. of entries of key=keyno on called device
segm (return, integer) no. of segm. of key=keyno on called device
slicelength (return, integer) slicelength on called device
*'
begin
integer bsdevices,firstbs,ownadr,mainbs,i;
long array field name;
integer array core(1:18);
system(5,92,core);
bsdevices:=(core(3)-core(1))//2;
firstbs:=core(1);
mainbs:= core(4);
ownadr:=system(6,i,bsname);
if bsno<-1 or bsno'=bsdevices or
keyno<'0 and keyno<'2 and keyno<'3 then
begin
\f
claimproc:=false; goto exitclaim monitor
end;
claimproc:=true;
begin integer array nametable(1:bsdevices);
name:=18;
system(5,firstbs,nametable);
if bsno= -1 then <*find main device number*'
for bsno:= bsno + 1 while nametable(bsno+1) <' mainbs do;
system(5,nametable(bsno+1)-36,core); <*get chaintable*'
if core(10)=0 then goto exitclaim;
bsname(1):=core.name(1); bsname(2):=core.name(2);
slicelength:=core(15);
system(5,ownadr+core(1),core); <*get process description*'
entries:=core(keyno+1) shift (-12);
segm:=core(keyno+1) extract 12 * slicelength;
end;
if false then
begin
exitclaim:
entries:=segm:=slicelength:=0;
bsname(1):=bsname(2):=0;
end;
end claimproc;
Claims on a specific device are found as follows:
bsno:=-1;
for bsno:=bsno+1 while
claimproc(keyno,bsno,bsname,entries,segm,slicelength)
and -,(searchname(1)=bsname(1) and searchname(2)=bsname(2)) do;
Max claims are found as follows:
\f
maxentr:=max:=maxslice:=0; monitor
maxbs(1):=maxbs(2):=0;
bsno:=-1;
for bsno:=bsno+1 while
claimproc(keyno,bsno,bsname,entries,segm,slicelength) do
if entries'0 and segm'max then
begin
maxentr:=entries; max:=segm; maxslice:=slicelength;
maxbs(1):=bsname(1); maxbs(2):=bsname(2);
end;
E_x_a_m_p_l_e_ _5_: R_e_n_a_m_i_n_g_ _a_n_ _e_n_t_r_y_
The procedure renames a catalog entry. The procedure works iden-
tical to the utility program rename, with the extension that a
work-name may be returned.
integer procedure renameproc (oldname, newname);
long array oldname, newname;
<*
renameproc (return integer) 0 ok
1 new name exists already
2 cat i/o error
document not mounted or
document not ready
3 oldname not found
4 name protected
5 name in use
6 name format illegal
7 catalog inconsistent
oldname (call long array) contains old name
newname (call long array) contains new name or <::'.
if newname(1)=long<::' then
newname is a return parameter,
containing a wrk-name.
'*
\f
begin monitor
integer i; boolean wrk;
long array field laf;
zone zhelp(1, 1, stderror);
integer array ia(1:20);
wrk:=newname(1)=long<::';
if wrk then
begin
generate _next:
monitor(68<*generate*', zhelp, 0, ia);
getzone6(zhelp, ia);
laf:=2;
newname(1):=ia.laf(1); newname(2):=ia.laf(2);
end;
laf:=0;
ia.laf(1):=newname(1);
ia.laf(2):=if newname(1) extract 8 = 0 then long<::'
else newname(2);
open(zhelp, 0, oldname, 0);
renameproc:= i:= monitor(46<*rename*', zhelp, 0, ia);
if i=3 then
begin <*oldname not found, or newname already exists*'
i:=monitor(42<*lookup*', zhelp, 0, ia);
if i=0 then
begin
if wrk then goto generate _next else renameproc:=1
end;
end
end renameproc;
\f
E_x_a_m_p_l_e_ _6_: L_i_s_t_i_n_g_ _o_f_ _a_n_ _e_n_t_r_y_ _t_a_i_l_ monitor
Monitor 42, lookup entry, will place the catalog tail in an
array, which can be listed by the following procedure:
procedure list _tail (zout, tail);
zone zout; integer array tail;
<* the procedure lists the contents of array tail as a catalog entry
zout (return, zone) zone for output
tail (call, integer array) contains entry tail
*'
begin
integer n,i;
long array field docname;
real r;
docname:=2;
n:=tail(1);
if n'=0 then write(zout,<<z',n) else
write(zout,<<z',n shift (-12) extract 12,<:.:',n extract 12);
n:=tail(2);
if n=0 or n=1 then write(zout,n) else
write(zout,<: :',tail.docname);
n:=tail(9) shift (-12);
i:=6;
if -,(n=4 or n'=32) and tail(6)<'0 then
begin
write(out),<:d.:',<<zddddd.dddd',
systime(6, tail(6), r)+r/1000000);
i:= 7;
end;
while i<11 do \f
begin monitor
n:=tail(i);
if n'= 0 and n<4096 then write(zout,<<z',n) else
write(zout,<<z',n shift (-12) extract 12,<:.:',<<z',n extract 12);
i:= i + 1;
end;
end list _tail;
E_x_a_m_p_l_e_ _7_: C_r_e_a_t_i_n_g_ _a_ _n_e_w_ _e_n_t_r_y_
The procedure creates a new catalog entry with scope temp or
changes an already existing entry (with scope temp) according to
the parameters. The procedure works identical to the utility
program set, with the extension that a work-name may be
returned.
integer procedure setproc (name, tail);
long array name; integer array tail;
<*
setproc (return, integer) 0 ok
1 change kind impossible
2 bs device unknown
3 change bs device impossible
4 no resources
5 in use
6 name format illegal
7 catalog inconsistent
name (call, long array) contains the entry name.
If name(1)=long<::' a wrkname is
created and name is returnparameter.
tail (call, integer array) contains the entry tail
1 size or modekind
2:5 docname
6 shortclock, in case shortclock
is wanted in the entry
7:10 remaining tail
*' \f
begin monitor
integer i;
long array field laf;
zone zhelp(1,1,stderror);
integer array ia(1:20);
open(zhelp, 0, name ,0);
for i:= 1 step 1 until 10 do ia(i):= tail(i);
<*tail could possible be a fielded array. As fielding does
not work in monitor the contents of tail is moved to the
non-fielded array ia*'
setproc:= i:= monitor(40<*create*',zhelp,0,ia);
if name(1)=long<::' then
begin <*get wrkname*'
getzone6(zhelp,ia);
laf:=2;
name(1):=ia.laf(1);
name(2):=ia.laf(2);
end;
if i=3 then
begin <*entry exist*'
i:=monitor(42<*lookup*',zhelp,0,ia);
if i<'0 then
begin
setproc:=7; goto exit _setproc
end;
if tail(1)<0 or ia(1)<0 then
begin
if tail(1)'=0 or ia(1)'=0 then
begin
setproc:=1; goto exit _setproc
end;
goto change
end;
if tail(2)=0 or tail(2)=1 then goto change;
if tail(3) extract 8=0 then tail(4):=tail(5):=0;
if tail(2)<'ia(2) or tail(3)<'ia(3) or
tail(4)<'ia(4) or tail(5)<'ia(5) then \f
begin monitor
setproc:=3; goto exit _setproc
end;
change:
for i:= 1 step 1 until 10 do ia(i):= tail(i);
i:=monitor(44<*change*',zhelp,0,ia);
if i=6 then i:=4;
setproc:=i;
end entry exists;
exit _setproc:
end setproc;
In case an array containing head _and _tail exists, it may be used as
follows:
iaf:= 14; setproc(name,head _and _tail.iaf);
\f
E_x_a_m_p_l_e_ _8_: C_h_a_n_g_i_n_g_ _a_n_ _e_n_t_r_y_ monitor
The procedure changes the specified entry. The procedure works
identical to the utility program changeentry.
integer procedure changeentryproc (name, tail);
long array name; integer array tail;
<*
changeentryproc (return, integer)
0 ok
1 change kind impossible
2 cat i/o error, doc. not mounted or not ready
3 name not found
4 name protected
5 name in use
6 name format illegal
7 catalog inconsistent
8 change bs device impossible
9 claims exceeded
name (call, long array) contains the entry name
tail (call, integer array) contains new entry tail
*'
begin
integer i;
integer array ia(1:10);
zone zhelp(1,1,stderror);
open(zhelp,0,name,0);
i:= monitor(42<*lookup*',zhelp,0,ia);
if i<'0 then
begin
changeentryproc:=i; goto exit _changeentryproc
end;
if tail(1)<0 or ia(1)<0 then
begin
if tail(1)'=0 or ia(1)'=0 then
begin
changeentryproc:= 1; goto exit _changentryproc
end;
goto change;
end; \f
if tail(2)=0 or tail(2)=1 then goto change; monitor
if tail(3) extract 8=0 then tail(4):=tail(5):=0;
if tail(2)<'ia(2) or tail(3)<'ia(3) or
tail(4)<'ia(4) or tail(5)<'ia(5) then
begin
changeentryproc:=8; goto exit _changeentryproc
end;
change:
<*tail could be a fielded array, cf.example 7*'
i:=monitor(44<*change*',zhelp,0,ia);
if i=6 then i:=9;
changeentryproc:=i;
exit _changeentryproc:
end changeentryproc;
In case the programmer only wants to change shortclock and maybe
size, it may be done as follows:
begin
integer i;
zone z(128,1,stderror);
integer array ia(1:10);
open(z,4,<:pip:',0);
...
...
i:=monitor(42<*lookup*',z,0,ia);
if i<'0 then
begin <* alarm, see lookupproc (ex. 9)*' end;
ia(1):=36; <*new size*'
ia(6):= systime (7, 0, 0.0); <*shortclock*'
i:=monitor(44<*change*',z,0,ia);
if i<'0 then
begin <* alarm, as changeentryproc, except 6=claims
exceeded *'
end;
...
\f
E_x_a_m_p_l_e_ _9_: L_o_o_k_u_p_ _o_f_ _a_n_ _e_n_t_r_y_ monitor
The procedure performs a lookup of the specified name.
integer procedure lookupproc (scope, name, tail);
long array scope, name;
integer array tail;
<*
lookupproc (return, integer)
0 found
1 the call param scope does not contain a legal
scope name
2 cat i/o error
3 not found
6 name format illegal
scope (call, long array)
contains the name of a scope or <::'.
If scope(1)=long <::' then scope will
be a return parameter which may be <:***:'
name (call, long array) contains the name of the entry
tail (return, integer array)
contains tail of the entry:
1 size or modekind
2:5 docname
6 shortclock, in case shortclock is found in the
entry
7:10 remaining tail
*'
\f
integer procedure lookupproc (scope, name, tail); monitor
long array scope, name;
integer array tail;
begin
integer scopeno, permkey, i;
long l1, l2;
zone zhelp(1, 1, stderror);
integer array bases(1:8), ba(1:2), head _and _tail(1:17);
real array field raf;
procedure return (val);
value val; integer val;
begin
lookupproc:= val;
for i:= 1 step 1 until 10 do tail(i):= 0;
if scopeno <' 6 then reset _base;
goto exit _lookupproc;
end;
procedure reset _base;
begin
close(zhelp,false);
open(zhelp,0,<::',0);
monitor (72<*set bases*', zhelp, 0, bases);
end;
lookupproc:= 0;
l1:= scope(1) shift (-8) shift 8; <*first 5 chars*'
scopeno:= 6;
for i:= 0 step 1 until 5 do
if l1 = long (case i+1 of (
<::', <:temp:', <:login:',
<:user:', <:proje:' <:syste:'))
then scopeno:= i;
if scope = 6 then return(1); <*illegal scope specified*'
\f
system (11<*catalog bases*', 0, bases); monitor
if scopeno < 3 then 3 else
if scopeno = 3 then 5 else 7;
ba(1):= bases(i); ba(2):= bases(i+1);
open(zhelp,0,<::',0);
monitor (72<*set cat base*', zhelp,0,ba);
close (zhelp, true);
open (zhelp,0,name,0);
i:= monitor (76<*head _and _tail*', zhelp,0,head _and _tail);
if i<'0 then return(i);
if scopeno'0 and scopeno<5 and
(head _and _tail(2) <' ba(1) or
head _and _tail(3) <' ba(2))
then return(3); <*entry not found*'
permkey:= head _and _tail(1) extract 3;
if scopeno=1 and permkey<'0 or
scopeno=2 and permkey<'2 or
scopeno'2 and permkey<'3
then return(3); <*entry not found*'
if scopeno=5 then
begin
if -, (head _and _tail(2) < ba(1) or
head _and _tail(3) ' ba(2))
then return(3); <*entry not found*'
end;
\f
<*now the entry has been found, find the scopemonitor
if this was not specified*'
if scopeno = 0 then
begin
l1:= head _and _tail(2);
l2:= head _and _tail(3);
case permkey+1 of
begin
<*0*' if l1 = bases(3) and
l2 = bases(4)
then scopeno:= 1 <*temp*'
else scopeno:= 6;<*undef*'
<*1*' scopeno:= 6;<*undef*'
<*2*' if l1 = bases(3) and
l2 = bases(4)
then scopeno:= 2 <*login*'
else scopeno:= 6;<*undef*'
<*3*' if l1 = bases(5) and
l2 = bases(6) then scopeno:= 3 <*user*'
else
if l1 = bases(7) and
l2 = bases(8) then scopeno:= 4 <*project*'
else
if l1 <= extend bases(7) and
l2 '= extend bases(8) then scopeno:= 5 <*system*'
else scopeno:= 6;<*undef*'
end case;
raf:= 0
scope(2):= 0;
movestring (scope.raf, 1, case scopeno of (
<:temp:', <:login:', <:user:',
<:project:',<:system:',<:***:'));
end scopeno = 0;
\f
<*assign the catalog tail to the return parameter*' monitor
for i:= 1 step 1 until 10 do
tail(i):= head _and _tail(i+7);
reset _base;
exit _lookupproc:
end lookupproc;
If the entry of smallest scope should be looked up, this
procedure is not necessary, as this can be done by the following
procedure or similar statements:
integer procedure xlookup (name, tail);
long array name; integer array tail;
begin
zone zhelp(1,1,stderror);
integer i;
open(zhelp,0, name ,0);
xlookup:= i:= monitor(42<*lookup*',zhelp,0,tail);
if i<'0 then
for i:=1 step 1 until 10 do tail(i):=0;
end xlookup
where xlookup will contain the value corresponding to
lookupproc with the exception of the value 1.
E_x_a_m_p_l_e_ _1_0_: W_a_i_t_
The procedure waits as many seconds as specified by the
parameter.
procedure pause (time);
integer time ;
begin
integer array ia(1:20);
zone clock(1,1, stderror);
\f
open (clock, 2, <:clock:', 1 shift 9); monitor
getshare6(clock, ia, 1);
ia(4):= 0;
ia(5):= time;
setshare6(clock, ia, 1);
if monitor (16<*send message*), clock, 1, ia) = 0 then
system(9,6,<:<10'break:'); <*buffer claim exceeded*'
monitor (18<* wait answer*', clock, 1, ia);
end pause;
E_x_a_m_p_l_e_ _1_1_: See example 4 of system.
\f
F_ 2_._8_9_ _ _ _ _ _ _m_o_v_e_s_t_r_i_n_g_ 2.89 movestring
This integer standard procedure is used for moving textstrings
of various kind.
C_a_l_l_: movestring (ra, i, st);
movestring (return value, integer); the number of
elements in ra to which a string port-
ion has been assigned. It is negative
if the string was too big for the
array.
ra (return value, real array or zone). The
string is stored in ra(i), ra(i+1), and
so on. For arrays of more dimensions
the lexicographical ordering is used.
i (call value, integer); see ra above.
st (call value, string); layout or text-
string terminated by a NULL character.
Moves either a layout or a whole textstring until
a null character is encountered or the array is
filled. The various string expressions are defined
in ref. 15.
E_x_a_m_p_l_e_ _1_: A textstring can be inserted in a long array when
using a real array field:
begin
long array la(1:10);
real array field raf;
...
raf:= 0;
movestring (la.raf, 1, <:some text:');
\f
2_._9_0_ _ _ _ _ _ _m_u_l_t_i_p_l_y_ _(_*_)_ 2.90 multiply
This delimiter, which is an arithmetic operator, yields the
product of the two operands.
S_y_n_t_a_x_: <operand1' * <operand2'
P_r_i_o_r_i_t_y_: 3
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real.
R_e_s_u_l_t_ _t_y_p_e_: <integer' * <integer' is of type integer
<integer' * <long' - - - long
<integer' * <real' - - - real
<long' * <integer' - - - long
<long' * <long' - - - long
<long' * <real' - - - real
<real' * <integer' - - - real
<real' * <long' - - - real
<real' * <real' - - - real
S_e_m_a_n_t_i_c_: The operation may include a type conversion.
Real values are represented with a relative pre-
cision of about 3>-11 (cf. ref. 15). This means
that real variables holding an integral value is
represented exact in the interval -2**35 <= real
<= 2**35-1.
As multiplication of long values includes
call of subroutines (cf. ref. 15), and cannot
be performed by built-in operations, a
representation of certain long variables in
real variables may be advantageous (cf. ref.
15).
E_x_a_m_p_l_e_ _1_: i:= 5*a;
j:= i*(b+4);
r:= k * z.laf(4) * arr(7*c)
\f
F_ 2_._9_1_ _ _ _ _ _ _n_e_w_a_c_t_i_v_i_t_y_ 2.91 newactivity
This long standard procedure initializes an e_m_p_t_y_ _a_c_t_i_v_i_t_y_ with a
procedure (a coroutine), and starts the activity.
C_a_l_l_: new _activity (actno, virt, proc, params);
new _activity (return value, long). The value is
composed by two integers:
activityno shift 24 add cause
describing the way in which newactivity
returns (see below).
actno (call value, integer). The identifica-
tion of the activity to be initialized.
The activity must be e_m_p_t_y_.
virt (call value, integer). Determines
whether or not the designated activity
will share stack area with another
activity:
virt = 0: The designated activity will
n_o_t_ be virtual, i.e. it will have its
own stack area.
virt ' 0: must be a legal activity
number. The activity: actno, will be
virtual, i.e. share stack area with the
activity numbered: virt. If virt <'
actno virt must define a non-empty
virtual activity.
proc (call value, procedure). The activity
actno is initialized with this
procedure, wich is called with the
actual parameters stated in the
parameter list params.
params (call values). A (possibly empty) list
of parameters in the call of proc.
Storage resources for variables etc. are allocated in the stack,
the top of which is defined by a running system variable:
last _used. \f
The stack administration is for activity purposes supplied withnewactivity
another running system variable: max _last _used, defining the
upper limit for last used. Stack overflow is detected by compari-
son of these two variables.
To each activity is allocated a maximal contiguous stack area,
defined by the pair: (initial _last _used, max _last _used) for the
activity. The very first call of new _activity for each activity,
determines the values of the corresponding: (initial _last _used,
max _last _used). When an activity is entered (by activate), the
running system uses the stack allocated to the activity. When an
activity returns to the monitor block (by passivate), the running
system uses the stack allocated to the monitor block.
F_u_n_c_t_i_o_n_: new _activity must be called at the m_o_n_i_t_o_r_ _b_l_o_c_k_ level
(cf. procedure activity).
The execution of:
result := new _activity (actno, virt, proc, params);
now proceeds as follows:
1) If the block level of the call is not the monitor
block level, new _activity terminates with an
alarm.
2) If the program is not in monitor mode, the run is
terminated with an alarm.
3) If actno < 1 or actno ' max _no _of _activities or
virt < 0 or virt ' max _no _of _activities, the run is
terminated with an alarm.
4) If the activity actno, is not empty, new _activity
returns with the result = actno shift 24 add (-1).
5) If the stack area is not allocated, the actual
value of last _used (monitor last used) defines the
stack and initial _last _used for the activity.
\f
6) If the activity is to be virtual, and shared vir- newactivity
tual occupies the stack area, the used part of the
stack area is transferred to the virtual storage.
If, however, the shared virtual waits for an i/o
operation to complete, newactivity returns with the
result:
shared _virtual shift 24 add (-2).
7) The procedure: proc, is called with params as ac-
tual parameters, and the program is now in activity
mode. It is n_o_t_ _c_h_e_c_k_e_d_, that this parameter list
corresponds to the formal specifications in the
procedure declaration. The procedure returns:
- executing a passivate statement or
- leaving through its final end or
- because of a runtime alarm.
defining the value of: result. At return, the
program is back in monitor mode.
8) If a stack area was not allocated, when newactivity
was called, the following is done at return from
newactivity: The maximal last _used appearing during
the execution in activity mode is selected to re-
present max _last _used of the activity, and at the
same time last _used of the monitor block.
9) If the activity is to be virtual, a record in the
virtual storage is reserved to hold the stack area
of the activity.
The transfers between stack and virtual storage
(swops) are initiated by newactivity or activate,
when an activity, not at present occupying the
stack area, is to be activated (restarted). The
virtual storage is the same as used for context
blocks.
\f
If the designated activity is empty, but has been in-newactivity
itialized before in a previous call of new _activity,
the stack area is a priori fixed by limits defined in
the very first call of new _activity for the designated
activity. A non-empty activity becomes empty, if it:
- leaves throuth its final end or
- terminates with a runtime alarm.
R_e_s_u_l_t_ _v_a_l_u_e_s_: The return values activityno shift 24 add cause
have the following meaning:
activity _no: The identification of the activity
causing the return. In case of
cause = -2, the activity waiting
for an i/o operation to complete.
cause indicate the return cause:
cause = -3: new _activity returned because of an
alarm in a started activity, which
is now empty.
cause = -2: new _activity returns, because the
designated activity is virtual and
shares storage with another activi-
ty waiting for an i/o operation to
complete (see the parameter: virt).
cause = -1: new _activity returns because the
designated activity is n_o_t_ empty.
cause = 0: new _activity returns because a
started activity terminated via its
final end. The activity is now
empty.
cause = 1: new _activity returns because a
started activity is passivated by a
p_r_o_g_r_a_m_m_e_d_ passivate statement.
\f
cause = 2: new _activity returns because anewactivity
started activity is passivated by
an implicit passivate statement in
the zone i/o system.
E_x_a_m_p_l_e_ _1_: If a minimum space is needed in the stack for an
activity (for later procedure calls, arrays in
inner blocks etc.) this may be assured by calling
the following procedure from an activity, during
its very first execution (cf. 8 in the description
above);
procedure claim (n); value n; integer n;
begin array a (1:n); end;
Example 1 of activity shows the use of the
procedure.
E_x_a_m_p_l_e_ _2_: begin integer i, j; <*monitor block*'
procedure p (n, m);
integer n, m;
begin integer s, t;
...<*activity mode*'
s:=2; t:=3;
passivate;
...
end;
procedure q (x, y, z);
value x, y, z; real x, y, z;
begin integer k, l;
...<*activity mode*'
k:=4; 1:=5;
passivate;
...
end;
<*neutral mode*'
activity (5);
<*monitor mode*'
for i:=1, 2 do
new _activity (i, 0, p, i, j);
for i:= 3, 4, 5 do
new _activity (i, 3, q, 0, 0, 0);
...
\f
newactivity
In this example, 5 activities are created and
initialized. Activity no. 1 and 2 are both started
with the procedure p. The virtual activities no.
3, 4, and 5 are all started with the procedure q.
In the figure above is shown the contents of stack
and virtual storage after initialization of
activity no. 5. Note that activity no. 1 and 2 via
name parameter work on common variables. Note
also, that the virtual record of activity no. 5 is
empty, because the stack is still in core.
\f
2_._9_2_ _ _ _ _ _ _n_e_w_s_o_r_t_ 2.92 newsort
This standard procedure creates a zone record in core store which
is to take part in a sorting process. The contents of the record
is initially undefined, but the user is supposed to assign values
to the record variables before next call of any sorting
procedure. The so defined record becomes an active record in the
sorting process (see procedure outsort).
C_a_l_l_: newsort (z, key) or newsort (z)
z (call and return value, zone). The name of
the record created.
key (call value, integer procedure or empty). The
name of a procedure for comparison of two re-
cords (see below).
The key parameter is omitted if standard sequen-
cing is used (see procedure startsort6).
Z_o_n_e_ _s_t_a_t_e_: The zone state must be 9, in sort, i.e. startsort6
(or initsort) must have been called. The state is
not changed by the procedure.
S_e_q_u_e_n_c_i_n_g_: The integer procedure key is supplied by the user,
when a non-standard sequencing is wanted. It det-
ermines which of two records is to appear first
in a sorted string of records:
C_a_l_l_: key (record1, record2)
record1, record2, (call values, arrays). The name
of two records to be compared.
key (return value, integer). The
result of comparison of record1
and record2. This return value
must adhere to the following
rules.
record1 before record2: key < 0
record1 after record2 : key ' 0
sequence unimportant : key = 0
\f
E_x_a_m_p_l_e_ _1_: This is an example of a key procedure which can be newsort
used to sort a number of records of length 10 real
on ascending number of equal words within a single
record.
integer procedure mostequals(v, w);
real array v, w ;
begin
integer procedure equals(x);
real array x ;
begin
integer count, i, j, k;
real z;
count:= 0;
for i:= 1, i+1 while i<= 10 and count < i do
begin
z:= x(i); k:= 1;
for j:= i + 1 step 1 until 10 do
if z = x(j) then k:= k + 1;
if k ' count then count := k;
end;
equals:= count
end equals;
mostequals:= equals(v) - equals(w)
end mostequals;
Note that the structure of a record (for instance
the record length) is supposed to be known to the
procedure as global information (for instance by
certain values of certain fields in the record).
E_x_a_m_p_l_e_ _2_: 100 records of length 10 double words per record
are stored in array B(1:100,1:10). These records
are to be sorted on ascending number of equal
words within a single record. Therefore, the key
procedure of example 1 is used.
\f
begin newsort
zone z(1199,1,sorterror);
<*buffer length as required by initsort*'
integer i, j;
initsort(z, 10);
for i:= 1 step 1 until 100 do
begin
newsort(z, mostequals);
for j:= 1 step 1 until 10 do z(j):= B(i, j)
end;
for i:= 1 step 1 until 100 do
begin
outsort(z, mostequals);
for j:= 1 step 1 until 10 do B(i, j):= z(j)
end
end;
E_x_a_m_p_l_e_ _3_: Same as example 2, but now the sorting is on
ascending double word one followed by descending
double word five (standard sequencing).
begin
zone z(1022,1,sorterror);
<*buffer length as required by startsort6*'
integer i, j;
integer array keys(1:2, 1:2);
keys(1,1):= 4; keys(1,2):= 4;
keys(2,1):=-4; keys(2,2):=20;
<* definition of sequencing,
see startsort6*'
startsort6(z, keys, 2, 40);
for i:= 1 step 1 until 100 do
begin
newsort(z);
for j:= 1 step 1 until 10 do z(j):= B(i, j)
end;
for i:= 1 step 1 until 100 do
\f
begin newsort
outsort(z);
for j:= 1 step 1 until 10 do B(i,j):= z(j)
end
end;
\f
F_ 2_._9_3_ _ _ _ _ _ _n_o_t_ _(_-_,_)_ 2.93 not
This delimiter, which is a monadic logical operator, yields the
logical negation of the operand.
S_y_n_t_a_x_: -, <operand'
P_r_i_o_r_i_t_y_: 6
O_p_e_r_a_n_d_ _t_y_p_e_: boolean
R_e_s_u_l_t_ _t_y_p_e_: boolean
S_e_m_a_n_t_i_c_: The negation of a boolean gives the result false
if the boolean is true and the result true if the
boolean is false.
E_x_a_m_p_l_e_ _1_: -, b
-, (a=2)
-, (-,p) is equivalent to p
-, (p and q) is equivalent to -,p or -,q
-, (p or q) is equivalent to -,p and -,q
-, p or q is equivalent to p =' q
\f
F_ 2_._9_4_ _ _ _ _ _ _n_o_t_ _e_q_u_a_l_ _(_<_'_)_ 2.94 not equal
This delimiter, which is a relational operator, gives the value
true or false.
S_y_n_t_a_x_: <operand1' <' <operand2'
P_r_i_o_r_i_t_y_: 5
O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real.
R_e_s_u_l_t_ _t_y_p_e_: always boolean.
S_e_m_a_n_t_i_c_: The relation takes on the value true whenever the
bitpattern of the two operands are equal,
otherwise false.
The relation is performed as a bit by bit compari-
son of the two operands (after a possible type
conversion whenever the operands are of different
types).
E_x_a_m_p_l_e_ _1_: c:= d <' q;
if m <' idle then ... else ...
while empty <' full do ... \f
F_ 2_._9_5_ _ _ _ _ _ _o_p_e_n_ 2.95 open
This standard procedure connects a document to a given zone in
such a way that the zone may be used for input/output with the
high level zone procedures.
C_a_l_l_: open (z, modekind, doc, giveup)
z (call and return value, zone). After re-
turn, z describes the document.
modekind (call value, integer). Mode shift 12 +
kind. See below.
doc (call value, string or any type array). A
text string or an array containing a text,
specifying the name of the document as re-
quired by the monitor, i.e. a small letter
followed by a maximum of 10 small letters
or digits.
giveup (call value, integer). Used in connection
with the checking of a transfer. See
below.
M_o_d_e_k_i_n_d_: Specifies the kind of the document (typewriter,
backing storage, magnetic tape, etc.) and the
mode in which it should be operated (even parity,
odd parity, etc.).
The kind of the document tells the input/output proce-
dures how error conditions are to be handled, how the
device should be positioned, etc. This kind has nothing
to do with the kind mentioned in ref. 1. As a rule, the
procedures do not care for the actual physical kind of
the document, but disagreements may give rise to bad
answers from the document. If you, for example, open a
backing storage area with a kind specifying printer,
and later attempt to output via the zone, the backing
storage area will reject the message because the docu-
ment was initialised as required by printer.
\f
Mode and kind must be coded as shown in the table be-open
low. If you attempt a mode which does not fit into the
table, an alarm occurs.
Kind:
0 i_n_t_e_r_n_a_l_ _p_r_o_c_e_s_s_
4 b_a_c_k_i_n_g_ _s_t_o_r_a_g_e_ _a_r_e_a_
mode = 0, specifies full error recovery.
mode = 2, specifies suppression of automatic error
recovery.
mode = 4, specifies limited error recovery on parity
errors occuring at an input operation.
8 t_e_r_m_i_n_a_l_s_
input modes:
mode = 0, intended for conversational operation by means of
keyboard.
mode = 2, paper tape input from teleterminal, ISO characters
in even parity.
mode = 4, paper tape input from teleterminal, no parity.
output modes:
mode = 0, normal text mode.
mode = 2, transparent text mode, even parity.
mode = 4, transparent output mode, no parity.
10 p_a_p_e_r_ _t_a_p_e_ _r_e_a_d_e_r_
mode = 0, odd parity.
mode = 2, even parity.
mode = 4, no parity.
mode = 6, flexowriter to ISO conversion.
12 p_a_p_e_r_ _t_a_p_e_ _p_u_n_c_h_
mode = 0, odd parity.
mode = 2, even parity.
mode = 4, no parity.
mode = 6, ISO to flexowriter conversion.
mode = 8, even parity (<10' implies <13' <10' <127').
\f
14 l_i_n_e_ _p_r_i_n_t_e_r_ open
mode = 0, the answer is returned when the transmitted
block has been w_r_i_t_t_e_n_.
mode = 2, the answer is returned when the transmitted
block has been r_e_c_e_i_v_e_d_.
16 c_a_r_d_ _r_e_a_d_e_r_
mode = 0, punched binary.
mode = 10, punched decimal with conversion.
mode = 64, mark sense binary.
mode = 74, mark sense decimal with conversion.
mode = 256, basic cards.
See ref. 3 for further information.
18 m_a_g_n_e_t_i_c_ _t_a_p_e_:
modekind is defined to be:
T shift 16 + mode shift 12 + 18
9 track tape:
mode = 0, means 1600 bpi MTO
mode = 4, means 800 bpi NRZ
For output 0 <= T < 6 specifies that the last T
physical characters in a block should not be output to
the tape.
For input T should be 0.
7 track tape:
mode = 4, means 556 bpi NRZ
mode = 6, means 556 bpi NRZE
For the description of T see ref. 3.
For further information see ref. 3.
If you use T <' 0 during output you should set the
word defect bit (1 shift 7) and the stopped bit (1 shift
8) in your give up mask and after a check of halfwords
transferred simply ignore the bit in your block proce-
dure.
\f
18 c_a_s_e_t_t_e_ _t_a_p_e_ open
modekind is defined to be:
SLEW shift 20 + ECMA shift 19 + T shift 16 + mode
shift 12 + kind.
ECMA = 1 for ECMA version 1 (read only),
= 0 otherwise.
SLEW = 0, normal
= 1, slew mode
T see description of 9-track tape.
mode = 4, 800 bpi NRZ
For further information about kind and mode, see
relevant manual describing the external processes.
I_n_i_t_i_a_l_i_s_a_t_i_o_n_ _o_f_ _a_ _d_o_c_u_m_e_n_t_
Open prepares the later use of the document according
to kind:
Internal process, backing storage area, typewriter:
Nothing is done. When a transfer is checked later, the
necessary initialisation is performed.
Paper tape, card reader:
First, open checks to see whether the reader is reser-
ved by another process. If it is, the parent receives
the message
wait for <name of document'
and open waits until the reader is free. Second, open
initialises the reader and empties it. Third, open
initialises the reader again (in order to start reading
in lower case), sends a parent message asking for the
reader to be loaded, and waits until the first char-
acter is available.
\f
Paper tape punch, line printer: open
Open attempts to reserve the document for the job, but
the result of the reservation is neglected.
Magnetic tape:
If the tape is not mounted, a parent message is sent
asking for mounting of the tape. The message is sent
without wait indication (see ref. 7).
Some of these rules have been introduced to remedy a
possible lack of an advanced operating system.
G_i_v_e_u_p_: The parameter giveup is a mask of 24 bits which will be
compared to the logical status word (ref. 15) each time
a transfer is checked. If the logical status word
contains a one in a bit where giveup has a one, the
standard action for that error is skipped and the block
procedure is called instead (the block procedure is
also called if a hard error is detected during the
checking).
The bit 1 shift 9 in giveup has a special meaning: If
the zone is opened with this bit set to one, and the
program is in activity mode, then an implicit passivate
statement is executed in the running systems check
routine and in monitor (18 ...) making concurrent i/o
transfers possible in a program containing coroutines.
For further information see ref. 19.
Z_o_n_e_ The zone must be in state 4, after declaration. The
s_t_a_t_e_: state becomes positioned after open (ready for input-
/output) except for magnetic tapes, where setposition
must be called prior to a call of an input/output
procedure.
The entire buffer area of z is divided evenly among the
shares and if the document is a backing storage area,
the share length is made a multiple of 512 halfwords.
If this cannot be done without using a share length of
0, the run is terminated.
The logical position becomes just before the first
element of block 0, file 0.
\f
E_x_a_m_p_l_e_ _1_: The normal usage of a tape reader named >reader> goes open
like this:
begin zone z(25*2,2,stderror);
open(z,2 shift 12+10,<:reader:',0);
read(z,...);...
close(z,true);
end;
If you replaced stderror with the procedure >list>:
procedure list(z,s,b); zone z; integer s,b;
write(out,<:<10':',s,b);
and called open with 1 shift 1 instead of 0, the
block procedure would be activated after each tape
transfer and you would get a complete log of the
actions of the reader. (The procedure >list>
should print in a better way to be really useful).
E_x_a_m_p_l_e_ _2_: Assume you need two magnetic tapes in a job. Then the
best communication with the operating system is obtaine
in this way:
open(z1,18,<:mt1706:',0);
open(z2,18,<:mt1712:',0);
setposition(z1,1,0); setposition(z2,1,0);
If none of the tapes are mounted, the operating
system may get the messages:
mount mt1706 without wait indication (caused by open(z1,...))
mount mt1712 without wait indication (caused by open(z2,...))
mount mt1706 with wait indication (caused by setposition(z1...))
and the job is stopped by the operating system until
the tape waited for has been mounted.
\f
E_x_a_m_p_l_e_ _3_: Nearly all document names will be supplied as data to open
the algol program and in many cases the kind and mode
are given as data too. A convenient way of doing this
is to use the following syntax of the data:
<kind and mode' <document name' <possibly a fileno'
Kind and mode are represented as the mnemonic code of
the fp-utility program >set>. The algol program may
then look like this:
begin
boolean procedure openvar(z,giveup);
zone z; integer giveup;
begin array text(1:3); integer i,j;
openvar:= true; j:= 0;
readstring(in,text,1);
for i:= 1 step 1 until 17 do
if text(1) = real(case i of
(<:ip:',<:bs:',<:tw:',<:tro:',<:tre:',...))
then j:= i;
if readstring(in,text,1) ' 2 or j = 0 then
openvar:= false
else
open(z,case j of(0,4,8,10,2 shift 12 + 10,...),
text, giveup);
if j ' 15 then <*magnetic tape*'
begin read(in,i);
setposition(z,i,0)
end;
end openvar;
...
begin zone master,trans,new(256*2,2,stderror);
if -, (openvar(master,0) and
openvar(trans,0) and
openvar(new,0)) then dataerror
else
begin
inrec6(master,m1); inrec6(trans,t1);...
\f
F_ 2_._9_6_ _ _ _ _ _ _o_p_e_n_t_r_a_n_s_ 2.96 opentrans
This standard procedure outputs a transaction head of a format
8000 transaction, and initiates a zone for character writing.
Opentrans may be regarded as the reverse operation of waittrans.
Note, that no waiting takes place.
C_a_l_l_: opentrans (z, format, destination, aux1, aux2)
z (call and return value, zone). Specifies the
document to which transactions are
transferred.
format (call value, integer). Defines the format of
the transaction to be sent:
1: read modified format
2: short read format
3: write format
4: read buffer format
destination (call value, integer). Designates the
receiver of the transaction, i.e.
display terminal, computer, or RC8000
application.
aux1 (call value, integer). Depending on the
format of the transaction, aux1 speci-
fies the attention type, write command
code, or is not used.
aux2 (call value, integer). Depending on the
format of the transaction, aux2 speci-
fies the cursorposition, write control
character, or is not used.
Note that in communication with display terminals, only
format 3 (write format) can be used. Format 1, 2, and 4
can only be sent to computers or other RC8000 applica-
tions.
For further details about format, aux1, and aux2 see
waittrans.
\f
Z_o_n_e_ _s_t_a_t_e_: The zone must be open and ready for opentrans opentrans
(state 0 or 13), i.e. since the latest call of
open, setposition, or closetrans. The state
becomes 3, i.e. the zone is ready for character
output by means of the procedures writefield,
write, outtext, etc.
E_x_a_m_p_l_e_ _1_: The following procedure sends the number of sound
alarms specified by the parameter no:
procedure beep (z, dest, no);
zone z ;
integer dest, no ;
begin integer i, state;
getstate (z, state);
if state = 3 then closetrans (z);
for i:= 1 step until no do
begin
opentrans (z, 3<*write format*', dest,
49<*write*', 1 shift 2 <*sound*');
closetrans(z);
end;
if state =3 then
opentrans (z, 3<*write format*', dest,
49<*write*', 1<*reset MDT bits*');
end beep;
E_x_a_m_p_l_e_ _2_: See example 3 of writefield.
\f
\f
i
T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_
1. INTRODUCTION ........................................... 1
2. THE FRONT PROCESS ADAPTOR .............................. 2
3. FDLC PROTOCOL CHARACTERISTICS .......................... 4
3.1 Transmission Elements ............................. 4
3.2 Error Detection and Correction .................... 4
3.3 Transmission Unit Identification .................. 4
4. PROTOCOL FORMAT SPECIFICATIONS ......................... 5
4.1 Startbyte ......................................... 5
4.2 Statusbyte ........................................ 5
4.3 Textblocks ........................................ 6
4.4 Master Clear ...................................... 6
5. PROTOCOL PROCEDURES SPECIFICATIONS ..................... 7
5.1 Flow Control ...................................... 7
5.2 Initialization .................................... 8
5.3 Error Detection and Correction .................... 8
5.4 Transmission Unit Numbering ....................... 9
5.5 Standard Operation of the Transmitter ............. 9
5.6 Error Actions of the Transmitter .................. 10
5.7 Standard Operation of the Receiver ................ 10
5.8 Error Reactions of the Receiver ................... 11
A_P_P_E_N_D_I_X_:
A. REFERENCES ............................................. 13
\f
ii
\f
1_._ _ _ _ _ _ _ _ _I_N_T_R_O_D_U_C_T_I_O_N_ 1.
This manual describes a communication line protocol, the FDLC-
protocol (F_PA D_ata L_ink C_ontrol), which is used in CENTERNET to
connect the RC8000 host with the RC3502 TC. The protocol is a
subset of the FDLC-protocol described in ref. 5.
The FPA is a high-speed, 8-bit parallel data communication line.
When initated, a transfer may proceed with a speed of up to
600.000 bytes per second. Interfaces exist to FPA-lines on
RC8000, RC3600 and RC3500 series of computers.
In the network hierarchy of protocol levels generally used in
international standards, the FDLC is a level 2 protocol. Thus it
functionally corresponds to the HDLC or the X25.2 protocol.
Being a reference manual, this description only defines the for-
mats and procedures to be followed on the line. Thus this de-
scription is independent of the computers actually involved.
However, the presence of an FDLC-handler module in the computers
is assumed. This module implements the FDLC-protocol on the FPA-
line and offers a computer-type-dependent interface to user-mo-
dules.
\f
F_ 2_._ _ _ _ _ _ _ _ _T_H_E_ _F_R_O_N_T_ _P_R_O_C_E_S_S_ _A_D_A_P_T_O_R_ 2.
The communication between the computers is carried out using an
FPA-connection (Front Process Adaptor). Fig. 1 shows an FPA-con-
nection seen from a logical point of view.
Figure 1: The logical structure of the FPA-connection.
The FPA consists of two subdevices - a transmitter and a
receiver. These two devices are totally independent of each
other.
The FPA transmitter can execute the following tasks:
- it can transmit a data block of any size to the receiver
- it can receive one single byte - normally holding status
information
- it can transfer a reset signal which, in case the receiver is
waiting for data, will stop the receiver immediately
\f
- it can transfer an autoload signal, which will activate the
autoload function of the computer on which the receiving FPA is
situated.
The FPA receiver is able to execute the following tasks:
- it can be set up for reception of any data block
- it can transmit one single byte to the transmitting end of
line.
An FPA-connection between two computers can be regarded as a pair
of independent simplex-lines with a low-volume return channel.
Both computers have two channels, a transmitter channel and a
receiver channel.
A detailed description of the FPA hardware used on RC8000, RC3600
and RC3500 can be found in ref. 1, 2, 3, 4.
\f
F_ 3_._ _ _ _ _ _ _ _ _F_D_L_C_ _P_R_O_T_O_C_O_L_ _C_H_A_R_A_C_T_E_R_I_S_T_I_C_S_ 3.
This chapter gives an overview of the FDLC-protocol and defines
the elements of the protocol. Details of formats and procedures
are found in the following chapter.
3_._1_ _ _ _ _ _ _ _T_r_a_n_s_m_i_s_s_i_o_n_ _E_l_e_m_e_n_t_s_ 3.1
The protocol is based on the exchange of T_r_a_n_s_m_i_s_s_i_o_n_ _U_n_i_t_s_ _(_T_U_)_.
A TU consists of a s_t_a_r_t_b_y_t_e_ followed by a number (at least one)
of d_a_t_a_ _b_y_t_e_s_. The receiver of a TU will return a s_t_a_t_u_s_b_y_t_e_
which specifies the result of the transfer and indicates that the
receiver is ready for the next transfer.
The FPA-connection may be regarded as two independent communica-
tion channels (one for each direction). Each channel is unidirec-
tional but with a l_o_w_-_v_o_l_u_m_e_ return channel, which is used to re-
turn the statusbytes.
The startbyte, databytes and the statusbyte each occupy 8 bits.
3_._2_ _ _ _ _ _ _ _E_r_r_o_r_ _D_e_t_e_c_t_i_o_n_ _a_n_d_ _C_o_r_r_e_c_t_i_o_n_ 3.2
Error detection is based on a parity checking mechanism. The FPAs
will add a parity-bit to each transmitted byte. The parity is
checked by the receiving FPA and an error will be reported.
Error correction is based on retransmission of the erroneous TU.
3_._3_ _ _ _ _ _ _ _T_r_a_n_s_m_i_s_s_t_i_o_n_ _U_n_i_t_ _I_d_e_n_t_i_f_i_c_a_t_i_o_n_ 3.3
Retransmission of a TU is detected by a TU-number which is added
to each TU. This number counts modulo 2, which means that only
one TU may be outstanding waiting for acknowledge.
\f
F_ 4_._ _ _ _ _ _ _ _ _P_R_O_T_O_C_O_L_ _F_O_R_M_A_T_ _S_P_E_C_I_F_I_C_A_T_I_O_N_S_ 4.
This presents the formats used for the various transmission
elements.
4_._1_ _ _ _ _ _ _ _S_t_a_r_t_b_y_t_e_ 4.1
All Transmission Units are preceded by a startbyte. It contains
the following information:
0 1 2 3 4 5 6 7
0 0 0 0 0
TU _NUMBER
TYPE
TU _NUMBER: is a modulo 2 sequence number as described in
section 3.3.
TYPE : 0 Text block
1 Not used
2 Master clear
3 Not used
4_._2_ _ _ _ _ _ _ _S_t_a_t_u_s_b_y_t_e_ 4.2
A statusbyte is returned, when a TU has been received. It
indicates whether the TU was received correctly or whether an
error occured.
A statusbyte has the following format:
0 1 2 3 4 5 6 7
0 0 0 0 0 0
PARITY ERROR
BLOCK SIZE ERROR
\f
P_a_r_i_t_y_ _e_r_r_o_r_ indicates that the parity checking mechanism
indicated an error for at least one of the characters received.
B_l_o_c_k_ _s_i_z_e_ _e_r_r_o_r_ indicates an overflow in the user buffer, in
which the textblock should be stored.
The statusbyte should have initial value = 255, see section 5.4.
4_._3_ _ _ _ _ _ _ _T_e_x_t_b_l_o_c_k_s_ 4.3
Textblocks are used to exchange information between the users of
the FDLC-protocol. The datapart of a textblock is solely defined
by the user and the bytes in the datapart may take any value from
0 to 255.
4_._4_ _ _ _ _ _ _ _M_a_s_t_e_r_ _C_l_e_a_r_ 4.4
A master clear block is used to synchronize the two ends of the
transmission line. It is used after initial load or after an
irrecoverable error. The master clear block carries no data and
consists solely of a startbyte.
The master clear startbyte will have:
TU _NUMBER = 0
TYPE = 2
\f
F_ 5_._ _ _ _ _ _ _ _ _P_R_O_T_O_C_O_L_ _P_R_O_C_E_D_U_R_E_S_ _S_P_E_C_I_F_I_C_A_T_I_O_N_S_ 5.
This chapter presents the procedures that are to be followed by
the FDLC-handlers.
5_._1_ _ _ _ _ _ _ _F_l_o_w_ _C_o_n_t_r_o_l_ 5.1
Due to the characteristics of the line and the intended use of
the protocol, only a rather simple method of flowcontrol is
implemented.
The flowcontrol is based on the assumption that the users of the
protocol should in general always assure that a buffer is ready
in which to receive data. If a buffer is not always present, the
time in which the F_D_L_C_-_h_a_n_d_l_e_r_ is without a buffer should be
short compared to the time-out period after which retransmission
will take place.
The flowcontrol is implemented by means of the statusbytes in the
following manner:
A statusbyte is not returned until a buffer is ready for
reception of a new (or retransmitted) TU.
This means that if the FDLC-handler receives a textblock into the
last buffer from the user, it will not return the statusbyte
until a new buffer is present.
In case this exceeds the timeout value of the transmitter, a re-
transmission, will take place. This will, until a buffer is
ready, terminate immediately because no input operation is pre-
sent at the receiving end.
\f
5_._2_ _ _ _ _ _ _ _I_n_i_t_i_a_l_i_z_a_t_i_o_n_ 5.2
During initialization, the FPA-connection is regarded as a pair
of totally independant lines, one for each direction.
The lines are initialized during initial start up or after an
irrecoverable error. The initiative for initialization always
rests with the transmitting end of the line.
If the receive part of an FDLC-handler receives a master clear
startbyte, it should perform the clean up actions necessary and
return a statusbyte = 0 (ok), indicating that the receive part is
ready to operate.
When the transmit part of an FDLC-handler wants to initialize the
line, it should transmit a master clear startbyte. If a status-
byte = 0 has not been received within a certain time interval,
the master clear startbyte should be retransmitted. Having re-
ceived the statusbyte (and assuming no error indications) the
transmit part is ready to operate.
During initial start up of the two FDLC-handlers, the initial-
ization described above is performed for both directions. If an
irrecoverable error has been detected by only one of the FLDC-
handlers or if one of the FDLC-handlers has been restarted, the
initialization need only be performed for the direction in-
volved.
5_._3_ _ _ _ _ _ _ _E_r_r_o_r_ _D_e_t_e_c_t_i_o_n_ _a_n_d_ _C_o_r_r_e_c_t_i_o_n_ 5.3
Error detection is based on a parity checking mechanism. For each
transmitted byte, the FPA will generate a parity bit, which is
transmitted along with the byte. If the receiving FPA detects a
parity error, it will indicate this in a hardware status.
In this case a statusbyte which contains the PARITY ERROR-bit
should be returned and the TU will be retransmitted.
\f
5_._4_ _ _ _ _ _ _ _T_r_a_n_s_m_i_s_s_i_o_n_ _U_n_i_t_ _N_u_m_b_e_r_i_n_g_ 5.4
All TU's are numbered. The TU-number counts modulo 2. The first
TU transmitted after initalization has a TU-number of 1.
The transmitter and receiver will each maintain its version of a
TU-counter.
The TU-counter in the transmitter holds the number of the next TU
that is going to be transmitted or is during transmission. The
TU-counter is increased by 1 (modulo 2) each time a statusbyte
without errorindication has been received. When a TU is trans-
mitted or retransmitted, the current value of the TU-counter is
inserted as TU-number in the startbyte.
The TU-counter in the receiver holds the TU-number that is ex-
pected in the next TU. It is increased by 1 (modulo 2), when a TU
with this expected TU-number has been received without error. If
a TU is received with a TU-number different from what is expected
(and it is not a master clear block), the block is ignored and
the last statusbyte is transmitted again.
The statusbyte does not itself include any TU-number because it
will always refer to the TU just received. However, the initial
value of statusbyte is used to signal to the transmitting end of
the line if a TU-number mismatch has occurred at the receiving
end, due to restart of the local FDLC-handler. Therefore, the
initial value of statusbyte should be 255. If a statusbyte hold-
ing this value is received, this indicates that the TU-counter
should be increased by 1 (modulo 2) before retransmission.
5_._5_ _ _ _ _ _ _ _S_t_a_n_d_a_r_d_ _O_p_e_r_a_t_i_o_n_ _o_f_ _t_h_e_ _T_r_a_n_s_m_i_t_t_e_r_ 5.5
The transmitter is the active part in the communication. Its
normal working cycle consists of a transmission of a TU, headed
by the startbyte after which the transmitter waits to receive the
statusbyte.
\f
Now the transfer is checked by inspecting partly the hardware
status from the transmission, partly the received statusbyte. If
no errors are indicated, the TU-counter is increased.
The operation must terminate within a certain time, if necessary
by means of a software timer.
The FPA-connection will very seldom cause errors to be imposed on
the transmitted data except in case of permanent hardware errors.
Therefore the timeout value may be rather big and it should be
set to 5 seconds.
5_._6_ _ _ _ _ _ _ _E_r_r_o_r_ _A_c_t_i_o_n_s_ _o_f_ _t_h_e_ _T_r_a_n_s_m_i_t_t_e_r_ 5.6
The standard error action is to retransmit the TU. In order to
force the receiver into a well defined state, the retransmission
must be initated by transmission of a reset signal. This will
terminate a possible input operation at the receiver. After
transmission of the reset signal, the transmitter must wait at
least 50 msec. to allow the receiver to prepare a new input
operation. Then the transmit-operation is repeated.
The FPA-line must be initialized if the same block has been
transmitted 5 times without success.
5_._7_ _ _ _ _ _ _ _S_t_a_n_d_a_r_d_ _O_p_e_r_a_t_i_o_n_ _o_f_ _t_h_e_ _R_e_c_e_i_v_e_r_ 5.7
The receiver is the passive part in the transmission. Having
received a TU, the receiver checks the hardware status for parity
errors or blocklength errors, and generates the appropriate
statusbyte. Then the statusbyte is returned and a new receive
operation issued.
\f
5_._8_ _ _ _ _ _ _ _E_r_r_o_r_ _R_e_a_c_t_i_o_n_s_ _o_f_ _t_h_e_ _R_e_c_e_i_v_e_r_ 5.8
Parity error in block received:
set PARITY ERROR in statusbyte
transmit statusbyte - receive new TU
Wrong TU-number in TU:
ignore block arrived
transmit old statusbyte - receive new TU
Blocklength error:
Set BLOCK SIZE ERROR in statusbyte
transmit statusbyte - receive new TU
Master clear received
Initialize the FPA-line
Any other error situation
Receive new TU
The receiver should keep on repeating the operation, because the
decision of whether to give up is placed at the transmitter.
\f
F_
\f
F_ A_._ _ _ _ _ _ _ _ _R_E_F_E_R_E_N_C_E_S_ A.
1 FPA 801, RC8000
2 FPA 705, RC3600
3 FPA 707, RC3600
4 FPA 100, RC3500
5 RCSL No 43-GL7810:
RCNET, FDLC-FPA Data Line Control
Erik Lilholt
\f
F_
\f
«eof»