Hi, Came up with a few PCLATH adjusting macros the other day, usage: LONG_CALL ROUTINE ; any page to any page ( two BSF/BCF ) Or SHORT_CALL ROUTINE ; page0<->1 or page2<->3 ( one BSF/BCF ) Sets the highest (relevant) two bits of the PCLATH according to the page boundary crossing. Resets after call, w is left untouched. Message's are provided at compile to aid in replacing LONG_CALL with regular CALL or SHORT_CALL ( also provided ). Don't know if anyone is interested, anyway here You go: ;+++++ ; SET_PCLATH 'help' macro for LONG_CALL ; Set's/clears PCLATH bits 3:4 according to ; 'variable' PCLATH_34 ; SET_PCLATH MACRO PCLATH_34 IF(PCLATH_34&0x10) BSF PCLATH,4 ELSE BCF PCLATH,4 ENDIF IF(PCLATH_34&0x08) BSF PCLATH,3 ELSE BCF PCLATH,3 ENDIF ENDM ;+++++ ; SET_PCLATH4 'help' macro for LONG/SHORT_CALL ; Set's/clears PCLATH bit 4 according to ; 'variable' PCLATH_4 ; SET_PCLATH4 MACRO PCLATH_4 IF(PCLATH_4&0x10) BSF PCLATH,4 ELSE BCF PCLATH,4 ENDIF ENDM ;+++++ ; SET_PCLATH3 'help' macro for LONG/SHORT_CALL ; Set's/clears PCLATH bit 3 according to ; 'variable' PCLATH_3 ; SET_PCLATH3 MACRO PCLATH_3 IF(PCLATH_3&0x08) BSF PCLATH,3 ELSE BCF PCLATH,3 ENDIF ENDM ;+++++ ; LONG_CALL long call, sets the page bits 4:5 of PCLATH ; so call can cross ANY page boundary, reset's PCLATH after call. ; w-reg is left untouched. LONG_CALL MACRO LABEL LOCAL DEST_HIGH, SOURCE_HIGH, DIFF_HIGH DEST_HIGH SET (HIGH(LABEL)&0x18) ; save bit's 4:5 of dest adress SOURCE_HIGH SET (HIGH($)&0x18) ; --- || --- source adress DIFF_HIGH SET DEST_HIGH ^ SOURCE_HIGH ; get difference ( XOR ) IF (DIFF_HIGH == 0) ; same page, SHOULD generate no extra code, delta 0 pages MESSG "Call on same page, replace LONG_CALL with CALL " LABEL NOP ; redundant NOP's NOP CALL LABEL NOP NOP ELSE ; test if both bits must be set ? i.e. page0<->page3 or page2<->page3 IF (DIFF_HIGH == 0x18) ; difference in BOTH bit's, delta 2 pages MESSG "Setting page bit's for page crossing call" SET_PCLATH DEST_HIGH ; set both bits in PCLATH CALL LABEL SET_PCLATH SOURCE_HIGH ; reset both bits in pclath ELSE ; if we end up here then one BSF/BCF is enough, i.e. delta 1 page ; i.e. page0<->1 or page2<->3 MESSG "Call only one page, replace LONG_CALL with SHORT_CALL " LABEL IF (DIFF_HIGH == 0x10) ; diff in high bit NOP ; redundant NOP SET_PCLATH4 DEST_HIGH ; set high(4) bit of PCLATH CALL LABEL SET_PCLATH4 SOURCE_HIGH NOP ; redundant NOP ELSE ; lowest bit only NOP ; redundant NOP SET_PCLATH3 DEST_HIGH ; set low(3) bit of PCLATH CALL LABEL SET_PCLATH3 SOURCE_HIGH NOP ENDIF ENDIF ENDIF ENDM ;+++++ ; SHORT_CALL short call, code for calling between page0<->1 or page2<->3 ; Reset's PCLATH after call. ; w-reg is left untouched. SHORT_CALL MACRO LABEL LOCAL DEST_HIGH, SOURCE_HIGH, DIFF_HIGH DEST_HIGH SET (HIGH(LABEL)&0x18) ; save bit's 4:5 of dest adress SOURCE_HIGH SET (HIGH($)&0x18) ; --- || --- source adress DIFF_HIGH SET DEST_HIGH ^ SOURCE_HIGH ; get difference ( XOR ) IF (DIFF_HIGH == 0) ; same page, SHOULD generate no extra code, delta 0 pages MESSG "Call on same page, replace SHORT_CALL with CALL " LABEL NOP ; redundant NOP's CALL LABEL NOP ELSE IF (DIFF_HIGH == 0x10) ; diff in high bit SET_PCLATH4 DEST_HIGH ; set high(4) bit of PCLATH CALL LABEL SET_PCLATH4 SOURCE_HIGH ELSE ; lowest bit only SET_PCLATH3 DEST_HIGH ; set low(3) bit of PCLATH CALL LABEL SET_PCLATH3 SOURCE_HIGH ENDIF ENDIF ENDM /Tony Tony KŸbek, Flintab AB ΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣ E-mail: tony.kubek@flintab.com ΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣΣ