Page 1 of 2

CopyMemory with modulo

Posted: Fri Apr 13, 2007 3:52 pm
by freddix
Hi,

does it exist any command like CopyMemory to do the same job but with a modulo for both source and target,only for target and, only for source ?

It's to make something similar to old Amiga blitter in the past for those that know about this.

Posted: Fri Apr 13, 2007 4:06 pm
by Kaeru Gaman
I don't completely understand, what you mean by "modulo for source/target"

do you mean something like copying the same 1024byte block repetively into 16K target?

or just modifying the adresses to creating a kind of map-display that switches at the end of a big source-area to the beginning of it within the same copy-loop?

I'm quite sure there will be a really performant solution if we know what you finally want to achieve... ;)

Posted: Sat Apr 14, 2007 12:16 pm
by freddix
no.

In fact, imagine, I want from source :
-Read 16 bytes
-Donc read the X following.
-Read 16 bytes
-Donc read the X following.
-Read 16 bytes
-Donc read the X following.
XXX times ...

Target :
-Write 16 bytes
-Donc Write the Y following.
-Write 16 bytes
-Donc Write the Y following.
-Write 16 bytes
-Donc Write the Y following.
XXX times ...

X and Y are modulos.

Here is what I though ;)

Posted: Sat Apr 14, 2007 12:45 pm
by thefool
Donc??

Posted: Sat Apr 14, 2007 1:02 pm
by Kaeru Gaman
hm.. and where come the 16 in your example from?

so that would be Copy(Length, Skip1, Skip2),
for your example Length=16, Skip1=X, Skip2=Y

but that is not really "modulo", modulo would be "read L, skip X-L"

however, a function like that is easy to program yourself.

I think it is not implemented, because the use of this isn't too obvious...

...what is the use of it?

Posted: Sat Apr 14, 2007 7:10 pm
by freddix
it's exactly modulo ;)


From Source :
Read X(.l), Skip Y(.l), Read X(.l), skip Y(.l) .... Z Times

From Target:
Write X(.l), Skip W(.l), Write X(.l), Skip W(.l) .... Z Times too.

Modulo can be different from source and target (that's why I used Y and W here ;))

Posted: Sat Apr 14, 2007 7:18 pm
by Kaeru Gaman
Kaeru Gaman wrote:however, a function like that is easy to program yourself.

I think it is not implemented, because the use of this isn't too obvious...

...what is the use of it?

Posted: Sat Apr 14, 2007 10:18 pm
by Anonymous
Donc / thus :D
-Donc read the X following.
This language is Frenglish :D

Posted: Sat Apr 14, 2007 11:48 pm
by thefool
:lol:
Yeah after thinking a bit i got the idea. I have been having a bit french in school, and i have been down there a few times too :)

Posted: Sun Apr 15, 2007 6:55 am
by wilbert
Like this ?

Code: Select all

; *Src    = source
; *Dst    = destination
; bpCycle = bytes to copy per cycle
; rSkip   = read skip value
; wSkip   = write skip value
; cycles  = number of cycles

Procedure CopyMemoryM(*Src, *Dst, bpCycle, rSkip, wSkip, cycles)
 ; push registers used
 !push ecx
 !push esi
 !push edi
 !pushfd
 ; set direction for movsb
 !cld
 ; retrieve some parameters
 !mov esi,[esp + 20]
 !mov edi,[esp + 24]
 !mov ecx,[esp + 40]
 ; exit if bpCycle or cycles are 0
 !mov eax,[esp + 28]
 !and eax,ecx
 !jz cmm_exit
 ; main loop
 !cmm_loop1:
 !mov eax,[esp + 28]
 !cmm_loop2:
 !movsb
 !dec eax
 !jnz cmm_loop2
 !add esi,[esp + 32]
 !add edi,[esp + 36]
 !dec ecx
 !jnz cmm_loop1
 ; pop registers used and exit
 !cmm_exit:
 !popfd
 !pop edi
 !pop esi
 !pop ecx
EndProcedure 

S.s = "This is a source string to see if the copy function works as it should"
D.s = "                                                                      "

CopyMemoryM(@S, @D, 4, 1, 3, 6)

Debug D

Posted: Sun Apr 15, 2007 8:21 am
by freddix
wow, directly in ASM :) Great :)
it's what I'm looking for.
In fact, I know how to code it in PureBASIC but I wanted the faster available.
(I did this in the past on 68000 asm for Amiga)
And coded in ASM must be fast :)

Thanks.

Posted: Sun Apr 15, 2007 9:06 am
by wilbert
Writing out the movsb instruction is a bit faster

Code: Select all

Procedure CopyMemoryM(*Src, *Dst, bpCycle, rSkip, wSkip, cycles)
 ; push registers used
 !push ecx
 !push edx
 !push esi
 !push edi
 !pushfd
 ; retrieve some parameters
 !mov esi,[esp + 24]
 !mov edi,[esp + 28]
 !mov ecx,[esp + 44]
 ; exit if bpCycle or cycles are 0
 !mov edx,[esp + 32]
 !and edx,ecx
 !jz cmm_exit
 ; main loop
 !cmm_loop1:
 !mov edx,[esp + 32]
 !cmm_loop2:
 !mov al,[esi]
 !mov [edi],al
 !inc esi
 !inc edi
 !dec edx
 !jnz cmm_loop2
 !add esi,[esp + 36]
 !add edi,[esp + 40]
 !dec ecx
 !jnz cmm_loop1
 ; pop registers used and exit
 !cmm_exit:
 !popfd
 !pop edi
 !pop esi
 !pop edx
 !pop ecx
EndProcedure
but requires a bit more code.
If you don't copy very much data you probably won't notice the difference.

I'm still wondering what practical use it has :?

Posted: Sun Apr 15, 2007 12:11 pm
by freddix
it's for small data copying but several copy to do :p

Thanks.

Posted: Mon Apr 16, 2007 11:43 am
by dell_jockey
alors, I still don't really get it. Where would this be useful, can somebody please explain?

thanks!

Posted: Mon Apr 16, 2007 12:25 pm
by wilbert
The code I posted before contained a bug. Here's a fixed version with two examples at the end of the code. I suppose the function can be useful for repetitive copy of data.

Code: Select all

; *Src    = source
; *Dst    = destination
; bpCycle = bytes to copy per cycle
; rSkip   = read skip value
; wSkip   = write skip value
; cycles  = number of cycles

Procedure CopyMemoryM(*Src, *Dst, bpCycle, rSkip, wSkip, cycles)
 ; push registers used
 !push ecx
 !push edx
 !push esi
 !push edi
 !pushfd
 ; retrieve some parameters
 !mov ecx,[esp + 44]
 !mov edx,[esp + 32]
 !mov esi,[esp + 24]
 !mov edi,[esp + 28]
 ; exit if bpCycle or cycles are 0
 !and ecx,ecx
 !jz cmm_exit
 !and edx,edx
 !jz cmm_exit
 ; main loop
 !cmm_loop1:
 !push edx
 !cmm_loop2:
 !mov al,[esi]
 !mov [edi],al
 !inc esi
 !inc edi
 !dec edx
 !jnz cmm_loop2
 !pop edx
 !add esi,[esp + 36]
 !add edi,[esp + 40]
 !dec ecx
 !jnz cmm_loop1
 ; pop registers used and exit
 !cmm_exit:
 !popfd
 !pop edi
 !pop esi
 !pop edx
 !pop ecx
EndProcedure 


; filling a string with another one

S1.s = Space(50)
CopyMemoryM(@"12345", @S1, 5, -5, 0, 10)
Debug S1

; pairs of numbers

S2.s = Space(26)
CopyMemoryM(@"1234567890", @S2, 2, -1, 1, 9)
Debug S2