Richard, I'm not sure why you are doing it that way but I would use the standard method. You need to define W_copy in both banks at the same offset (ie: 0x20, 0xA0). S_copy is in Bank 0. MOVWF W_copy ; Copy W to temp SWAPF STATUS,W ; Swap STATUS to be saved in W CLRF STATUS ; Switch to Bank 0 MOVWF S_copy ; Copy STATUS to temp (Your ISR stuff) SWAPF S_copy,W ; Restore STATUS (and Bank) MOVWF STATUS SWAPF W_copy,F ; Restore W SWAPF W_copy,W RETFIE - Tom At 09:08 AM 9/3/99 +1200, Richard Prosser wrote: >I am having a related problem that again, seems simple but I must be missing >something > >If you use code similar to the below to save your STATUS and W registers - >how do you recover them correctly? > >The obvious solution would be along the lines of:- >swapf S_copy,W ;get the old status reg >movwf STATUS ;this will also perform bank switching >movf W_copy,W ;get the old W value >RETFIE > >There are 2 problems with this >1) If the interrupt was entered when in bank1 (say) then S_copy will be in >bank 1 but I will be attempted to recover it from bank 0 (or wherever the >interupt routine points it). Is this why they reccommend saving a copy in >every bank? >2) The final movf,w W_copy may change the STATUS,Z bit. > >If I change the order of the STATUS and W recovery, obviously the W reg will >be corrupted during the STATUS recovery. > >I have come up with a sequence that will sort everything out - bit it is >very long & messy and relies on a multitude of bit test & set etc >operations. >Surely there is a simpler, tidy way? > >My code is as follows for anyone interested - 16C73A. (It has a minor fault >in that I cover for a STATUS,Z bit change during a movwf operation - I now >realise that this doesn't happen) > > >int_handle ;interrupt handler - timer 2 >interrupt > ;note: location int_status ust be >clear before entering handler > btfss STATUS,RP0 ;handle the bank switch > goto int_bank_0 ;STATUS is in bank 0 > bcf STATUS,RP0 ;goto bank 0 > bsf int_status,RP0 ;set the bank bit - only 2 banks available >with 16C73 >int_bank_0 > btfsc STATUS,Z ;handle the zero bit > bsf int_status,Z ;make sure that int_status carries the >correct bit > > movwf int_w ;store existing w reg - could be >either bank at this point This may > ;change the Zero bit > movf STATUS,w ;get status -zero bit may have been >changed by mov operations > andlw 0x9B ;mask out zero & bank switch bits > iorwf int_status,w ;& bring in int_status along with previous >values > movwf int_status2 ;save. This should now be exact copy >of incoming status reg > clrf int_status ;make sure int_status is cleared for >next time around > >;************** perform required interrupt operations in here > >;************** >int_out > movf int_status2,w ;get the old status reading > movwf STATUS ;& store in STATUS > andlw 0xDB ;mask out Bank select & Zero Bit >(stay in bank 0) > movf int_w,w ;recover old w reg > bcf STATUS,Z ;clear the zero bit (could have been >set by move) > btfsc int_status2,Z ;test the stored value > bsf STATUS,Z ;set the zero bit if it was set > btfsc int_status2,RP0 ;check the bank select bit > bsf STATUS,RP0 ;& set the bank select if required > RETFIE ;return from interrupt > >Any Comments? >Richard ------------------------------------------------------------------------ Tom Handley New Age Communications Since '75 before "New Age" and no one around here is waiting for UFOs ;-)