Application Notes
Holon 11 Monitors
Handling Interrupts
Using the Real Time Kernel
Memory Banks

Holon 11 Interrupt Service Routines

An interrupt service routine (ISR) is a subroutine that is called by an event instead of the program. ISRs run in parallel to your program. This is very elegant, but the elegance comes at a price. You must take care of several steps.  

With Holon 11 you can implement and test all steps separately. This is probably best seen  with an example. I assume that you are using Holon 11 with the monitor PMON on the target system, and consider the monitors EMON and IMON later. 

Example  (PMON)

The example presents a simple interrupt service routine for the real time interrupt (RTI) of the internal 68HC11 timer. The routine increments memory location $100. Holon 11 lets you watch the memory of a running program, and you can see the RTI in action. 

     inc $100  
     ldaa # $40 staa TFLG2           \ clear this RTI event

An interrupt service routine ends with the instruction rti (return from interrupt) instead of rts (return from subroutine). Connect the routine with the event and enable the source of the RTI. When a real time interrupt occurs, the CPU jumps to the location that is contained in the RTI vector located at vRTI =$FFF0. The RTI is enabled, when the RTII bit in the 68HC11 register TMSK2 is set to one.

: SetRTI
     RTI-IRS vRTI  !                        \ set interrupt vector
     2 PACTL c!                            \ set RTI period = 16 ms
     $40 TMSK2 c!                        \ set RTII in TMSK2, enable RTI

Load the code and execute the word SetRTI. See the contents of memory location $100  change (press F6, then Alt+F6 and enter the address 100. Be sure to see the target memory - press T)


Testing the ISR

The example is very simple and it will probably run. However, in the general case it is nice to be able to test every step. Here's how Holon 11 helps you.

Interrupt service routine

Does the ISR do what you intended?

Interrupt vector

Is the interrupt vector set correctly?

You can also set the interrupt vector interactively at the command line. Go to test mode (Ctl+F4) and enter the command RTI-ISR  vRTI  ! .

Interrupts enabled

Are the interrupts enabled in the CPU?

Interrupt source enabled

Is the interrupt source enabled? Most interrupt sources are masked and must be enabled individually.

Interrupt source acknowledged

Is the interrupt acknowledged? The interrupt source must learn that the IRQ has been serviced, otherwise the IRQ stays pending. The interrupt is acknowledged in the ISR.  Every source has its own rules, typically: read a register, set or clear a flag. 

If the RTI-IRQ doesn't set this bit, a new RTI occurs instantly. The program spends the rest of its life in the RTI service routine. You can only stop it with a reset of the target system.

Interrupts and EMON

The monitor EMON operates in the internal EEPROM at $FF00 ff. This means that the interrupt vector space is in EEPROM and you can't simply write to the RTI vector here. It is possible to write into EEPROM, but EMON offers another solution. The interrupt vectors in EMON are redirected to a table of pseudo-vectors in the internal system RAM. A pseudo- vector consists of the opcode JMP and the address of the ISR.The RTI is directed to location evRTI=$3F1. The word SetRTI now inserts a JMP to the RTI-ISR at this pseudo-vector location.

: SetRTI
     $7E evRTI c!  RTI-ISR evRTI 1+  !
     2 PACTL c!                            \ set RTI period = 16 ms
     $40 TMSK2 c!                        \ set RTII in TMSK2

Interrupts and IMON

The example does not work with the monitor IMON, because IMON runs with interrupts disabled. You can use interrupts in your application, but you can't watch the memory while your program runs.  However, you can watch external signals. For example generate a short pulse on bit 0 of port A and watch it with a logic probe.

     ldaa PORTA  anda # $FE  staa PORTA   ora # $01   staa PORTA 
     ldaa # $40  staa TFLG2       

Now create and run a simple program that is interrupted by the RTI, say, an infinite loop. 

: main
1 DDRA c!                      \ turn PORTA bit 0 into an output
     begin  again ;

When you start the program from the monitor, interrupts are enabled. Therefore you should now detect pulses on port A/0.   

Reset the target system to return control to the host (this is only needed with IMON, because the communication is polled. The monitor is offline while the user program runs.)


We also must be able to set an interrupt vector without activating target code. Holon 11 provides the compiler directive SetVector. Example:

( Set_RTI_vector )
       RTI-ISR  vRTI  SetVector

When you load this script, the host writes the ISR address in the vector location in target memory. (A script is a Holon word that is interpreted when loaded. The name of the script is written in parentheses and the compiler ignores it.)

Assembler applications

You can create pure assembler programs in Holon 11. The monitors IMON, PMON and EMON are assembler applications that are written in Holon 11. 

In an assembler program replace the word SetRTI by the equivalent code in assembler.