At C8051F120 DataSheet said that: When an interrupt occurs, the SFR Page Register will automatically switch to the SFR page containing the flag bit that caused the interrupt. The automatic SFR Page switch function conveniently removes the burden of switching SFR pages from the interrupt service routine. Upon execution of the RETI instruction, the SFR page is automatically restored to the SFR Page in use prior to the interrupt.
I tried it, but the simulator doesn't automatic work for SFRPAGE.
#include <c8051F120.h> sfr16 RCAP3 = 0xCA; // Timer3 reload value sfr16 TMR3 = 0xCC; // Timer3 counter sbit LED1=P4^0; sbit LED2=P4^1; sbit LED3=P4^2; sbit LED4=P4^3; sbit LED5=P4^4; sbit LED6=P4^5; void ConfigTimer3() //Timer 3 is 128Hz { data int Divider; SFRPAGE=TMR3_PAGE; TMR3CN=0; TMR3CF=0x00 ;// SYSCLK/12 Freq=98000000; Divider=Freq/12/128; RCAP3=-Divider; TMR3=0xFFFF; EXF3=0; EIE2|=0x01; //EIE2.0=1, ET3=1; EIP2&=0xFE; //EIP2.0=0; PT3=0; //Timer 3 has low priorty TMR3CN=0x04;//TR3=1; SFRPAGE = LEGACY_PAGE; // Page to sit in for now EA=1; } void InitLed() { SFRPAGE=CONFIG_PAGE; P4|=0x3F; //close all led SFRPAGE = LEGACY_PAGE; // Page to sit in for now memset(BlinkInterval, 9, 6); ConfigTimer3(); } void ProcessLed() { BlinkInterval[0]=6; BlinkInterval[1]=6; BlinkInterval[2]=6; BlinkInterval[3]=6; BlinkInterval[4]=6; BlinkInterval[3]=9;//()?4:9; } void Timer3() interrupt 14 using 2 //7.8125ms once { code unsigned char code Mask[10]={0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF}; SFRPAGE=TMR3_PAGE;//This line needn't? TMR3CN=0x04; //TF3=0; //EXF3=0; BlinkCounter++; SFRPAGE=CONFIG_PAGE; LED1=BlinkCounter & Mask[BlinkInterval[0]]; LED2=BlinkCounter & Mask[BlinkInterval[1]]; LED3=BlinkCounter & Mask[BlinkInterval[2]]; LED4=BlinkCounter & Mask[BlinkInterval[3]]; LED5=BlinkCounter & Mask[BlinkInterval[4]]; LED6=BlinkCounter & Mask[BlinkInterval[5]]; }