The COP8_ISR library simplifies the creation of interrupt handlers. Including cop8_isr.h gives a program access to the SaveContext() and RestoreContext() macros.
Some operations require the use of temporary variables to store intermediate values. Since main line code and interrupt code are independent, a conflict can arise if the compiler uses the same temporary variable in both the main loop and in the interrupt. Use the SaveContext() and RestoreContext() macros at the beginning and end of interrupt subroutines to ensure registers and temporary variables are not overwritten.
Figure 4-2. interrupt subroutine using SaveContext() and RestoreContext() rtccint2.lst
0008 unsigned long rtcc_total;
01FE 02 00 void __SWI(void)
0200 {
SaveContext();
0200 67 PUSHA
0201 9D FE LD A,B
0203 67 PUSHA
0204 9D EF LD A,0EF
0206 67 PUSHA
0207 9D F0 LD A,0F0
0209 67 PUSHA
020A 9D FF LD A,S
020C 67 PUSHA
020D 9D FC LD A,X
020F 67 PUSHA
0210 DF 00 LD S,#000
0212 5F LD B,#00
0213 AA LD A,[B+]
0214 67 PUSHA
0215 48 FC IFBNE 08
000A unsigned long interrupt_count;
0217 9D A4 LD A,0A4 interrupt_count=PORTBD&0xf;
0219 DF 00 LD S,#000
021B BC 0B 00 LD 000B,#00
021E 55 LD B,#0A
021F A2 X A,[B+]
0220 CE DRSZ B
0221 AE LD A,[B]
0222 95 0F AND A,#00F
0224 A2 X A,[B+]
0225 9A 00 LD [B+],#000
0227 55 LD B,#0A interrupt_count++;
0228 A0 RC
0229 AE LD A,[B]
022A 90 01 ADC A,#001
022C A2 X A,[B+]
022D 64 CLRA
022E 80 ADC A,[B]
/*_figure a_*/
022F A6 X A,[B] rtcc_total += interrupt_count+0x8000;
0230 A0 RC
0231 64 CLRA
0232 55 LD B,#0A
0233 80 ADC A,[B]
0234 9C 02 X A,0002
0236 9D 0B LD A,000B
0238 90 80 ADC A,#080
023A 9C 03 X A,0003
023C A0 RC
023D 9D 02 LD A,0002
023F 57 LD B,#08
0240 80 ADC A,[B]
0241 A6 X A,[B]
0242 9D 03 LD A,0003
0244 56 LD B,#09
0245 80 ADC A,[B]
/*_figure a_*/
0246 A6 X A,[B] RestoreContext();
0247 DF 00 LD S,#000
0249 58 LD B,#07
024A 8C POPA
024B A3 X A,[B-]
024C 40 FC IFBNE 00
024E 8C POPA
024F A6 X A,[B]
0250 8C POPA
0251 9C FC X A,X
0253 8C POPA
0254 9C FF X A,S
0256 8C POPA
0257 9C F0 X A,0F0
0259 8C POPA
025A A0 RC
025B 9F EF LD B,#0EF
025D 60 80 ANDSZ A,#080
025F 7F SBIT 07,[B]
0260 60 40 ANDSZ A,#040
0262 7E SBIT 06,[B]
0263 8C POPA
0264 9C FE X A,B
0266 8C POPA
0267 8F RETI }
000C unsigned long main_loop_total;
void main(void)
{
077E unsigned long count;
DDR(PORTB,OOOOIIII); /* set upper nibble of PORTB as output */
while(1)
{
/*_figure b_*/
0268 BC A5 F0 LD 0A5,#F0 main_loop_total += count - 0x8000;
026B A1 SC
026C DF 07 LD S,#007
026E 9D 7E LD A,077E
0270 91 00 SUBC A,#000
0272 DF 00 LD S,#000
0274 5D LD B,#02
0275 A2 X A,[B+]
0276 DF 07 LD S,#007
0278 9D 7F LD A,077F
027A 91 80 SUBC A,#080
027C DF 00 LD S,#000
027E A6 X A,[B]
027F A0 RC
0280 CE DRSZ B
0281 AE LD A,[B]
0282 53 LD B,#0C
0283 80 ADC A,[B]
0284 A6 X A,[B]
0285 9D 03 LD A,0003
0287 52 LD B,#0D
0288 80 ADC A,[B]
/*_figure b_*/
0289 A6 X A,[B] count++;
028A 9F 7E LD B,#07E
028C A0 RC
028D DF 07 LD S,#007
028F AE LD A,[B]
0290 90 01 ADC A,#001
0292 A2 X A,[B+]
0293 AE LD A,[B]
0294 90 00 ADC A,#000
0296 A6 X A,[B] }
0297 22 6B JMP 0026B
}
If, in either the main loop or interrupt service routines, you don't use math library operations (multiply, divide, modulus) or 16-bit variables, you can reduce the amount of memory needed for preserving program state. To do so, define the symbol __NO16BIT_NOMATH_ISR in your program before cop8_isr.h is included. If you are using the BCLINK linker, this definition must be in the linker command file.
Figure 4-3. optimized SaveContext() and RestoreContext() rtccint3.lst
void __INT(void)
{
SaveContext();
0102 9C 08 X A,008
0104 9D FC LD A,X
0106 DC 09 LD X,#009
0108 B2 X A,[X+]
0109 9D FE LD A,B
010B B2 X A,[X+]
010C 9D EF LD A,0EF
010E B2 X A,[X+]
010F 9D F0 LD A,0F0
0111 B2 X A,[X+]
000E unsigned int interrupt_temp;
0112 51 LD B,#0E rtcc_total <<= interrupt_temp;
0113 AE LD A,[B]
0114 9C FC X A,X
0116 9D FC LD A,X
0118 92 00 IFEQ A,#000
011A 09 JP 00124
011B 9D 0D LD A,00D
011D BD 0D 84 ADD A,00D
0120 52 LD B,#0D
0121 A6 X A,[B]
0122 CC DRSZ X
0123 F7 JP 0011B
0124 51 LD B,#0E interrupt_temp++;
0125 A6 X A,[B]
0126 8A INCA
0127 A6 X A,[B]
RestoreContext();
0128 53 LD B,#0C
0129 AB LD A,[B-]
012A 9C F0 X A,0F0
012C AE LD A,[B]
012D 84 ADD A,[B]
012E BD EF 6F RBIT 07,0EF
0131 88 IFC
0132 BD EF 7F SBIT 07,0EF
0135 BD EF 6E RBIT 06,0EF
0138 76 IFBIT 06,[B]
0139 A1 SC
013A CE DRSZ B
013B AB LD A,[B-]
013C 9C FE X A,B
013E 9D 09 LD A,009
0140 9C FC X A,X
0142 9D 08 LD A,008
0144 8F RETI }