--- BasiliskII/src/Unix/video_blit.h 2000/09/23 06:51:46 1.2 +++ BasiliskII/src/Unix/video_blit.h 2002/01/15 14:58:37 1.6 @@ -1,7 +1,7 @@ /* * video_blit.h - Video/graphics emulation, blitters * - * Basilisk II (C) 1997-2000 Christian Bauer + * Basilisk II (C) 1997-2002 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,79 +18,97 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef FB_BLIT_1 +#ifndef FB_DEPTH +# error "Undefined screen depth" +#endif + +#if !defined(FB_BLIT_1) && (FB_DEPTH <= 16) # error "Undefined 16-bit word blit function" #endif -#ifndef FB_BLIT_2 +#if !defined(FB_BLIT_2) # error "Undefined 32-bit word blit function" #endif -#ifndef FB_DEPTH -# error "Undefined screen depth" +#if !defined(FB_BLIT_4) +# error "Undefined 64-bit word blit function" #endif static void FB_FUNC_NAME(uint8 * dest, const uint8 * source, uint32 length) { +#define DEREF_WORD_PTR(ptr, ofs) (((uint16 *)(ptr))[(ofs)]) +#define DEREF_LONG_PTR(ptr, ofs) (((uint32 *)(ptr))[(ofs)]) +#define DEREF_QUAD_PTR(ptr, ofs) (((uint64 *)(ptr))[(ofs)]) + +#ifndef UNALIGNED_PROFITABLE #if FB_DEPTH <= 8 // Align source and dest to 16-bit word boundaries - if (FB_DEPTH <= 8 && ((unsigned long) source) & 1) { + if (((unsigned long) source) & 1) { *dest++ = *source++; length -= 1; } #endif - // source and dest are mutually aligned - uint16 * swp = ((uint16 *)source); - uint16 * dwp = ((uint16 *) dest ); - -#if FB_DEPTH <= 8 - if (length >= 2) { -#endif - #if FB_DEPTH <= 16 // Align source and dest to 32-bit word boundaries if (((unsigned long) source) & 2) { - const uint16 val = *swp++; - FB_BLIT_1(*dwp++, val); + FB_BLIT_1(DEREF_WORD_PTR(dest, 0), DEREF_WORD_PTR(source, 0)); + dest += 2; source += 2; length -= 2; } #endif +#endif - // Blit 4-byte words - if (length >= 4) { - const int remainder = (length / 4) % 8; - uint32 * slp = (uint32 *)swp + remainder; - uint32 * dlp = (uint32 *)dwp + remainder; + // Blit 8-byte words + if (length >= 8) { + const int remainder = (length / 8) % 8; + source += remainder * 8; + dest += remainder * 8; - int n = ((length / 4) + 7) / 8; + int n = ((length / 8) + 7) / 8; switch (remainder) { case 0: do { - slp += 8; dlp += 8; - FB_BLIT_2(dlp[-8], slp[-8]); - case 7: FB_BLIT_2(dlp[-7], slp[-7]); - case 6: FB_BLIT_2(dlp[-6], slp[-6]); - case 5: FB_BLIT_2(dlp[-5], slp[-5]); - case 4: FB_BLIT_2(dlp[-4], slp[-4]); - case 3: FB_BLIT_2(dlp[-3], slp[-3]); - case 2: FB_BLIT_2(dlp[-2], slp[-2]); - case 1: FB_BLIT_2(dlp[-1], slp[-1]); + dest += 64; source += 64; + FB_BLIT_4(DEREF_QUAD_PTR(dest, -8), DEREF_QUAD_PTR(source, -8)); + case 7: FB_BLIT_4(DEREF_QUAD_PTR(dest, -7), DEREF_QUAD_PTR(source, -7)); + case 6: FB_BLIT_4(DEREF_QUAD_PTR(dest, -6), DEREF_QUAD_PTR(source, -6)); + case 5: FB_BLIT_4(DEREF_QUAD_PTR(dest, -5), DEREF_QUAD_PTR(source, -5)); + case 4: FB_BLIT_4(DEREF_QUAD_PTR(dest, -4), DEREF_QUAD_PTR(source, -4)); + case 3: FB_BLIT_4(DEREF_QUAD_PTR(dest, -3), DEREF_QUAD_PTR(source, -3)); + case 2: FB_BLIT_4(DEREF_QUAD_PTR(dest, -2), DEREF_QUAD_PTR(source, -2)); + case 1: FB_BLIT_4(DEREF_QUAD_PTR(dest, -1), DEREF_QUAD_PTR(source, -1)); } while (--n > 0); } } + // There could be one long left to blit + if (length & 4) { + FB_BLIT_2(DEREF_LONG_PTR(dest, 0), DEREF_LONG_PTR(source, 0)); +#if FB_DEPTH <= 16 + dest += 4; + source += 4; +#endif + } + #if FB_DEPTH <= 16 - // There might remain one word to blit + // There could be one word left to blit if (length & 2) { - uint16 * const s = (uint16 *)(((uint8 *)swp) + length - 2); - uint16 * const d = (uint16 *)(((uint8 *)dwp) + length - 2); - FB_BLIT_1(*d, *s); + FB_BLIT_1(DEREF_WORD_PTR(dest, 0), DEREF_WORD_PTR(source, 0)); +#if FB_DEPTH <= 8 + dest += 2; + source += 2; +#endif } #endif #if FB_DEPTH <= 8 - } + // There could be one byte left to blit + if (length & 1) + *dest = *source; #endif + +#undef DEREF_LONG_PTR +#undef DEREF_WORD_PTR } #undef FB_FUNC_NAME @@ -103,6 +121,10 @@ static void FB_FUNC_NAME(uint8 * dest, c #undef FB_BLIT_2 #endif +#ifdef FB_BLIT_4 +#undef FB_BLIT_4 +#endif + #ifdef FB_DEPTH #undef FB_DEPTH #endif