Searching \ for 'Efficient move block PIC16C77' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/devices.htm?key=16C
Search entire site for: 'Efficient move block PIC16C77'.

Truncated match.
PICList Thread
'Efficient move block PIC16C77'
1999\01\13@083607 by Howard McGinnis

flavicon
face
What's the most efficient way to move blocks of data in a 16C77?

Howard
---------------------------------------------------------------------
Howard McGinnis                   Electronic Visions, Inc
spam_OUThmcginniTakeThisOuTspamdigital.net            1650 Barrett Drive
(407) 632-7530                      Rockledge FL 32955
FAX (407) 632-3396               http://ddi.digital.net/~hmcginni

1999\01\13@164122 by Barry King

flavicon
face
Howard McGinnis asked:

>What's the most efficient way to move blocks of data in a 16C77?

Since the PIC has only one index register, the general case
of a block move requires that for each byte, you move a source
pointer into FSR, then get the data, then move the destination
pointer to FSR and store the data.

Usual disclaimer applies: This code should work, I use something very
similar myself, but no warranty!  Free software can be expensive :)

;(all these RAM addresses are arbitrary)
Source   EQU    H'30'                  ;the source data, H'30'..H'5F'
Dest     EQU    H'A0'                  ;the destination, H'A0'..H'CF'

#define NBytes  H'30'                  ;thats 48 bytes to you

PtrS     EQU    H'20'                  ;the source pointer
PtrD     EQU    H'21'                  ;the destination pointer
Count    EQU    H'22'                  ;number of bytes to copy
Temp     EQU    H'23'

MemCopy:
        MOVLW  NBytes                 ;number of bytes to be copied
        MOVWF  Count                  ;init counter
        MOVLW  Source                 ;the address of the source
        MOVWF  PtrS                   ;init source pointer
        MOVLW  Dest                   ;the address of the
destination
        MOVWF  PtrD                   ;init dest pointer

MCLoop:
        MOVF   PtrS,W                 ;get the source pointer...
        MOVWF  FSR                    ;into FSR
        MOVF   INDF,W                 ;get data, indirect
        MOVWF  Temp                   ;save the data a moment
        MOVF   PtrD,W                 ;get the dest pointer
        MOVWF  FSR                    ;into FSR
        MOVF   Temp,W                 ;get the data back
        MOVWF  INDF                   ;put to destination, indirect

        INCF   PtrS,F                 ;bump source pointer to next
data
        INCF   PtrD,F                 ;bump destination pointer
        DECFSZ Count,F                ;one less to do, skip if done
        GOTO   MCLoop                 ;if not done, loop for another

;skips to here when done...

This is the best general case I know, but still not very efficent.
Another index register, anyone?

Be careful if the Source and Destination overlap!  If the source is
at a lower but overlapping address, this routine will not work
because it copies lowest address first!

Here is a good trick:  If the source and destination areas are always
the same locations, you can optimize a lot by locating them at
corresponding addresses in different banks, or otherwise so that
there is one bit difference in their addresses.  Then you can use a
BSF and BCF on one bit of the FSR to point FSR to source then to
destination. You can also do this trick by twiddling bit IRP instead,
then the source and dest are in different pages.  Note that you can
consider IRP+FSR as a 9 bit index register.

For example:

#define NBytes 30
;(these RAM addresses are carefully chosen for this trick to work.
; notice that 30h and B0h are corresponding addresses in Bank0 and 1
; and therefore differ by the high bit of their address)
Source   EQU    H'30'                  ;the source data
Dest     EQU    H'B0'                  ;the destination

Count    EQU    H'20'                  ;number of bytes to copy

Sneaky:
        MOVLW  NBytes
        MOVWF  Count
        MOVLW  Source                 ;the address of the source
        MOVWF  FSR                    ;into FSR

SCLoop:
        MOVF   INDF,W                 ;get data, indirect
        BSF    FSR,                   ;switch to dest area
        MOVWF  INDF                   ;put to destination, indirect
        BCF    FSR, 7                 ;back to source bank
        INCF   FSR                    ;point at next pair
        DECFSZ Count                  ;one less to do, skip if done
        GOTO   SCLoop                 ;if not done, loop for another
;skips to here when done...

This uses less RAM and is mush quicker, at the expense of generality
(in maintaining the code, if you decide to move variables around in
RAM, it FAILS!)

Try coding THAT trick in portable C! :)

---------------------------------------------------
Barry King
Engineering Manager
NRG Systems "Measuring the Wind's Energy"
.....barryKILLspamspam@spam@nrgsystems.com
"The witty saying has been deleted due to limited EPROM space"

1999\01\13@170000 by Barry King

flavicon
face
Like all good programmers, I made a critical typo in entering a piece
of perfectly good code.  Correction:
SCLoop:
        MOVF   INDF,W                 ;get data, indirect
        BSF    FSR, 7                 ;switch to dest area
        MOVWF  INDF                   ;put to destination, indirect
        BCF    FSR, 7                 ;back to source bank
        INCF   FSR                    ;point at next pair
        DECFSZ Count                  ;one less to do, skip if done
        GOTO   SCLoop                 ;if not done, loop for another
;skips to here when done...

Good luck!

---------------------------------------------------
Barry King
Engineering Manager
NRG Systems "Measuring the Wind's Energy"
barryspamKILLspamnrgsystems.com
"The witty saying has been deleted due to limited EPROM space"

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