171 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
.SN 9
 | 
						|
.VS 1 0
 | 
						|
.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
 | 
						|
.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
 | 
						|
 | 
						|
	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
 | 
						|
.ta 1n 24n
 | 
						|
	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
 |