/** ** shiftscl.c ---- shift and copy an array (scanline) ** for 1bpp and 4bpp frame driver blit operations ** ** Copyright (c) 1998 Hartmut Schirmer ** ** This file is part of the GRX graphics library. ** ** The GRX graphics library is free software; you can redistribute it ** and/or modify it under some conditions; see the "copying.grx" file ** for details. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** **/ #include "libgrx.h" #include "highlow.h" void _GR_shift_scanline(GR_int8u **dst, GR_int8u **src, int ws, int shift, int planes) { int plane; GRX_ENTER(); if (shift <= 0) { shift = -shift; for (plane = 0; plane < planes; ++plane) { GR_int8u *s = *(src++) + ws; GR_int8u *d = *(dst++) + ws; # if defined(__GNUC__) && defined(__i386__) int _dummy_, w = ws; /* sad but true: the x86 bytesex forces this inefficient code :( */ asm volatile ("\n" " movb (%0),%%ch \n" " jmp 1f \n" " .align 4,0x90 \n" "1: decl %0 \n" " movb %%ch,%%al \n" " movb (%0),%%ah \n" " movb %%ah,%%ch \n" " shrl %%cl,%%eax \n" " movb %%al,(%1) \n" " decl %1 \n" " decl %2 \n" " jne 1b \n" " shrb %%cl,%%ch \n" " movb %%ch,(%1) " : "=r" ((void *)s), "=r" ((void *)d), "=r" ((int)w), "=c" (_dummy_) : "0" ((void *)s), "1" ((void *)d), "2" ((int)w), "3" ((int)shift) : "ax" ); # else int w = ws; do { --s; *(d--) = highlowP(s)>>shift; } while (--w); *d = *s >> shift; # endif } } else { shift = 8-shift; for (plane = 0; plane < planes; ++plane) { GR_int8u *s = *(src++); GR_int8u *d = *(dst++); # if defined(__GNUC__) && defined(__i386__) int _dummy_, w = ws; asm volatile ("\n" " movb (%0),%%ch \n" " jmp 1f \n" " .align 4,0x90 \n" "1: incl %0 \n" " movb %%ch,%%ah \n" " movb (%0),%%al \n" " movb %%al,%%ch \n" " shrl %%cl,%%eax \n" " movb %%al,(%1) \n" " incl %1 \n" " decl %2 \n" " jne 1b " : "=r" ((void *)s), "=r" ((void *)d), "=r" ((int)w), "=c" (_dummy_) : "0" ((void *)s), "1" ((void *)d), "2" ((int)w), "3" ((int)shift) : "ax" ); # else int w = ws; do { *(d++) = highlowP(s)>>shift /* sh */; s++; } while (--w); # endif } } GRX_LEAVE(); }