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 }