; exceptions.h -- declarations applying to exceptions ; language: SMAL32 assembly language, intended as an include file ; author: Douglas W. Jones ; date: Jan 4, 2024 ; An exception record has 3 one-word fields EXHAND = 0 ; one word, points to the handler EXAR = 4 ; one word, points to the handler's activation record EXOLD = 8 ; one word, points to the previous exception record EXSIZE = 12 ; the size of an exception record, in bytes ; Exception pointers are words in RAM holding addresses of exception records. ; Normally, each exception pointer will be a global variable. ; Exceptions that may be raised by the hardware: ; Note: Each of these global variables is an exception pointer. ; By default, they are initialized to NULL. ; If NULL, on trap, the Hawk monitor will output a message and halt. ; If not NULL, on trap, the monitor will throw the indicated exception. EXT EXBUSTR ; bus trap -- illegal use of memory EXT EXINSTR ; instruction trap -- illegal instruction EXT EXEPRIV ; priv. trap -- CPUSET or CPUGET in user mode EXT EXECOPR ; coprocessor trap -- tried to use a missing one ; To create a user defined exception, allocate a one-word exception pointer. ; Note that on entry to an exception handler, nothing should be assumed ; about the value of any register except R2. That means that, before ; installing a handler, all important values must be saved in RAM. ; To install a handler in code following the standard Hawk calling conventions: ; a) Add a 3-word exception record as a local variable ; b) Make the EXHAND field point to the code of the desired handler ; c) Make the EXAR field hold the current activation record's address ; d) Make the EXOLD field hold the previous value of the exception pointer ; e) Make the exception pointer refer to the new exception record ; The following macro does steps b-e, assuming the exception pointer is global ; and that R1 and R3 are free. MACRO EXINSTALL =expointer, =exrecord, =handler LEA R1,handler STORE R1,R2,exrecord+EXHAND STORE R2,R2,exrecord+EXAR LIL R1,expointer LOADS R3,R1 STORE R3,R2,exrecord+EXOLD LEA R3,R2,exrecord STORES R3,R1 ENDMAC ; To deinstall a handler in the same context: ; a) Restore the exception pointer from the EXOLD field of the exception record ; The following macro does this, assuming the standard calling conventions ; and assuming R1 and R3 are both free. MACRO EXREMOVE =expointer, =exrecord LOAD R3,R2,exrecord+EXOLD LIL R1,expointer STORES R3,R1 ENDMAC ; To throw an exception ; a) Follow the exception pointer to the exception record ; b) Restore the exception pointer from the EXOLD field ; c) Load R2 from the EXAR field ; d) Load PC from the EXHAND field MACRO EXTHROW =expointer LIL R15,expointer LOADS R1,R15 LOAD R2,R1,EXOLD STORES R2,R15 LOAD R2,R1,EXAR LOADS PC,R1;EXHAND ENDMAC ; Note: The above macro preserves R3-14, allowing Java-style ; "parameters" to the handler to be passed when an exception is thrown. ; Note: Throwing an exception de-installs the handler ; This is important because when a trap is translated to throwing an ; exception, if the exception handler traps, we want that to be handled ; by the previous handler, not this one. If we didn't do this, the cpu ; would hang if a programmer installed an invalid handler for a trap. ; Note: When throwing an exception to a local handler, that is, throwing it ; within the bounds of the same routine that installed the handler, use ; EXREMOVE followed by BR to the handler instead of EXTHROW. This does ; the same thing using half as many machine instructions