Archived

This topic is now archived and is closed to further replies.

buffers & assembler

This topic is 6596 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I suggest you use simple and more efficient code. Move 160 into ecx then simply rep movsd (keep your code to setup edi and esi first). Do this for each line. This will move 640 bytes at a time (you stil need to increment esi to right the offset after each transfer). I assume you're in 8 bit colour mode, otherwise you'll need to move twice that. I'd recommend you use (or have an option to use) the DDraw blitter though, since most graphics cards today can accelerate this sort of function and make it faster than you can do it.

Oh, you also didn't include any code to push your registers before you use them, and pop them when you're done (remember FILO order).

Good luck

Starfall

Share this post


Link to post
Share on other sites
The buffer is located in the system area so I can't use hardware acceleration (can I?).

I was told that VC++ 6.0 automatically pops and pushes registers.

Putting the labels in the _asm{} block generates a lot of errors (maybe they must be typed differently?).

Share this post


Link to post
Share on other sites
VC6 may well push and pop automatically - I use VC5. Personally I could see reasons for not wanting it to do that but I suppose there's a way to turn it off.

I've been told labels in ASM code do nasty things in Borland too, though in VC5 they work well enough for me. You shouldn't need them if you just use rep movsd though.

Though the buffer is in the system memory, you will still get system to video h/w acceleration on many modern cards (use the dx diags software to see if you can on your specific card). It's often noticeably faster than doing things yourself, so it's worth at least having the option there.

Regards

Starfall

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I don't understand what you're trying
to do, but this might help.
void Copy(void *dest, const void *src, int count)
{
__asm {
mov ecx, count
mov esi, src
mov edi, dest
mov ebx, ecx
shr ecx, 2
and ebx, 3
rep movsd
mov ecx, ebx
rep movsb
}
}

Share this post


Link to post
Share on other sites
If you really want to do it in software, than I agree you need to use rep movsd. Also, don't use the loop instruction; EVER. It is very slow, and should be taken out of your instruction vocabulary. It takes about 5 cycles, where a dec/jnz set will pair and take only 1 cycle.

Rock

Share this post


Link to post
Share on other sites
I have found the solution.
For those interested here's the code:
void buffer_to_backsurface(void){
_asm{
mov ecx,76800
mov edi,backsurface
mov esi,buffer
add esi,32
xor edx,edx
};
Looper:
_asm{
inc edx
cmp edx,161
jnz Store
mov edx,1
add esi,64
};
Store:
_asm{
movsd
loop Looper
};
};
Now there is a problem. I need the pointer to the attached backsurface (I used the screen as backsurface in the code above).
Rock2000:I will look at the loop problem.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Ok, Rock is right get 'loop' out of yer asm vocab and that now!
But you should also try to avoid string instructions that are slow as an elephant on molasses on 486 'n' upp.
clever loop unrolling can give you soo much more..
And have you considred MMX?

Share this post


Link to post
Share on other sites
At first, for some reason I too had a problem with the labels in the _asm blocks, but somehow it worked itself out and now everything is peachy. This is with VC5. Maybe I played with the setting or something. Has anyone else found a problem with this?

[This message has been edited by Gromit (edited November 18, 1999).]

Share this post


Link to post
Share on other sites
I have a 704x640 8bit buffer and a 640x480 primary surface (two borders of 32x32 pixels) I have wrote a transfer routine in assembler but it doesn't seem to work.
Here is the code:
void buffer_to_backsurface(void){
_asm{
mov ecx,78600 //copy 4x76800=307200 (640x480) bytes
mov edi,backsurface //store pointer to the backsurface
mov esi,buffer //load pointer to the buffer
add esi,32 //add 32 pixels (screenborder)
xor edx,edx //counter edx to ZERO
};
Looper:
_asm{
inc edx //counting horizontal pixels
cmp edx,161 //hit a border(640/4=160)+1
jnz Store //if not jump to store
xor edx,edx //set the counter to ZERO
add esi,64 //skip 64 pixels (32+32 next line)
};
Store:
_asm{
movsd //store (esi->edi)
loop Looper //and loop
};
};

But it doesn't seem to work (programmed in VC++ 6.0 & directX).
Anyone has found an error in it?

Share this post


Link to post
Share on other sites