I've been wondering how would you move along a buffer/array, reading or
writing to each location in a loop? I can't see any obvious indirect memory
access instructions in the reference manual.
In my old 6502/'6510 assembler days I'd do something like (IIRC);
LDA #0
LDX #5
loop:
STA buffer_start,X
DEX
BNE loop
...
Obviously, PIC only has the W register, and doesn't have index registers...Is
there some 16-bit address to set, and some indirect instruction or something?
cheers,
Mark
==============================================================================
This message is for the sole use of the intended recipient. If you received
this message in error please delete it and notify us. If this message was
misdirected, CSFB does not waive any confidentiality or privilege. CSFB
retains and monitors electronic communications sent through its network.
Instructions transmitted over this system are not binding on CSFB until they
are confirmed by us. Message transmission is not guaranteed to be secure.
==============================================================================
On Mon, Oct 18, 2004 at 01:04:46PM +0100, Mcgee, Mark wrote:
> Hi
>
> I'm using PIC16F628A.
>
> I've been wondering how would you move along a buffer/array, reading or
> writing to each location in a loop? I can't see any obvious indirect memory
> access instructions in the reference manual.
The SFR combo you're looking for is FSR/INDF
>
> In my old 6502/'6510 assembler days I'd do something like (IIRC);
> LDA #0
> LDX #5
> loop:
> STA buffer_start,X
> DEX
> BNE loop
In PIC the eqivalent would be something like (unchecked code warning...):
> ...
>
> Obviously, PIC only has the W register, and doesn't have index registers...Is
> there some 16-bit address to set, and some indirect instruction or something?
It does have index register(s). But they are special function registers as
opposed to out of memory registers likw W.
FSR holds the address, while INDF references the target of that address.
And the 18F family actually has 3 pairs of them, along with auto inc/dec
instructions for the FSR registers. Yet another advantage of the 18F parts.
Finally be aware that FSR is only 8 bits. If the memory you need to access
is beyond that, then you have to manipulate the indirect upper bits in
some register (STATUS or OPTION can't remember off the top of my head).
One advntage of FSR is that it is 8 bits so you can indirectly address up
to 256 bytes (in)directly, while you can only access 128 bytes directly without
switching banks. That's why sometimes I'll do code like:
movlw TRISB ; In bank 1
movwf FSR
clrf INDF ; make port B all outputs
Without bothering to fiddle with the banking bits.
>-----Original Message-----
>From: spam_OUTpiclist-bouncesTakeThisOuTmit.edu [.....piclist-bouncesKILLspam@spam@mit.edu]
>On Behalf Of Mcgee, Mark
>Sent: 18 October 2004 13:05
>To: 'piclistKILLspammit.edu'
>Subject: [PIC]Stepping through buffer in assembler?
>
>
>Hi
>
>I'm using PIC16F628A.
>
>I've been wondering how would you move along a buffer/array,
>reading or writing to each location in a loop? I can't see
>any obvious indirect memory access instructions in the
>reference manual.
>
>In my old 6502/'6510 assembler days I'd do something like
>(IIRC); LDA #0 LDX #5
>loop:
>STA buffer_start,X
>DEX
>BNE loop
>...
>
>Obviously, PIC only has the W register, and doesn't have index
>registers...Is there some 16-bit address to set, and some
>indirect instruction or something?
>
>cheers,
>Mark
Indirect addressing is performed using the INDF and FSR regsiters. You put
the address in the FSR register and then use the INDF register to read or
write the location as usual. You can then perform any indexing math you
require on the FSR register. Note that the FSR register can address only
256 bytes (two banks). For devices with more than two banks of RAM you use
the IRP bit in the STATUS register as the bit of the address.
Regards
Mike
=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================
_______________________________________________ http://www.piclist.com
View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist
> Hi
>
> I'm using PIC16F628A.
>
> I've been wondering how would you move along a buffer/array, reading or
> writing to each location in a loop? I can't see any obvious indirect
> memory
> access instructions in the reference manual.
>
> In my old 6502/'6510 assembler days I'd do something like (IIRC);
> LDA #0
> LDX #5
> loop:
> STA buffer_start,X
> DEX
> BNE loop
> ...
>
> Obviously, PIC only has the W register, and doesn't have index
> registers...Is
> there some 16-bit address to set, and some indirect instruction or
> something?
>
> cheers,
> Mark
Mark:
Take a look at the description of FSR and INDF. This is what you need to
use. A PIC equivalent of your code would be something like this:
movlw buffer ; get addr of buffer
movwf FSR ;into FSR
movlw 5 ;get count
movwf temp ;into a working reg
loop:
clrf INDF ; store info mem pointed to be FSR
incf FSR ; point to next mem location
decfsz temp ; any more to do?
goto loop
; Of course, for this short buffer at a known location, I would just write:
> Hi
>
> I'm using PIC16F628A.
>
> I've been wondering how would you move along a buffer/array, reading or
> writing to each location in a loop? I can't see any obvious indirect memory
> access instructions in the reference manual.
>
> In my old 6502/'6510 assembler days I'd do something like (IIRC);
> LDA #0
> LDX #5
> loop:
> STA buffer_start,X
> DEX
> BNE loop
> ...
>
> Obviously, PIC only has the W register, and doesn't have index registers...Is
Oh but it DOES have an index register.
Read the description for the "FSR" register (0x4).
Load FSR with your pointer (making sure Status bit IRP is set
correctly to point the bank for the SFRs you want to address.
Then address the INDF resister (0x00) to read/write your data.
> there some 16-bit address to set, and some indirect instruction or something?
Or something. It's 8 bits and you need to adjust the 9th bit using the
status register.
I believe this comes under the heading of RTFM (read the fricking
manual).
>
>And the 18F family actually has 3 pairs of them, along with auto inc/dec
>instructions for the FSR registers. Yet another advantage of the 18F parts.
Very AVR-ish :) The AVR has three pointer regs, also usable as "normal"
regs, X, Y, and Z.
So in AVR:
Point at the data, and set up how many bytes to transfer
ldi ZL,low(Data_Array)
ldi ZH,high(Data_Array)
ldi Loop,Data_Array_Len
Read_Loop:
ld TEMP,Z+
;Here, you might DO something with the data..
dec LOOP
brne Read_Loop
For a null terminated string in rom:
ldi ZL,low(Data_Array*2) ;Data is stored in WORDS in the AVR flash
ldi ZH,high(Data_Array*2) ;So the byte address needs to be doubled.
;The lowest bit then selects high/low byte
of the word.
Read_Loop:
LPM ;Data is now in R0, similar to RETLW
adiw ZL,1 ;Inc the pointer
tst R0 ;Is the data null?
breq Read_Done
;Here, you might DO something with the data..
rjmp Read_Loop
Read_Done: ;dummy label
Given that most of these instructions take only one clock (xtal) this is
pretty fast.
Thanks for the help. I thought there must be something like that, given there
is no indexing register or indirect opcode.
I assume that once the FSR and (IRP-status bit 7 - looked it up) have been
set, by referencing location INDF with clrf or movlf etc will perform the
indirection for you?
>
> I've been wondering how would you move along a buffer/array, reading or
> writing to each location in a loop? I can't see any obvious indirect
> memory
> access instructions in the reference manual.
>
>
Check out the INDF and FSR registers.
When you use INDF as a source/destination register, it actually returns
the contents of the register addressed by FSR. Described in section 4.4
of the pic16f628a datasheet.
> Is there some 16-bit address to set, and some indirect
> instruction or something?
It's sorta like an indirect addressing peripheral :-)
> > Obviously, PIC only has the W register, and doesn't have
> > index registers...Is
> > there some 16-bit address to set, and some indirect
> > instruction or something?
>
> It does have index register(s). But they are special function
> registers as opposed to out of memory registers likw W.
Hi.
Since you mentioned the PIC18's later, I though this could be
in place...
Not that on the PIC18's, the W register is also accessable through
the WREG SFR that is mapped in RAM just as any other SFR. So *any*
instruction with 'f' as part of the parameters can also act on W. Such as
a direct MOVFF between W and *any* register in *any* bank no matter
what the BSR bits are currently set to.
The PIC18F252 data sheet says (below the MOVFF description on
page 236) :
"... Either source or destination can be W (a useful special situation)..."
> One advntage of FSR is that it is 8 bits so you can indirectly address up
> to 256 bytes (in)directly, while you can only access 128 bytes directly without
> switching banks. That's why sometimes I'll do code like:
So you can avoid (some of the banking) issues by using FSR? Please say it is so
as I have a buffer copy routine to write and only a limited number of cycles
to write it in (copy the buffer between 19.2kBaud characters) this would help
eliminate two instruction bank switching.
Sorry I don't have the data sheet in front of me I'd look it up myself if I had
On Mon, Oct 18, 2004 at 04:19:07PM +0100, Mcgee, Mark wrote:
> Hi BAJ.
>
> Thanks for the help. I thought there must be something like that, given there
> is no indexing register or indirect opcode.
>
> I assume that once the FSR and (IRP-status bit 7 - looked it up) have been
> set, by referencing location INDF with clrf or movlf etc will perform the
> indirection for you?
>
> I like the 'no bankswitching' technique.
Limited bankswitching... as IRP is still required.
FSR/INDF basically saved me when I wrote the interpreter for my NPCI
compiler. I'd load the target address into FSR and then use INDF to access
that target.
On a PIC, the FSR is the equivalent of an index register. Point it to the
location you want to read or write, then read or write indf . The "pointed
to" location will be read or written. The 18f series has several fsr
registers. There are also registers that pre and post increment and
decrement, doing some of the work for you.
> Hi
>
> I'm using PIC16F628A.
>
> I've been wondering how would you move along a buffer/array, reading or
> writing to each location in a loop? I can't see any obvious indirect
> memory
> access instructions in the reference manual.
>
> In my old 6502/'6510 assembler days I'd do something like (IIRC);
> LDA #0
> LDX #5
> loop:
> STA buffer_start,X
> DEX
> BNE loop
> ....
>
> Obviously, PIC only has the W register, and doesn't have index
> registers...Is
> there some 16-bit address to set, and some indirect instruction or
> something?
>
> cheers,
> Mark
>
> ==============================================================================
> This message is for the sole use of the intended recipient. If you
> received
> this message in error please delete it and notify us. If this message was
> misdirected, CSFB does not waive any confidentiality or privilege. CSFB
> retains and monitors electronic communications sent through its network.
> Instructions transmitted over this system are not binding on CSFB until
> they
> are confirmed by us. Message transmission is not guaranteed to be secure.
> ==============================================================================
>
> _______________________________________________
> http://www.piclist.com
> View/change your membership options at
> http://mailman.mit.edu/mailman/listinfo/piclist
>
>-----Original Message-----
>From: EraseMEpiclist-bouncesspam_OUTTakeThisOuTmit.edu [piclist-bouncesspam_OUTmit.edu]
>On Behalf Of @spam@toftatKILLspamcowshed.8m.com
>Sent: 18 October 2004 17:40
>To: KILLspampiclistKILLspammit.edu
>Subject: Re: [PIC]Stepping through buffer in assembler?
>
>
>> One advntage of FSR is that it is 8 bits so you can
>indirectly address
>> up to 256 bytes (in)directly, while you can only access 128 bytes
>> directly without switching banks. That's why sometimes I'll do code
>> like:
>
>So you can avoid (some of the banking) issues by using FSR?
>Please say it is so as I have a buffer copy routine to write
>and only a limited number of cycles to write it in (copy the
>buffer between 19.2kBaud characters) this would help
>eliminate two instruction bank switching.
Because the FSR is 8 bits wide, you can access two banks without having to
set any extra bits. On some PIC's this will be the entire memory, on others
you will have access to two banks at a time, selected by the IRP bit.
Regards
Mike
=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================
____________________________________________
Michael Rigby-Jones wrote:
> Indirect addressing is performed using the INDF and FSR regsiters.
> You put the address in the FSR register and then use the INDF
> register to read or write the location as usual. You can then
> perform any indexing math you require on the FSR register. Note that
> the FSR register can address only 256 bytes (two banks). For devices
> with more than two banks of RAM you use the IRP bit in the STATUS
> register as the bit of the address.
This describes the PIC 16 (14 bit core) architecture. The 12 bit core is
very similar.
The PIC 18 (16 bit core) is considerably more flexible. There are 3
separate FSRs and they can preincrement, postincrement, and postdecrement.
The PIC 30 has true indirect addressing where each of the 16 general
registers can be used as the address of an indirect reference. It even has
indirect with fixed offset addressing.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________
piclist@xargs.com wrote:
>> The PIC 30 [...] even has indirect with fixed offset addressing.
>
> Is that different than PLUSW on the PIC18?
Yes. You can specify a limited signed offset in the instruction itself.
This is the addressing mode that a C compiler would typically use to access
automatic variables. These are relative to the stack pointer with an offset
known at compile time.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________