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
-Donc read the X following.
This language is Frenglish

Posted: Sat Apr 14, 2007 11:48 pm
by thefool
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