
129
Chapter 2 Applications Programming
preparation code required for Freeze mode C level handlers. High C 29K uses global
registers in the
gr96–gr111
range as temporaries before starting to use g
r116–gr120
.
The reduced use of global registers might make GCC a better choice for building
Freeze mode C–level interrupt handlers.
The assembler, as29, supplied with the GCC compiler chain does not support
macros directly. But it is possible to use the C preprocessor, CPP, to do macro instruc-
tion expansion. The
interrupt_cache
macro shown below demonstrates the use of
CPP with 29K assembly code. The macro is used to install a C handler for the selected
trap_number
. The early part of the macro code requests the HIF
settrap
service be
used to insert the interrupt handler address into the processor vector table. The actual
address inserted depends on the register usage of the C handler.
The handler must be examined to determine the registers used. Parameter
nregs
is used to specify the number of registers used in the
gr116–gr120
range. The handler
preparation code saves the necessary global registers in an interrupt context cache
before calling the C code. Global registers
gr96–gr111
are not saved in the cache, as it
is likely that they are not used by the handler –– it certainly has no return value.
The context cache is formed with global registers
gr64–gr80
. Registers
gr64–gr79
are used by floating–point emulation routines, and hence their contents
are available for use between floating–point trap instructions. This assumes that the
trapware runs with interrupts turned off which is normally the case. For more details
see section 2.5. Saving the registers used by the handler in this way is much faster
than pushing the registers onto an off–chip memory stack.
#define interrupt_cache(trap_number, C_handler, nregs)\
;start of interrupt_cache macro, nregs must be >=1 _CR_\
nop
;delay slot protection _CR_\
sub
gr1,gr1,4*4
;get lr0–lr3 space _CR_\
asgeu
V_SPILL,gr1,rab ;check for stack spill _CR_\
add
lr1,gr121,0
;save gr121 _CR_\
add
lr0,gr96,0
;save gr96 _CR_\
const
gr121,290
;HIF 2.0 SETTRAP service _CR_\
const
lr2,trap_number ;trap number, macro parameter_CR_\
const
lr3,cache_##trap_number–(nregs*4) ;handler adds._CR_\
consth
lr3,cache_##trap_number–(nregs*4) ; _CR_\
asneq
69,gr1,gr1
;HIF service request _CR_\
add
gr121,lr1,0
;restore gr121 _CR_\
add
gr96,lr0,0
;restore gr96 _CR_\
add
gr1,gr1,4*4
;restore stack _CR_\
jmp
cache_end_##trap_number ;install code finished _CR_
asleu
V_FILL,lr1,rfb
;check for stack fill _CR_\
;START of
interrupt handler
code_CR_\
;save gr120 _CR_\
;save gr119 _CR_\
;save gr118 _CR_\
;save gr117 _CR_\
;save lr0 _CR_\
;gr96–gr111 not saved in cache _CR_\
add
add
add
add
add
gr70,gr120,0
gr69,gr119,0
gr68,gr118,0
gr67,gr117,0
gr64,lr0,0
cache_##trap_number: