In the wiki article Interrupt Context Saving in an ISR I discuss the need to save the TBLPTR registers if your ISR accesses const data arrays or strings in program memory.
Reading memory using the table pointer registers is a three step process:
- load the TBLPTRU/H/L address registers
- use TBLRD instruction to read the data into the table latch register (TABLAT)
- save TABLAT register into the user's destination
If an interrupt occurs between steps 2 and 3 and the ISR reads program memory, upon return the TABLAT register will not be correct.
While the chance of this is very low, low isn't 0.
Bottom line - if you need to save the TBLPTR registers, you need to save the TABLAT register too: save(TBLPTRU, TBLPTRH, TBLPTRL, TABLAT)
This would make the save() instruction to save all the hardware registers one of the following:
Code: Select all
save(FSR0, FSR1, FSR2, PROD, TBLPTRU, TBLPTRH, TBLPTRL, TABLAT) // save all hdw registers
save(0, FSR2, TBLPTRU, TBLPTRH, TBLPTRL, TABLAT) // save the system vars + all hdw regs
This also effects Vectored Interrupts with SF and the IVT.bas module, which I have updated as well.
An updated version of the SAVE_CONTEXT() macro to correct this is in the ivt.bas v2.20 module attached below.
This will be included in the next update.