1993-03-30 15:43:44 +00:00
|
|
|
.bp
|
|
|
|
.P1 "TRAPS AND INTERRUPTS"
|
|
|
|
.PP
|
1986-02-04 17:37:41 +00:00
|
|
|
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.
|
1993-03-30 15:43:44 +00:00
|
|
|
.PP
|
1990-02-05 10:06:42 +00:00
|
|
|
The action taken when a trap occurs is determined by the value
|
1986-02-04 17:37:41 +00:00
|
|
|
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.
|
1993-03-30 15:43:44 +00:00
|
|
|
.PP
|
1986-02-04 17:37:41 +00:00
|
|
|
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.
|
1993-03-30 15:43:44 +00:00
|
|
|
.br
|
1986-02-04 17:37:41 +00:00
|
|
|
If the bit is 0, traps are not ignored.
|
|
|
|
The instructions LIM and SIM allow copying and replacement of
|
|
|
|
the ignore mask.~
|
1993-03-30 15:43:44 +00:00
|
|
|
.PP
|
1986-02-04 17:37:41 +00:00
|
|
|
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).
|
1993-03-30 15:43:44 +00:00
|
|
|
.PP
|
1986-02-04 17:37:41 +00:00
|
|
|
The RTT instruction returns from the trap procedure and continues after the
|
|
|
|
trap.
|
|
|
|
In the list below all traps marked with an asterisk ('*') are
|
1991-11-19 13:19:02 +00:00
|
|
|
considered to be fatal and it is explicitly undefined what happens when
|
|
|
|
restarting after the trap.
|
1993-03-30 15:43:44 +00:00
|
|
|
.PP
|
1986-02-04 17:37:41 +00:00
|
|
|
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:
|
1993-03-30 15:43:44 +00:00
|
|
|
.IP "\0\00\-\063" 12
|
1986-02-04 17:37:41 +00:00
|
|
|
EM machine errors, e.g. illegal instruction.
|
1993-03-30 15:43:44 +00:00
|
|
|
.RS
|
|
|
|
.IP "\00\-15" 8
|
1986-02-04 17:37:41 +00:00
|
|
|
maskable
|
1993-03-30 15:43:44 +00:00
|
|
|
.IP "16\-63" 8
|
1986-02-04 17:37:41 +00:00
|
|
|
not maskable
|
1993-03-30 15:43:44 +00:00
|
|
|
.RE
|
|
|
|
.IP "\064\-127" 12
|
1986-02-04 17:37:41 +00:00
|
|
|
Reserved for use by compilers, run time systems, etc.
|
1993-03-30 15:43:44 +00:00
|
|
|
.IP "128\-252" 12
|
1986-02-04 17:37:41 +00:00
|
|
|
Available for user programs.
|
1993-03-30 15:43:44 +00:00
|
|
|
.LP
|
1986-02-04 17:37:41 +00:00
|
|
|
EM machine errors are numbered as follows:
|
|
|
|
.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
|
1988-04-11 10:29:59 +00:00
|
|
|
17@EHEAP@Heap overflow
|
1986-02-04 17:37:41 +00:00
|
|
|
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
|
1993-03-30 15:43:44 +00:00
|
|
|
.PP
|
1986-02-04 17:37:41 +00:00
|
|
|
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:
|
1993-03-30 15:43:44 +00:00
|
|
|
.LP
|
|
|
|
.KS
|
|
|
|
.nf
|
1986-02-04 17:37:41 +00:00
|
|
|
.ta 1n 24n
|
|
|
|
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
|
|
|
|
|
1990-02-05 10:06:42 +00:00
|
|
|
pro $calcule,0 ; entry point
|
1986-02-04 17:37:41 +00:00
|
|
|
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
|
1993-03-30 15:43:44 +00:00
|
|
|
.KE
|
|
|
|
.KS
|
|
|
|
.LP
|
1986-02-04 17:37:41 +00:00
|
|
|
Example of catch procedure
|
1993-03-30 15:43:44 +00:00
|
|
|
.LP
|
|
|
|
.nf
|
1986-02-04 17:37:41 +00:00
|
|
|
.ta 1n 24n
|
1990-02-05 10:06:42 +00:00
|
|
|
pro $catch,0 ; Local procedure that must catch the overflow trap
|
1986-02-04 17:37:41 +00:00
|
|
|
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
|
1993-03-30 15:43:44 +00:00
|
|
|
.KE
|
|
|
|
.fi
|