Searching \ for 'PCLATH lowest three bits ? never changes ?' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=pclath+lowest+three
Search entire site for: 'PCLATH lowest three bits ? never changes ?'.

Truncated match.
PICList Thread
'PCLATH lowest three bits ? never changes ?'
2000\04\25@130947 by Kbek Tony

flavicon
face
Hi, having a very odd problem, been fighting it for a few hours now
maybe someone on the list can assist me, here goes:

Running a 16F876 at 20 Mhz connected with an ICD ( latest rev. ).
My problem: The lowest three bits of the PCLATH reg NEVER changes ?
( not when stepping or anything else...)

What happens: Table lookup code ( all according to Mchip recommendation
)
             sets the PCLATH at times ( when crossing an page..duh..)
                 but the PCLATH is then NEVER cleared at return or
anything else.
                 Then other computed gotos goes haywire....why...???

Example code ( based on code from Nikolai ):

( ORG 0x011E )
PARSE_TABLE
       ; page boundary check, setup pclath corretly
->      MOVLW HIGH(PARSE_TABLE_START)                    
->      MOVWF   PCLATH
       MOVFW   Parse_State     ; read current state
       SKPNZ   ; initial state ? ( 0 )
       GOTO    PARSE_STATE0    
       ADDLW   -PARSE_STATE_OFFSET-1 ; remove offset
       ;jump table with automatic block boundary workaround    
       ADDLW   LOW(PARSE_TABLE_START)                    
       SKPNC
       INCF    PCLATH,F
       MOVWF   PCL     ; jump into table
.
.
.
(ORG 0x0136 )
PARSE_TABLE_START
;---------------- jump table start ----------------
       GOTO    PARSE_STATE1
.
.

The two lines marked with '->' will set the lowest bit of PCLATH
( in this code ) but then it NEVER is cleared without me testing it and
clearing
it manually. This affects other computed gotos or lookup tables...

WHY ???

feeling completely dumdfounded by this...

/Tony






Tony KŸbek, Flintab AB            
ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ
E-mail: spam_OUTtony.kubekTakeThisOuTspamflintab.com
ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ

2000\04\25@132020 by Kbek Tony

flavicon
face
Ahhhhrgg found out what my problem was, I thought
that the PCLATH was updated with the highest 3 bits from the PC,
but this is obviously not the case, sorry...
Also I thought that an return would reset the PCLATH but this is also
not
the case. Return takes you back to where you called from but does
not clear the PCLATH, that has to be done 'manually' ..strange...
For example calling an routine on another page ( with setting/clearing
the 4:5 bits
of PCLATH first ) gets you there, but after return the pagebits must be
cleared/set manually again to reflect current page, else the next goto
or similar
would go to an 'unknown' location,

I never heard this, can someone please correct me if i'm wrong ?

/Tony



Tony KŸbek, Flintab AB            
ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ
E-mail: .....tony.kubekKILLspamspam@spam@flintab.com
ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ

2000\04\25@133024 by Alice Campbell

flavicon
face
Hi Tony,
Ive seen the same thing in the 877.  im starting to treat
page changes like an ISR, with saves before and resets after.
At least that way i can make the code work. very annoying, i
though i was above that sort of thing. However, you should
also do what Andy said, and check that you are not corrupting
the flags by accident when initializing or fiddling with the
option register or port directions.

alice

{Quote hidden}

2000\04\25@135308 by Andrew Warren

face
flavicon
face
KŸbek Tony <.....PICLISTKILLspamspam.....MITVMA.MIT.EDU> wrote:

> I thought that the PCLATH was updated with the highest 3 bits from
> the PC, but this is obviously not the case
> ....
> Also I thought that an return would reset the PCLATH but this is
> also not the case. Return takes you back to where you called from
> but does not clear the PCLATH, that has to be done 'manually'
> ....
> I never heard this, can someone please correct me if i'm wrong ?

   No need for correction, Tony; you've described the PCLATH
   operation perfectly.

   The PIC's program counter is two bytes wide.  The low byte,
   "PCL", is accessible to you as a read/write register.  The high
   byte is NOT "PCLATH"; it's an internal register called "PCH"
   which isn't directly accessible to you at all.

   PCLATH is just a latch; whatever you write into it is
   automatically copied to PCH when you do a CALL or GOTO (and when
   you directly modify the PCL register), but nothing is ever
   automatically copied BACK into it.  The PIC never changes PCLATH
   unless your code tells it to.

   -Andy


=== Andrew Warren - EraseMEfastfwdspam_OUTspamTakeThisOuTix.netcom.com
=== Fast Forward Engineering - San Diego, California
=== http://www.geocities.com/SiliconValley/2499

2000\04\25@145929 by jamesnewton
face picon face
I have some questions and comments... just a few... sorry, but I'd like to
get some of this cleared up and put on the FAQ page. Some of these are
questions that I will most certainly raise at the Microchip seminar I'm
attending in August.

First, the compiler or relocatable assembly linker may change PCLATH with
out telling you or in ways that aren't always clear.

We understand from Walter Quitt that if you try to write relocatable
assembler code, the linker will put in
       movlw
       movwf
commands to load PCLATH.

On some processors (the 16F877 is one) the PAGESEL assembler macro will
cause MPLAB to produce

001973   3019     MOVLW     0x19                   PAGESEL IO
001974   008a     MOVWF     0xa
001975   217e     CALL      0x17e                  call    IO

where the BANKSEL does bit set/clears. Anyone know why? Anyway, watch out
for W not being what you think it will be on calling your subroutine if you
use PAGESEL on the '877. Try PAGESEL, then MOVLW, then GOTO or CALL.


Using the Macros suggested by Thorsten Klose might be a more consistent
idea.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XGOTO MACRO label
       if label & 0x800
       bsf     PCLATH, 3
       else
       bcf     PCLATH, 3
       endif
       goto    label
       ENDM

XCALL MACRO label
       LOCAL   testlabel
testlabel:
       if label & 0x800
       bsf     PCLATH, 3
       else
       bcf     PCLATH, 3
       endif
       call    label
       if testlabel & 0x800
       bsf     PCLATH, 3
       else
       bcf     PCLATH, 3
       endif
       ENDM
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

or the more efficient (but more complex) version by Tony K|bek

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
L_CALL  MACRO   LABEL
       IF      ((HIGH($)&0x18) == (HIGH(LABEL)&0x18)) ; same page,
generates no extra code
       MESSG   "Call on same page"
       NOP     ; without these I cannot compile !!

       NOP   ; <--- is there any way to remove these ???
       CALL    LABEL


       ELSE
       PAGESEL LABEL
               IF      ((HIGH(LABEL)&0x18) == 0x00) ; call to page0
               MESSG "call to page 0"
               BCF     PCLATH,3
               BCF     PCLATH,4
               CALL    LABEL

               ELSE

                       IF      ((HIGH(LABEL)&0x18) == 0x08) ; call to
page1
                       MESSG "call to page 1"
                       BSF     PCLATH,3
                       BCF     PCLATH,4
                       CALL    LABEL

                       ELSE

                               IF      ((HIGH(LABEL)&0x18) == 0x10) ;
call to page2
                               MESSG "call to page 2"
                               BCF     PCLATH,3
                               BSF     PCLATH,4
                               CALL    LABEL

                               ELSE
                               MESSG "call to page 3"
                               ; call to page3
                               BSF     PCLATH,3
                               BSF     PCLATH,4
                               CALL    LABEL

                               ENDIF
                       ENDIF
               ENDIF
       ENDIF

       ENDM
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
I'm not sure why Tony didn't use clrf PCLATH on the Page 0 case.... Also
note that you must be very consistent about using these macros if they don't
set PCLATH back to the current page. The SX has a RETP instruction that
takes care of that for you on subroutine returns. They will also take care
of the case where you do a local jump in your current page, but haven't
realized that you have rolled over from one page to the next and left PCLATH
set for the last page. Nasty trap, that!

Also, why not use a macro that computes a math operation (add or subtract)
on the PC for jumps that do cross a page but are not more that 255 addresses
away from the source?

My SXKey has a assembler macro called LJMP that assembles between 0 and 3
clear bit or set bit instructions to set up the Scenix equivalent of PCLATH
prior to a JMP (GOTO). I always thought that was a bit strange as the Scenix
also has a PAGE instruction (also supported) that loads a literal 3 bit
value into the top of the PCLATH. Maybe someone at Parallax wanted to remain
in the PIC instruction set. They do use the PAGE inst if you put a @ before
the target label in your CALL or JMP. Easy to miss that in the docs.

Maybe another look at this little table will clarify the whole thing. The
little x's need to get set or cleared in addition to the big X's supplied by
the goto or call instruction in order to address the indicated amount of
space.
PC
LATH goto or call
--- -----------
xxx XX XXXXXXXX 8K
0xx XX XXXXXXXX 8K
00x XX XXXXXXXX 2K

Finally, make sure you save and restore PCLATH in an ISR. Otherwise you have
to turn global interrupts off when you get ready for a long call?

---
James Newton (PICList Admin #3)
jamesnewtonspamspam_OUTpiclist.com 1-619-652-0593
PIC/PICList FAQ: http://www.piclist.com or .org

{Original Message removed}

2000\04\25@214929 by Kbek Tony

flavicon
face
Hi there,

>First, the compiler or relocatable assembly linker may change PCLATH
with
>out telling you or in ways that aren't always clear.
>We understand from Walter Quitt that if you try to write relocatable
>assembler code, the linker will put in
>        movlw
>        movwf
>commands to load PCLATH.

According to the manual Yes, but in practice who knows ;-)
( atleast not during my tests )

>
>On some processors (the 16F877 is one) the PAGESEL assembler macro will
>cause MPLAB to produce
>
>001973   3019     MOVLW     0x19                   PAGESEL IO
>001974   008a     MOVWF     0xa
>001975   217e     CALL      0x17e                  call    IO

>where the BANKSEL does bit set/clears. Anyone know why? Anyway, watch
out
>for W not being what you think it will be on calling your subroutine if
you
>use PAGESEL on the '877. Try PAGESEL, then MOVLW, then GOTO or CALL.

Hmmm think this example code is wrong, when I test with 16F876/7 and
pagesel I get BSF/BCF on the PCLATH bits. ( but I think that's what You
meant ).
Still havent heard any explanation for why, as according to the manual
is should
produce MOVLW etc. on all 14 bit processors. Strange...

>- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>
>or the more efficient (but more complex) version by Tony K|bek
>
>- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Nah not efficient ( and dont restore the pclath after call as You stated
) have
a few that I'm working on right now ( as my knowledge has increased a
bit after this experience ) that might be better. I'll post them
on the list when they are tested.

>I'm not sure why Tony didn't use clrf PCLATH on the Page 0 case....
Also
>note that you must be very consistent about using these macros if they
don't
>set PCLATH back to the current page. The SX has a RETP instruction that

:-) , was just playing around testing various setups ( macros ). This
was
by no means meant to be complete/final, my question concerned the two
redundant
NOP's at the 'same page call' which I now understand is no way to
dispose off
unless one has a two pass linker ( i.e. not possible with MPLINK ).

>Finally, make sure you save and restore PCLATH in an ISR. Otherwise you
have
>to turn global interrupts off when you get ready for a long call?

The wise man has spoken, ALWAYS save these !

And from Andy:


>    PCLATH is just a latch; whatever you write into it is
>    automatically copied to PCH when you do a CALL or GOTO (and when
>    you directly modify the PCL register), but nothing is ever
>    automatically copied BACK into it.  The PIC never changes PCLATH
>    unless your code tells it to.

Yes ( except on the 17C42 I think, someone ? ), but I always assumed
that
the restoring when returning from a call would be a given, but no go,
learned
that the hard way.

And finally from Alice:

>also do what Andy said, and check that you are not corrupting
>the flags by accident when initializing or fiddling with the
>option register or port directions.

Hmm I'm confused, these are RAM banks right ? they work independly
from PROGMEM banks as far as I know. So in this case one would
be safe. But in general one must also take care about the RAM banks.

My Thanks to all who responded,


/Tony

Tony KŸbek, Flintab AB            
ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ
E-mail: @spam@tony.kubekKILLspamspamflintab.com
ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ

2000\04\27@011353 by Nikolai Golovchenko

flavicon
face
Hi Tony,
There may be the page crossing problem with my code, but only if the
code is not located in one 11bit page, because this portion of code
uses gotos without PCLATH<4:3> presetting.

Goto and call are capable of 11 bit addressing, higher bits are taken
from PCLATH<4:3>:
A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0
       \____ goto or call _____________/
\4  3   2   1  0/
\_ PCLATH ____/  (PCLATH<2-0> bits are discarded I guess)

return instruction pops entire 13-bit address from stack. So before
making a call to a routine located in another 11bit page, PCLATH
should be preset to HIGH(address_of_routine), and any gotos or calls
in  that  routine  should  not  cross  the 11bit page boundary without
PCLATH<4:3> presetting.

This is one part of the problem - take care with goto and call.
Another part is computed goto. It deals with PCL register:

A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0
\4  3   2   1  0/ \7 6  5  4  3  2  1  0/
\_ PCLATH ____/   \_______ PCL _______/
(lower PCLATH bits are used)

Here you may have a problem with 8bit block crossing. (This paging is
really a nasty thing about PICs...) My code works this around by
incrementing the preset PCLATH if jump crosses 8bit block boundary. I
prefer always add the workaround so I don't have to worry that at some
point of development my program crashes... Don't like to step on the
rakes twice if you know what I mean...

Nikolai
http://techref.massmind.org/member/NG--944

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...