.SN 8
.VS 1 0
.BP
.S1 "ENVIRONMENT INTERACTIONS"
EM programs can interact with their environment in three ways.
Two, starting/stopping and monitor calls, are dealt with in this chapter.
The remaining way to interact, interrupts, will be treated
together with traps in chapter 9.
.S2 "Program starting and stopping"
EM user programs start with a call to a procedure called
m_a_i_n.
The assembler and backends look for the definition of a procedure
with this name in their input.
The call passes three parameters to the procedure.
The parameters are similar to the parameters supplied by the
UNIX
.FS
UNIX is a Trademark of Bell Laboratories.
.FE
operating system to C programs.
These parameters are often called
.BW argc ,
.B argv
and
.BW envp .
Argc is the parameter nearest to LB and is a wordsized integer.
The other two are pointers to the first element of an array of
string pointers.
.N
The
.B argv
array contains
.B argc
strings, the first of which contains the program call name.
The other strings in the
.B argv
array are the program parameters.
.P
The
.B envp
array contains strings in the form "name=string", where 'name'
is the name of an environment variable and string its value.
The
.B envp
is terminated by a zero pointer.
.P
An EM user program stops if the program returns from the first
invocation of m_a_i_n.
The contents of the function return area are used to procure a
wordsized program return code.
EM programs also stop when traps and interrupts occur that are
not caught and when the exit monitor call is executed.
.S2 "Input/Output and other monitor calls"
EM differs from most conventional machines in that it has high level i/o
instructions.
Typical instructions are OPEN FILE and READ FROM FILE instead
of low level instructions such as setting and clearing
bits in device registers.
By providing such high level i/o primitives, the task of implementing
EM on various non EM machines is made considerably easier.
.P
I/O is initiated by the MON instruction, which expects an iocode on top
of the stack.
Often there are also parameters which are pushed on the
stack in reverse order, that is: last
parameter first.
Some i/o functions also provide results, which are returned on the stack.
In the list of monitor calls we use several types of parameters and results,
these types consist of integers and unsigneds of varying sizes, but never
smaller than the wordsize, and the two pointer types.
.N 1
The names of the types used are:
.IS 4
.PS - 10
.PT int
an integer of wordsize
.PT int2
an integer whose size is the maximum of the wordsize and 2
bytes
.PT int4
an integer whose size is the maximum of the wordsize and 4
bytes
.PT intp
an integer with the size of a pointer
.PT uns2
an unsigned integer whose size is the maximum of the wordsize and 2
.PT unsp
an unsigned integer with the size of a pointer
.PT ptr
a pointer into data space
.PE 1
.IE 0
The table below lists the i/o codes with their results and
parameters.
This list is similar to the system calls of the UNIX Version 7
operating system.
.BP
.A
To execute a monitor call, proceed as follows:
.IS 2
.N 1
.PS a 4 "" )
.PT
Stack the parameters, in reverse order, last parameter first.
.PT
Push the monitor call number (iocode) onto the stack.
.PT
Execute the MON instruction.
.PE 1
.IE
An error code is present on the top of the stack after
execution of most monitor calls.
If this error code is zero, the call performed the action
requested and the results are available on top of the stack.
Non-zero error codes indicate a failure, in this case no
results are available and the error code has been pushed twice.
This construction enables programs to test for failure with a
single instruction (~TEQ or TNE~) and still find out the cause of
the failure.
The result name 'e' is reserved for the error code.
.N 1
List of monitor calls.
.DS B
number name    parameters      results           function

   1   Exit    status:int                        Terminate this process
   2   Fork                    e,flag,pid:int    Spawn new process
   3   Read    fildes:int;buf:ptr;nbytes:unsp
                               e:int;rbytes:unsp Read from file
   4   Write   fildes:int;buf:ptr;nbytes:unsp
                               e:int;wbytes:unsp Write on a file
   5   Open    string:ptr;flag:int
                               e,fildes:int      Open file for read and/or write
   6   Close   fildes:int      e:int             Close a file
   7   Wait                    e:int;status,pid:int2
                                                 Wait for child
   8   Creat   string:ptr;mode:int
                               e,fildes:int      Create a new file
   9   Link    string1,string2:ptr
                               e:int             Link to a file
  10   Unlink  string:ptr      e:int             Remove directory entry
  12   Chdir   string:ptr      e:int             Change default directory
  14   Mknod   string:ptr;mode,addr:int2
                               e:int             Make a special file
  15   Chmod   string:ptr;mode:int2
                               e:int             Change mode of file
  16   Chown   string:ptr;owner,group:int2
                               e:int             Change owner/group of a file
  18   Stat    string,statbuf:ptr
                               e:int             Get file status
  19   Lseek   fildes:int;off:int4;whence:int
                               e:int;oldoff:int4 Move read/write pointer
  20   Getpid                  pid:int2          Get process identification
  21   Mount   special,string:ptr;rwflag:int
                               e:int             Mount file system
  22   Umount  special:ptr     e:int             Unmount file system
  23   Setuid  userid:int2     e:int             Set user ID
  24   Getuid                  e_uid,r_uid:int2  Get user ID
  25   Stime   time:int4       e:int             Set time and date
  26   Ptrace  request:int;pid:int2;addr:ptr;data:int
                               e,value:int       Process trace
  27   Alarm   seconds:uns2    previous:uns2     Schedule signal
  28   Fstat   fildes:int;statbuf:ptr
                               e:int             Get file status
  29   Pause                                     Stop until signal
  30   Utime   string,timep:ptr
                               e:int             Set file times
  33   Access  string,mode:int e:int             Determine file accessibility
  34   Nice    incr:int                          Set program priority
  35   Ftime   bufp:ptr        e:int             Get date and time
  36   Sync                                      Update filesystem
  37   Kill    pid:int2;sig:int
                               e:int             Send signal to a process
  41   Dup     fildes,newfildes:int
                               e,fildes:int      Duplicate a file descriptor
  42   Pipe                    e,w_des,r_des:int Create a pipe
  43   Times   buffer:ptr                        Get process times
  44   Profil  buff:ptr;bufsiz,offset,scale:intp Execution time profile
  46   Setgid  gid:int2        e:int             Set group ID
  47   Getgid                  e_gid,r_gid:int   Get group ID
  48   Sigtrp  trapno,signo:int
                               e,prevtrap:int    See below
  51   Acct    file:ptr        e:int             Turn accounting on or off
  53   Lock    flag:int        e:int             Lock a process
  54   Ioctl   fildes,request:int;argp:ptr
                               e:int             Control device
  56   Mpxcall cmd:int;vec:ptr e:int             Multiplexed file handling
  59   Exece   name,argv,envp:ptr
                               e:int             Execute a file
  60   Umask   complmode:int2  oldmask:int2      Set file creation mode mask
  61   Chroot  string:ptr      e:int             Change root directory
.DE 1
Codes 0, 11, 13, 17, 31, 32, 38, 39, 40, 45, 49, 50, 52,
55, 57, 58, 62, and 63 are
not used.
.P
All monitor calls, except fork and sigtrp
are the same as the UNIX version 7 system calls.
.P
The sigtrp entry maps UNIX signals onto EM interrupts.
Normally, trapno is in the range 0 to 252.
In that case it requests that signal signo
will cause trap trapno to occur.
When given trap number -2, default signal handling is reset, and when given
trap number -3, the signal is ignored.
.P
The flag returned by fork is 1 in the child process and 0 in
the parent.
The pid returned is the process-id of the other process.
.BP
.S1 "TRAPS AND INTERRUPTS"
EM provides a means for the user program to catch all traps
generated by the program itself, the hardware, or external conditions.
This mechanism uses five instructions: LIM, SIM, SIG, TRP and RTT.
This section of the manual may be omitted on the first reading since it
presupposes knowledge of the EM instruction set.
.P
The action taken when a trap occures is determined by the value
of an internal EM trap register.
This register contains a pointer to a procedure.
Initially the pointer used is zero and all traps halt the
program with, hopefully, a useful message to the outside world.
The SIG instruction can be used to alter the trap register,
it pops a procedure pointer from the
stack into the trap register.
When a trap occurs after storing a nonzero value in the trap
register, the procedure pointed to by the trap register
is called with the trap number
as the only parameter (see below).
SIG returns the previous value of the trap register on the
stack.
Two consecutive SIGs are a no-op.
When a trap occurs, the trap register is reset to its initial
condition, to prevent recursive traps from hanging the machine up,
e.g. stack overflow in the stack overflow handling procedure.
.P
The runtime systems for some languages need to ignore some EM
traps.
EM offers a feature called the ignore mask.
It contains one bit for each of the lowest 16 trap numbers.
The bits are numbered 0 to 15, with the least significant bit
having number 0.
If a certain bit is 1 the corresponding trap never
occurs and processing simply continues.
The actions performed by the offending instruction are
described by the Pascal program in appendix A.
.N
If the bit is 0, traps are not ignored.
The instructions LIM and SIM allow copying and replacement of
the ignore mask.~
.P
The TRP instruction generates a trap, the trap number being found on the
stack.
This is, among other things,
useful for library procedures and runtime systems.
It can also be used by a low level trap procedure to pass the trap to a
higher level one (see example below).
.P
The RTT instruction returns from the trap procedure and continues after the
trap.
In the list below all traps marked with an asterisk ('*') are
considered to be fatal and it is explicitly undefined what happens if
you try to restart after the trap.
.P
The way a trap procedure is called is completely compatible
with normal calling conventions. The only way a trap procedure
differs from normal procedures is the return. It has to use RTT instead
of RET. This is necessary because the complete runtime status is saved on the
stack before calling the procedure and all this status has to be reloaded.
Error numbers are in the range 0 to 252.
The trap numbers are divided into three categories:
.IS 4
.N 1
.PS - 10
.PT ~~0-~63
EM machine errors, e.g. illegal instruction.
.PS - 8
.PT ~0-15
maskable
.PT 16-63
not maskable
.PE
.PT ~64-127
Reserved for use by compilers, run time systems, etc.
.PT 128-252
Available for user programs.
.PE 1
.IE
EM machine errors are numbered as follows:
.DS I 5
.TS
tab(@);
n l l.
0@EARRAY@Array bound error
1@ERANGE@Range bound error
2@ESET@Set bound error
3@EIOVFL@Integer overflow
4@EFOVFL@Floating overflow
5@EFUNFL@Floating underflow
6@EIDIVZ@Divide by 0
7@EFDIVZ@Divide by 0.0
8@EIUND@Undefined integer
9@EFUND@Undefined float
10@ECONV@Conversion error
16*@ESTACK@Stack overflow
17*@EHEAP@Heap overflow
18*@EILLINS@Illegal instruction
19*@EODDZ@Illegal size argument
20*@ECASE@Case error
21*@EMEMFLT@Addressing non existent memory
22*@EBADPTR@Bad pointer used
23*@EBADPC@Program counter out of range
24@EBADLAE@Bad argument of LAE
25@EBADMON@Bad monitor call
26@EBADLIN@Argument of LIN too high
27@EBADGTO@GTO descriptor error
.TE
.DE 0
.P
As an example,
suppose a subprocedure has to be written to do a numeric
calculation.
When an overflow occurs the computation has to be stopped and
the higher level procedure must be resumed.
This can be programmed as follows using the mechanism described above:
.DS B
 mes 2,2,2              ; set sizes
ersave
 bss 2,0,0              ; Room to save previous value of trap procedure
msave
 bss 2,0,0              ; Room to save previous value of trap mask

 pro calcule,0          ; entry point
 lxl 0                  ; fill in non-local goto descriptor with LB
 ste jmpbuf+4
 lor 1                  ; and SP
 ste jmpbuf+2
 lim                    ; get current ignore mask
 ste msave              ; save it
 lim
 loc 16                  ; bit for EFOVFL
 ior 2                  ; set in mask
 sim                    ; ignore EFOVFL from now on
 lpi $catch             ; load procedure identifier
 sig                    ; catch wil get all traps now
 ste ersave             ; save previous trap procedure identifier
; perform calculation now, possibly generating overflow
1                       ; label jumped to by catch procedure
 loe ersave             ; get old trap procedure
 sig                    ; refer all following trap to old procedure
 asp 2                  ; remove result of sig
 loe msave              ; restore previous mask
 sim                    ; done now
; load result of calculation
 ret 2                  ; return result
jmpbuf
 con *1,0,0
 end
.DE 0
.VS 1 1
.DS
Example of catch procedure
 pro catch,0            ; Local procedure that must catch the overflow trap
 lol 2                  ; Load trap number
 loc 4                  ; check for overflow
 bne *1                 ; if other trap, call higher trap procedure
 gto jmpbuf             ; return to procedure calcule
1                       ; other trap has occurred
 loe ersave             ; previous trap procedure
 sig                    ; other procedure will get the traps now
 asp 2                  ; remove the result of sig
 lol 2                  ; stack trap number
 trp                    ; call other trap procedure
 rtt                    ; if other procedure returns, do the same
 end
.DE
