**** 16C71 ****
Saving Registers When Interrupt Vectoring

One of the great advantages of using the 16C71 is the capability to generate
hardware interrupts. Vectoring to an interrupt instead of constantly polling
inputs, RTCC, etc. can really speed up your code. However, just as with
most microcontrollers, you MUST save any registers you use within the
interrupt routine!

The 16C71 doesn't have any built-in PUSH or POP instruction, something
pretty important when interrupts are being processed. However, thanks to
a little tinkering and some sample code supplied by Microchip, we think
we have something that will help.

In this example, we will assume that the interrupt uses the W register
and might corrupt the STATUS bits. You can check for the side effects of
your code by viewing the instruction set. However, saving the W and STATUS
registers is always a good idea!


Here's our interrupt routine using Parallax instructions:

int_routine	csne	var_1, var_2
		add	var_1, #4
		retfie


Thankfully, Parallax gives us some information on the actual Microchip
instructions used to create their macros. Taking a look at the CSNE
instruction we find that it uses a MOVF to the W register first. This
tells us already that the STATUS byte, specifically the Z flag, might be
changed and that the W register will be changed.

How do we gracefully preserve these values prior to changing them, then
restore them before exiting?

First, declare two variables:

temp_w		ds	1	;temporary storage of the W register
temp_stat	ds	1	;temporary storage of the STATUS register

These will be your temporary holders.

Next, add these lines to your code:

int_routine	movwf	temp_w			;save W register
		swapf	STATUS, W		;flip and swap status reg to W
		movwf	temp_stat		;save flipped STATUS register

		csne	var_1, var_2
		add	var_1, #4

		swapf	temp_stat, W		;unflip status to W
		movwf	STATUS			;then into STATUS register
		swapf	temp_w			;flip stored W
		swapf	temp_w, W		;unflip stored W to W		

		retfie				;and exit


What is going on with the SWAPFs? Well, one thing we must do when transferring
the STATUS and W registers back and forth is make sure we don't inadvertantly
corrupt the very registers we are trying to restore! Checking the Microchip
instruction set we find that using a MOVWF to move the W register to temp_w
does not affect any status bits. Therefore it's a safe move. However, trying to
use a MOVF to move STATUS into W can affect the Z flag in the STATUS register.
However, SWAPFs do not affect the STATUS register. Therefore, (though it may
seem convoluted) we take the STATUS register and move it to W via a SWAPF. Its
now in W with flipped nibbles. We then MOVWF it to temp_stat to save it.

Our code is executed.

We then SWAPF temp_stat back to the W register, unflipping the nibbles in the
process. Its passed back to to STATUS using a MOVWF. When W was passed to temp_w
with the MOVWF it was not flipped. Therefore, we flip temp_w on itself with the
first SWAPF, then unflip it and return it to W using the second SWAPF.

Hey, it works! If you have been seeing unexpected side effects from using
interrupts make sure you are using this PUSH/POP scheme.

Hope this helps,

Dan Mullin
Automated Systems Engineering, Inc.
Colorado Springs, Colorado
CompuServe 72644,2423
