I’m trying to follow the code generated by the compiler for interrupt context save/restore. I am trying to understand how the interrupt routine is using the stack. By compiler convention, FSR1 is the stack pointer and FSR2 is the frame pointer. I think I follow the context save ok, but have problems following the context restore.
<code>
224: #pragma interruptlow InterruptHandlerLow save=PROD /* You may want to save additional symbols. */
225:
226: unsigned int intb_int = 0;
227: unsigned int intb_lft = 0;
228: unsigned int intb_rgt = 0;
229: void InterruptHandlerLow ()
54DA CFD8 MOVFF 0xfd8, 0xfe4 STATUS -> ++(SP)
54DC FFE4 NOP
54DE CFE0 MOVFF 0xfe0, 0xfe4 BSR -> ++(SP)
54E0 FFE4 NOP
54E2 6EE4 MOVWF 0xfe4, ACCESS W -> ++(SP)
54E4 CFDA MOVFF 0xfda, 0xfe4 FP(H) -> ++(SP)
; Save old FP(H)
54E6 FFE4 NOP
54E8 CFE2 MOVFF 0xfe2, 0xfda SP(H) -> FP(H)
; Setup new FP(H)
54EA FFDA NOP
54EC CFE9 MOVFF 0xfe9, 0xfe4 FSR0L -> ++(SP)
54EE FFE4 NOP
54F0 CFEA MOVFF 0xfea, 0xfe4 FSR0H -> ++(SP)
54F2 FFE4 NOP
54F4 CFF3 MOVFF 0xff3, 0xfe4 PRODL -> ++(SP)
54F6 FFE4 NOP
54F8 CFF4 MOVFF 0xff4, 0xfe4 PRODH -> ++(SP)
54FA FFE4 NOP
54FC 52E6 MOVF 0xfe6, F, ACCESS (SP)++ -> (SP)++
; Read PRODH just stored on stack, increment sp
; Write PRODH again, increment sp again
54FE CFD9 MOVFF 0xfd9, 0xfe6 FP(L) -> (SP)++
; Save frame pointer address
5500 FFE6 NOP
5502 CFE1 MOVFF 0xfe1, 0xfd9 SP(L) -> FP(L)
; Set frame pointer address
5504 FFD9 NOP
5506 0E05 MOVLW 0x5 0x5 -> W
5508 26E1 ADDWF 0xfe1, F, ACCESS W + SP(L) ->
SP(L)
; Allocate five bytes local var. space
So we end up with a stack looking like the following:
; SP -> ]
; FP[4]: mask ] local auto variables...
; FP[3]: ibit ]
; FP[2]: int_count ]
; FP[1]: intb_curr ]
; FP[0]: int_byte ] <- FP
; FSR2L (old FP(L)) ]
; PRODH - ??? ]
; PRODH ]
; PRODL ]
; FSR0H ]
; FSR0L ]
; FSR2H (old FP(H)) ]
; Wreg ]
; BSR ]
; STATUS ]
; ]
At the end of the routine, we restore context.
This is where I have problems following the code.
5926 CFD9 MOVFF 0xfd9, 0xfe1 FP(L) -> SP(L)
; Rollback SP to frame pointer
; SP now pointing to int_byte
5928 FFE1 NOP
592A 52E5 MOVF 0xfe5, F, ACCESS (SP)-- -> (SP)--
; ??????????????
; Read int_byte, decrement sp to point to FP(L)
; write int_byte over FP(L), decrement sp
; sp ends up pointing to PRODH????
; ??????????????
592C CFE7 MOVFF 0xfe7, 0xfd9 (SP) -> FP(L)
; ??? Load FP with PRODH???
592E FFD9 NOP
5930 52E5 MOVF 0xfe5, F, ACCESS (SP)-- -> (SP)--
5932 CFE5 MOVFF 0xfe5, 0xff4 (SP)-- -> PRODH
5934 FFF4 NOP
5936 CFE5 MOVFF 0xfe5, 0xff3 (SP)-- -> PRODL
5938 FFF3 NOP
593A CFE5 MOVFF 0xfe5, 0xfea (SP)-- -> FSR0H
593C FFEA NOP
593E CFE5 MOVFF 0xfe5, 0xfe9 (SP)-- -> FSR0L
5940 FFE9 NOP
5942 CFE5 MOVFF 0xfe5, 0xfda (SP)-- -> FSR2H
5944 FFDA NOP
5946 50E5 MOVF 0xfe5, W, ACCESS (SP)-- -> W
5948 CFE5 MOVFF 0xfe5, 0xfe0 (SP)-- -> BSR
594A FFE0 NOP
594C CFE5 MOVFF 0xfe5, 0xfd8 (SP)-- -> STATUS
594E FFD8 NOP
5950 0010 RETFIE 0
611: