I have been reading various tutorials and datasheets but I seem to be blind to a very
basic concept that just eludes me.
Here is a bit of code taking a character from a Table for display to an LCD.
My question has to do with the instruction ADDWF
where tutorials give an example of:
MOVLW 1 ; put 1 in W
ADDWF temp,F ; add 1 to temp, store in temp
However, in the context below addwf does much more:
************************
Msg1 movlw high Msg1Ts ; Pick up high byte of table address
movwf PCLATH ; And save into PCLATH
movf MsgIdx,W ; Pick up index
addwf PCL,F ; And look up in table
Msg1Ts dt "TestMessage",0 ; Message, terminate with zero
****************************
If at the start of this subroutine, PCL = 0xA0 and MsgIdx =1...
In Debug, I would expect W to contain "PCL"+"1" which should mean W should contain 0xA1,
the sum. Instead, W contains the contents of address 0xA1, which happens to be the first
address of the table holding the ASCII value of the first table character.
How does the processor know when to interpret addwf as simple arithmetic of register
contents versus a pointer to a new address whose contents should be copied to W?
Must be an easy answer that I have just overlooked :-)
thanks
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
> I have been reading various tutorials and datasheets but I seem to be
> blind to a very basic concept that just eludes me.
>
> Here is a bit of code taking a character from a Table for display to an
> LCD.
>
> My question has to do with the instruction ADDWF
> where tutorials give an example of:
>
> MOVLW 1 ; put 1 in W
> ADDWF temp,F ; add 1 to temp, store in temp
>
> However, in the context below addwf does much more:
>
> ************************
> Msg1 movlw high Msg1Ts ; Pick up high byte of table address
> movwf PCLATH ; And save into PCLATH
> movf MsgIdx,W ; Pick up index
> addwf PCL,F ; And look up in table
>
> Msg1Ts dt "TestMessage",0 ; Message, terminate with zero
> ****************************
>
> If at the start of this subroutine, PCL = 0xA0 and MsgIdx =1...
>
> In Debug, I would expect W to contain "PCL"+"1" which should mean W should
> contain 0xA1, the sum. Instead, W contains the contents of address 0xA1,
> which happens to be the first address of the table holding the ASCII value
> of the first table character.
>
> How does the processor know when to interpret addwf as simple arithmetic
> of register contents versus a pointer to a new address whose contents
> should be copied to W?
>
> Must be an easy answer that I have just overlooked :-)
>
> thanks
As you suspect, it's simple once you know it! ADDWF RAM,F always adds the
contents of W to the RAM location specified RAM and puts the result back
in that RAM location (that's what the F means, put the result in the "file
register". If the destination was W, the result would be put in W and the
RAM location would remain unchanged). In the PIC16, the low half of the
program counter appears in the RAM memory map and is named PCL. So, here,
when you add to PCL, it causes the current PCL (actually, the address of
this instruction plus one since the PC increments before the addition is
executed) to be put into the low half of the program counter. At the same
time, the contents of PCLATH are put in the high half of the program
counter. The processor then executes the instruction at that address.
One thing to watch out for is a bank rollover. In your example, what if
PCLATH is loaded with the high byte of the address of Msg1Ts, but the
table itself rolls over into the next bank. The PCLATH will then have the
wrong value. So, a safer way to deal with this is to watch for the
rollover by doing something like this:
Msg1 movlw high Msg1Ts ; Pick up high byte of table address
movwf PCLATH ; And save into PCLATH
movlw low Msg1Ts ; get low byte of start of string
addwf MsgIdx,W ; Add in index to string
btfsc STATUS,C ; if no overflow, don't increment PCLATH
incf PCLATH,F ; increment PCLATH if we ran off end of bank
addwf PCL,F ; And look up in table
Msg1Ts dt "TestMessage",0 ; Message, terminate with zero
The dt "instruction" puts a bunch of retlw instructions in the code with
the ASCII text being returned in W, so that's how you get each character.
Have fun!
Harold
--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!
------------------------------------
to unsubscribe, go to http://www.yahoogroups.com and follow the instructions
______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.
(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )