FreeCalypso > hg > fc-tourmaline
diff src/cs/drivers/drv_app/r2d/lcds/R2D_vertical_lcd_i.c @ 0:4e78acac3d88
src/{condat,cs,gpf,nucleus}: import from Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:23:26 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/drivers/drv_app/r2d/lcds/R2D_vertical_lcd_i.c Fri Oct 16 06:23:26 2020 +0000 @@ -0,0 +1,3016 @@ +#if (R2D_PIXEL_DEPTH == 32) +#define R2D_PIXEL_DOWN_OUT(a) (0) +#define R2D_PIXEL_UP_OUT(a) (0) +#else +#define R2D_PIXEL_DOWN_OUT(a) (a>>R2D_PIXEL_DEPTH) +#define R2D_PIXEL_UP_OUT(a) (a<<R2D_PIXEL_DEPTH) +#endif + +#if (R2D_ASM == R2D_ON) + +// All below global are modified in the context of a blit_rect and +// the use of the self modifying blit_rect is protected by +// a semaphore + +extern T_R2D_DRAWING_MODE r2d_g_old_mode; +extern R2D_BOOLEAN r2d_g_old_use_foreground; +extern INT32 r2d_g_old_srcdst; +extern UINT32 r2d_g_old_foreground_pixelvalue; +extern UINT32 r2d_g_old_background_pixelvalue; + +extern void r2d_blit_la(UINT32 *a); +extern void r2d_blit_lb(UINT32 *a); + +#endif + +extern BOOLEAN IND_r2d_color_framebuffer_foreground_pixel(UINT32 lcd_value,T_R2D_GC_PTR src_gc); + + +#define r2d_get_texture_color() ((T_R2D_ANCHORED_TEXTURE*)(gc->background_texture))->pattern[((x-gc->s_org_x)&texture_mask)*texture_size+((ty-gc->s_org_y)&texture_mask)] + + + + + + +void r2d_write_lcd_line(T_R2D_GC* gc,INT16 x,INT16 y,INT16 nb,R2D_BOOLEAN background) +{ + UINT32 *p; + UINT16 tmp,ty; +// UINT32 temp; + UINT32 pixel_cache,pixel_value; + INT16 current_y,count; + UINT32 new_value,current_value; + T_R2D_DRAWING_OP dop; + INT16 texture_mask,texture_size; + + ty=y; // True y + + if (gc->background_texture!=NULL) + { + texture_mask=~((-1)<<gc->background_texture->size); + texture_size=1<<gc->background_texture->size; + } + + dop=gc->drawing_op; + + if (nb==0) + goto r2d_fail_line; + + p=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words; + + switch(((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->kind) + { + case 0:// LCD format with hard coded dimensions + + { + + // Get position of the memory word containing the pixel +#if (R2D_REFRESH == R2D_VERTICAL) + p+=((x*R2D_MWHEIGHT+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#else + p+=((x*R2D_MWWIDTH+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#endif + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + //printf("Error : frame_buffer overflow\n"); + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + + #endif + goto r2d_fail_line; + } + + + + // Get the pixel position into the memory word + new_value=0; + y=y & R2D_WORD_POSITION_MASK; + y=y << R2D_PIXEL_POS_TO_BIT_POS; + pixel_cache=*p; + current_y=0; + current_value=pixel_cache; + if (y!=0) + { + do + { + new_value =R2D_PIXEL_DOWN_OUT(new_value); + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + } while (current_y != y); + } + count=0; + #if (R2D_DITHERING == R2D_OFF) + if (background) + pixel_value=((T_R2D_GC*)gc)->background_pixel_value; + else + pixel_value=((T_R2D_GC*)gc)->foreground_pixel_value; + #endif + do + { + #if (R2D_DITHERING == R2D_ON) + if (background) + { + if (gc->background_texture!=NULL) + pixel_value=r2d_get_texture_color(); + else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_background_dithered_cache,x,ty); + + } + else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_foreground_dithered_cache,x,ty); + #endif + + #if (R2D_DITHERING == R2D_OFF) + if ((background) && (gc->background_texture!=NULL)) + pixel_value=r2d_get_texture_color(); + #endif + + ty++; + + new_value =R2D_PIXEL_DOWN_OUT(new_value); + + new_value|=((dop(current_value & R2D_PIXEL_MASK,pixel_value) & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + if (current_y==(1<<R2D_MEMORY_WORD)) + { + current_y=0; + *p++=new_value; + current_value=*p; + } + count++; + } while (count<nb); + + while(current_y != (1<<R2D_MEMORY_WORD)) + { + new_value =R2D_PIXEL_DOWN_OUT(new_value) ; + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + } + *p++=new_value; + + } + break; + case R2D_LCD_KIND: // LCD format with any size + { + INT16 height,width; + height=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->height; + width=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->width; + + // Get position of the memory word containing the pixel + #if (R2D_REFRESH == R2D_VERTICAL) + p+=((x*R2D_ALIGNED_MWLENGTH(height)+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#else + p+=((x*R2D_ALIGNED_MWLENGTH(width)+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#endif + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_line; + } + + + + // Get the pixel position into the memory word + new_value=0; + y=y & R2D_WORD_POSITION_MASK; + y=y << R2D_PIXEL_POS_TO_BIT_POS; + pixel_cache=*p; + current_y=0; + current_value=pixel_cache; + if (y!=0) + { + do + { + new_value =R2D_PIXEL_DOWN_OUT(new_value) ; + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + } while (current_y != y); + } + count=0; + #if (R2D_DITHERING == R2D_OFF) + if (background) + pixel_value=((T_R2D_GC*)gc)->background_pixel_value; + else + pixel_value=((T_R2D_GC*)gc)->foreground_pixel_value; + #endif + do + { + #if (R2D_DITHERING == R2D_ON) + if (background) + if (gc->background_texture!=NULL) + pixel_value=r2d_get_texture_color(); + else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_background_dithered_cache,x,ty); + else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_foreground_dithered_cache,x,ty); + #endif + + #if (R2D_DITHERING == R2D_OFF) + if ((background) && (gc->background_texture!=NULL)) + pixel_value=r2d_get_texture_color(); + #endif + + ty++; + + new_value =R2D_PIXEL_DOWN_OUT(new_value); + new_value|=((dop(current_value & R2D_PIXEL_MASK,pixel_value) & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + if (current_y==(1<<R2D_MEMORY_WORD)) + { + current_y=0; + *p++=new_value; + current_value=*p; + } + count++; + } while (count<nb); + + while(current_y != (1<<R2D_MEMORY_WORD)) + { + new_value =R2D_PIXEL_DOWN_OUT(new_value); + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + } + *p++=new_value; + + + } + break; + + case R2D_FULL_KIND: // LCD format with any size + { + INT16 height,width; + height=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->height; + width=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->width; + + + // Get position of the memory word containing the pixel +#if (R2D_REFRESH == R2D_VERTICAL) + p+=((x*height+y)); +#else + p+=((x*width+y)); +#endif + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_line; + } + + + + // Get the pixel position into the memory word + y=0; + new_value=0; + pixel_cache=*p; + current_y=0; + current_value=pixel_cache; + count=0; + if (background) + { + pixel_value=((T_R2D_GC*)gc)->background_pixel_value; + } + else + { + pixel_value=((T_R2D_GC*)gc)->foreground_pixel_value; + } + + do + { + + if ((background) && (gc->background_texture!=NULL)) + pixel_value=r2d_get_texture_color(); + + ty++; + new_value=dop(current_value,pixel_value); + current_y=0; + *p++=new_value; + current_value=*p; + count++; + } while (count<nb); + + + + } + break; + } + r2d_fail_line:tmp=0; // Just because one needs code after a label +} + +void r2d_arc_write_lcd_line(T_R2D_GC* gc,INT16 x,INT16 y, + INT16 org_x,INT16 org_y,INT16 nb, + T_R2D_ARC_REGION *rgn,R2D_BOOLEAN background) +{ + UINT32 *p; + UINT16 tmp,ty; +// UINT32 temp; + UINT32 pixel_cache,pixel_value; + INT32 current_y,count; + UINT32 new_value,current_value; + T_R2D_DRAWING_OP dop; + INT16 texture_mask,texture_size; + INT32 sides,sidee; + BOOLEAN start_filling=FALSE; + + sides=r2d_get_point_side((INT16)(x-org_x),(INT16)(y-org_y),rgn->sa,rgn->sb); + sidee=r2d_get_point_side((INT16)(x-org_x),(INT16)(y-org_y),rgn->ea,rgn->eb); + + ty=y; // True y + + if (gc->background_texture!=NULL) + { + texture_mask=~((-1)<<gc->background_texture->size); + texture_size=1<<gc->background_texture->size; + } + + dop=gc->drawing_op; + + if (nb==0) + goto r2d_fail_line; + + p=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words; + + switch(((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->kind) + { + case 0:// LCD format with hard coded dimensions + + { + + // Get position of the memory word containing the pixel +#if (R2D_REFRESH == R2D_VERTICAL) + p+=((x*R2D_MWHEIGHT+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#else + p+=((x*R2D_MWWIDTH+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#endif + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + //printf("Error : frame_buffer overflow\n"); + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + + #endif + goto r2d_fail_line; + } + + + + // Get the pixel position into the memory word + new_value=0; + y=y & R2D_WORD_POSITION_MASK; + y=y << R2D_PIXEL_POS_TO_BIT_POS; + pixel_cache=*p; + current_y=0; + current_value=pixel_cache; + if (y!=0) + { + do + { + new_value =R2D_PIXEL_DOWN_OUT(new_value); + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + } while (current_y != y); + } + count=0; + #if (R2D_DITHERING == R2D_OFF) + if (background) + pixel_value=((T_R2D_GC*)gc)->background_pixel_value; + else + pixel_value=((T_R2D_GC*)gc)->foreground_pixel_value; + #endif + do + { + #if (R2D_DITHERING == R2D_ON) + if (background) + { + if (gc->background_texture!=NULL) + pixel_value=r2d_get_texture_color(); + else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_background_dithered_cache,x,ty); + + } + else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_foreground_dithered_cache,x,ty); + #endif + + #if (R2D_DITHERING == R2D_OFF) + if ((background) && (gc->background_texture!=NULL)) + pixel_value=r2d_get_texture_color(); + #endif + + + + new_value =R2D_PIXEL_DOWN_OUT(new_value); + + if ( + ((rgn->one_sector==0) && (sides>=0) && (sidee>=0)) + || + ((rgn->one_sector==1) && (!(!(sides>=0) && !(sidee>=0)))) + || (rgn->one_sector==2) + ) + { + if (rgn->one_sector==0) + start_filling=TRUE; + new_value|=((dop(current_value & R2D_PIXEL_MASK,pixel_value) & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + } + else + { + if (start_filling) + goto r2d_fail_line; + new_value|=(current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH) ; + } + + ty++; + sides+=-(rgn->sa>>1); + sidee+=-(rgn->ea>>1); + + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + if (current_y==(1<<R2D_MEMORY_WORD)) + { + current_y=0; + *p++=new_value; + current_value=*p; + } + count++; + } while (count<nb); + + while(current_y != (1<<R2D_MEMORY_WORD)) + { + new_value =R2D_PIXEL_DOWN_OUT(new_value) ; + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + } + *p++=new_value; + + } + break; + case R2D_LCD_KIND: // LCD format with any size + { + INT16 height,width; + height=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->height; + width=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->width; + + // Get position of the memory word containing the pixel + #if (R2D_REFRESH == R2D_VERTICAL) + p+=((x*R2D_ALIGNED_MWLENGTH(height)+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#else + p+=((x*R2D_ALIGNED_MWLENGTH(width)+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#endif + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_line; + } + + + + // Get the pixel position into the memory word + new_value=0; + y=y & R2D_WORD_POSITION_MASK; + y=y << R2D_PIXEL_POS_TO_BIT_POS; + pixel_cache=*p; + current_y=0; + current_value=pixel_cache; + if (y!=0) + { + do + { + new_value =R2D_PIXEL_DOWN_OUT(new_value) ; + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + } while (current_y != y); + } + count=0; + #if (R2D_DITHERING == R2D_OFF) + if (background) + pixel_value=((T_R2D_GC*)gc)->background_pixel_value; + else + pixel_value=((T_R2D_GC*)gc)->foreground_pixel_value; + #endif + do + { + #if (R2D_DITHERING == R2D_ON) + if (background) + if (gc->background_texture!=NULL) + pixel_value=r2d_get_texture_color(); + else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_background_dithered_cache,x,ty); + else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_foreground_dithered_cache,x,ty); + #endif + + #if (R2D_DITHERING == R2D_OFF) + if ((background) && (gc->background_texture!=NULL)) + pixel_value=r2d_get_texture_color(); + #endif + + + + new_value =R2D_PIXEL_DOWN_OUT(new_value); + + if ( + ((rgn->one_sector==0) && (sides>=0) && (sidee>=0)) + || + ((rgn->one_sector==1) && (!(!(sides>=0) && !(sidee>=0)))) + || (rgn->one_sector==2) + ) + { + if (rgn->one_sector==0) + start_filling=TRUE; + new_value|=((dop(current_value & R2D_PIXEL_MASK,pixel_value) & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + } + else + { + if (start_filling) + goto r2d_fail_line; + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + } + ty++; + sides+=-(rgn->sa>>1); + sidee+=-(rgn->ea>>1); + + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + if (current_y==(1<<R2D_MEMORY_WORD)) + { + current_y=0; + *p++=new_value; + current_value=*p; + } + count++; + } while (count<nb); + + while(current_y != (1<<R2D_MEMORY_WORD)) + { + new_value =R2D_PIXEL_DOWN_OUT(new_value); + new_value|=((current_value & R2D_PIXEL_MASK) + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; + current_value=R2D_PIXEL_DOWN_OUT(current_value); + current_y+=(1<<R2D_PIXEL_POS_TO_BIT_POS); + } + *p++=new_value; + + + } + break; + + case R2D_FULL_KIND: // LCD format with any size + { + INT16 height,width; + height=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->height; + width=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->width; + + + // Get position of the memory word containing the pixel +#if (R2D_REFRESH == R2D_VERTICAL) + p+=((x*height+y)); +#else + p+=((x*width+y)); +#endif + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_line; + } + + + + // Get the pixel position into the memory word + y=0; + new_value=0; + pixel_cache=*p; + current_y=0; + current_value=pixel_cache; + count=0; + if (background) + { + pixel_value=((T_R2D_GC*)gc)->background_pixel_value; + } + else + { + pixel_value=((T_R2D_GC*)gc)->foreground_pixel_value; + } + + do + { + + if ((background) && (gc->background_texture!=NULL)) + pixel_value=r2d_get_texture_color(); + + + if ( + ((rgn->one_sector==0) && (sides>=0) && (sidee>=0)) + || + ((rgn->one_sector==1) && (!(!(sides>=0) && !(sidee>=0)))) + || (rgn->one_sector==2) + ) + { + if (rgn->one_sector==0) + start_filling=TRUE; + new_value=dop(current_value,pixel_value); + } + else + { + if (start_filling) + goto r2d_fail_line; + new_value=current_value; + } + ty++; + sides+=-(rgn->sa>>1); + sidee+=-(rgn->ea>>1); + + current_y=0; + *p++=new_value; + current_value=*p; + count++; + } while (count<nb); + + + + } + break; + } + r2d_fail_line:tmp=0; // Just because one needs code after a label +} + +// Returns the equivalent color pixel value +// for the color kind of framebuffer +// It must be converted to RGB components +// Don't confuse with r2d_get_pixel_value which is +// just reading the cached pixel vlue from +// the graphic context. +// That routine is extracting the pixel value at position (x,y) +// from framebuffer +UINT32 r2d_get_color_pixel_value(T_R2D_GC* gc,INT16 x,INT16 y) +{ + UINT32 *p; +// UINT16 tmp; + UINT32 pixel_cache;//,new_value; + UINT32 result; + + p=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words; + + switch(((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->kind) + { + case 0: // LCD format with hard coded dimensions + { + // Get position of the memory word containing the pixel +#if (R2D_REFRESH == R2D_VERTICAL) + p+=((x*R2D_MWHEIGHT+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#else + p+=((x*R2D_MWWIDTH+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#endif + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_get_pixel; + } + + + // Get the pixel position into the memory word + y=y & R2D_WORD_POSITION_MASK; + y=y << R2D_PIXEL_POS_TO_BIT_POS; + pixel_cache=*p; + + result=(pixel_cache >> y) & R2D_PIXEL_MASK; + return((~IND_r2d_lcd_to_color(result)) & 0x00FFFFFF); + } + break; + case R2D_LCD_KIND: // LCD format with any size + { + INT16 height,width; + height=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->height; + width=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->width; + +#if (R2D_REFRESH == R2D_VERTICAL) + // Get position of the memory word containing the pixel + p+=((x*R2D_ALIGNED_MWLENGTH(height)+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#else + p+=((x*R2D_ALIGNED_MWLENGTH(width)+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#endif + + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_get_pixel; + } + + + // Get the pixel position into the memory word + y=y & R2D_WORD_POSITION_MASK; + y=y << R2D_PIXEL_POS_TO_BIT_POS; + pixel_cache=*p; + + result=(pixel_cache >> y) & R2D_PIXEL_MASK; + + return(~IND_r2d_lcd_to_color(result) & 0x00FFFFFF); + } + break; + case R2D_FULL_KIND: + { + INT16 height,width; + height=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->height; + width=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->width; + + //printf("%08X\n",p); + // Get position of the memory word containing the pixel +#if (R2D_REFRESH == R2D_VERTICAL) + p+=(x*height+y); +#else + p+=(x*width+y); +#endif + + //printf(" --> %08X for x=%d and y=%d\n",p,x,y); + + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_get_pixel; + } + + + // Get the pixel position into the memory word + y=0; + pixel_cache=*p; + + result=(~pixel_cache) & 0x00FFFFFF; + } + break; + } +r2d_fail_get_pixel:return(0); +} + +// Low level pixel drawing +// (Note that for filling a more efficient version is used +// taking into account the fact that the position +// in the framebuffer has not to be recomputed from the coordinates +// for each pixel) +void r2d_write_lcd_pixel(T_R2D_GC* gc,INT16 x,INT16 y,UINT32 pixel_value) +{ + UINT32 *p; + UINT16 tmp; + UINT32 pixel_cache,new_value; + T_R2D_DRAWING_OP dop; + + dop=gc->drawing_op; + + p=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words; + + switch(((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->kind) + { + case 0: // LCD format with hard coded dimensions + { + // Get position of the memory word containing the pixel +#if (R2D_REFRESH == R2D_VERTICAL) + p+=((x*R2D_MWHEIGHT+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#else + p+=((x*R2D_MWWIDTH+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#endif + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_pixel; + } + + + // Get the pixel position into the memory word + y=y & R2D_WORD_POSITION_MASK; + y=y << R2D_PIXEL_POS_TO_BIT_POS; + pixel_cache=*p; + + new_value=dop((pixel_cache >> y) & R2D_PIXEL_MASK,pixel_value) & R2D_PIXEL_MASK; + pixel_cache &= ~(R2D_PIXEL_MASK << y) ; + + // Write new value + pixel_cache |= (new_value << y); + *p=pixel_cache; + } + break; + case R2D_LCD_KIND: // LCD format with any size + { + INT16 height,width; + height=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->height; + width=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->width; + +#if (R2D_REFRESH == R2D_VERTICAL) + // Get position of the memory word containing the pixel + p+=((x*R2D_ALIGNED_MWLENGTH(height)+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#else + p+=((x*R2D_ALIGNED_MWLENGTH(width)+(y>>R2D_PIXELS_PER_MEMORY_WORD))); +#endif + + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_pixel; + } + + + // Get the pixel position into the memory word + y=y & R2D_WORD_POSITION_MASK; + y=y << R2D_PIXEL_POS_TO_BIT_POS; + pixel_cache=*p; + + new_value=dop((pixel_cache >> y) & R2D_PIXEL_MASK,pixel_value) & R2D_PIXEL_MASK; + pixel_cache &= ~(R2D_PIXEL_MASK << y) ; + + // Write new value + pixel_cache |= (new_value << y); + *p=pixel_cache; + + } + break; + case R2D_FULL_KIND: + { + INT16 height,width; + height=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->height; + width=((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->width; + + //printf("%08X\n",p); + // Get position of the memory word containing the pixel +#if (R2D_REFRESH == R2D_VERTICAL) + p+=(x*height+y); +#else + p+=(x*width+y); +#endif + + //printf(" --> %08X for x=%d and y=%d\n",p,x,y); + + + if ((y<0) || (x<0) || ((p<((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_memory_words) + || (p>((T_R2D_FRAMEBUFFER*)(gc->p_frame_buffer))->p_frame_buffer_end))) + { + #if (R2D_DEBUG == R2D_ON) + IND_rvf_send_trace("R2D : Framebuffer overflow",26, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + #endif + goto r2d_fail_pixel; + } + + + // Get the pixel position into the memory word + y=0; + pixel_cache=*p; + + new_value=dop(pixel_cache,pixel_value); + pixel_cache = new_value; + *p=pixel_cache; + } + break; + } + r2d_fail_pixel:tmp=0; // Just because one needs code after a label +} + + + + +#if (R2D_ASM == R2D_OFF) + + + +// For blitting, two scanning direction are required because of possible +// overlaps between src and dst + +// Shift new pixel from srcstream to dststream using variable srccache +// as a pixel cache.dstcounter allows to keep track of number +// of pixels written +// (scanning direction is down) + +#define r2d_shift_pixel_down(dststream,srccache,srccounter,srcstream) {dststream =R2D_PIXEL_DOWN_OUT(dststream); \ + dststream|=((srccache & R2D_PIXEL_MASK) \ + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) ; \ + srccache=R2D_PIXEL_DOWN_OUT(srccache); \ + srccounter--; \ + if (srccounter==0) \ + { \ + srccounter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + srccache=*++srcstream; \ + } } + + +// Scanning direction is up +#define r2d_shift_pixel_up(dststream,srccache,srccounter,srcstream) {dststream =R2D_PIXEL_UP_OUT(dststream); \ + dststream |=(srccache >> ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) & R2D_PIXEL_MASK; \ + srccache=R2D_PIXEL_UP_OUT(srccache); \ + srccounter--; \ + if (srccounter==0) \ + { \ + srccounter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + srccache=*--srcstream; \ + } } + +#endif + +// Check overlap of src and dst rectangle and return the +// horizontal and vertical scanning direction required to do the +// blit rect + +// A positive value means standard direction (increasing x and increasing y) +// When that routine is called, both rectangles are expressed in framebuffer +// coordinates and come from the same framebuffer. +// The routine is never called if dstGc and srcGc are not using the same framebuffer. +// +// INT32 used because of stack bug ? +void r2d_check_rectangle_overlap(INT16 src_x,INT16 src_y,INT16 dst_x,INT16 dst_y, +INT32 width,INT32 height, +INT32 *h_direction,INT32 *v_direction) +{ + INT16 h,v; + INT16 rx,ry; + rx=dst_x-src_x; + ry=dst_y-src_y; + + h=1; + v=1; + + if ((rx>-width) && (rx < width) && (ry>-height) && (ry<height)) + { + if (rx>0) + h=-1; + else + h=1; + if (ry>0) + v=-1; + else + v=1; + } + + *h_direction=h; + *v_direction=v; +} + + +#if (R2D_ASM == R2D_OFF) + + +static UINT32 r2d_get_pixel_value(T_R2D_GC_PTR gc,R2D_BOOLEAN foreground,INT16 x,INT16 y) +{ + UINT32 pixel_value; + if (foreground) + { + #if (R2D_DITHERING == R2D_OFF) + pixel_value=((T_R2D_GC*)gc)->foreground_pixel_value; + #else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_foreground_dithered_cache,x,y); + #endif + } + else + { + #if (R2D_DITHERING == R2D_OFF) + pixel_value=((T_R2D_GC*)gc)->background_pixel_value; + #else + pixel_value=r2d_get_dithering_matrix_entry(((T_R2D_GC*)gc)->p_background_dithered_cache,x,y); + #endif + } + return(pixel_value); +} + +// When foreground color is used, the source pixel +// is converted to the background or foreground color +// then dithered +static UINT32 r2d_convert_from_lcd_to_lcd(R2D_BOOLEAN use_foreground,UINT32 src,T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc,INT16 x,INT16 y) +{ + if (use_foreground) + { + + UINT32 pixel_value; + if (IND_r2d_lcd_foreground_pixel(src,src_gc)) + pixel_value=r2d_get_pixel_value(dst_gc,TRUE,x,y); + else + pixel_value=r2d_get_pixel_value(dst_gc,FALSE,x,y); + + return(pixel_value); + } + else return(src); +} + +static UINT32 r2d_convert_from_color_to_color(R2D_BOOLEAN use_foreground,UINT32 src,T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc,INT16 x,INT16 y) +{ + if (use_foreground) + { + + UINT32 pixel_value; + if (IND_r2d_color_framebuffer_foreground_pixel(src,src_gc)) + pixel_value=r2d_get_pixel_value(dst_gc,TRUE,x,y); + else + pixel_value=r2d_get_pixel_value(dst_gc,FALSE,x,y); + + return(pixel_value); + } + else return(src); +} + + +static UINT32 r2d_convert_from_color_to_lcd(R2D_BOOLEAN use_foreground,UINT32 src,T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc,INT16 x,INT16 y) +{ + if (use_foreground) + { + UINT32 pixel_value; + if (IND_r2d_color_framebuffer_foreground_pixel(src,src_gc)) + pixel_value=r2d_get_pixel_value(dst_gc,TRUE,x,y); + else + pixel_value=r2d_get_pixel_value(dst_gc,FALSE,x,y); + + return(pixel_value); + } + else return(IND_r2d_color_to_lcd(src,x,y)); +} + +static UINT32 r2d_convert_from_lcd_to_color(R2D_BOOLEAN use_foreground,UINT32 src,T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc,INT16 x,INT16 y) +{ + if (use_foreground) + { + UINT32 pixel_value; + if (IND_r2d_lcd_foreground_pixel(src,src_gc)) + pixel_value=r2d_get_pixel_value(dst_gc,TRUE,x,y); + else + pixel_value=r2d_get_pixel_value(dst_gc,FALSE,x,y); + + return(pixel_value); + } + else + { + return(IND_r2d_lcd_to_color(src)); + } +} + +// FOR DEBUG +//#define dop(a,b) b + +#define r2d_shift_pixel_down_and_write(dst,src) {\ + dst##value =R2D_PIXEL_DOWN_OUT(dst##value); \ + dst##value|=dop((dst##_current & R2D_PIXEL_MASK), \ + r2d_convert_from_lcd_to_lcd(use_foreground_color,\ + src##_current & R2D_PIXEL_MASK,src_gc,dst_gc,x,y)) \ + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH) ; \ + src##_current=R2D_PIXEL_DOWN_OUT(src##_current); \ + dst##_current=R2D_PIXEL_DOWN_OUT(dst##_current); \ + dst##counter--; \ + src##counter--; \ + if (src##counter==0) \ + { \ + src##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + src##_current=*++p_##src##_current; \ + } \ + if (dst##counter==0) \ + { \ + dst##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + } \ + } + +#define r2d_shift_pixel_up_and_write(dst,src) {\ + dst##value =R2D_PIXEL_UP_OUT(dst##value); \ + dst##value |=dop( \ + (dst##_current >> ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) & R2D_PIXEL_MASK, \ + r2d_convert_from_lcd_to_lcd(use_foreground_color,\ + (src##_current >> ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) & R2D_PIXEL_MASK, \ + src_gc,dst_gc,x,y)); \ + src##_current=R2D_PIXEL_UP_OUT(src##_current); \ + dst##_current=R2D_PIXEL_UP_OUT(dst##_current); \ + dst##counter--; \ + src##counter--; \ + if (src##counter==0) \ + { \ + src##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + src##_current=*--p_##src##_current; \ + } \ + if (dst##counter==0) \ + { \ + dst##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + } \ + } + +extern UINT32 r2d_lcd_or_operator(UINT32 old,UINT32 value); +// Requires shapes in graphic context coordinates +void r2d_blit_lcd_to_lcd(T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc, + T_R2D_SHAPE_PTR src_rectangle, + T_R2D_SHAPE_PTR dst_rectangle, + R2D_BOOLEAN use_foreground_color) +{ + UINT32 *p_src,*p_dst,*p_src_current,*p_dst_current,*p_src_start,*p_dst_start; + INT16 rect_width,rect_height,src_x,src_y,dst_x,dst_y; + INT16 src_offset,dst_offset,src_height,dst_height; + INT16 xnb,ynb,src_nb_rows,dst_nb_rows; + INT16 src_dy,dst_dy,end_dst_dy,end_src_dy; // distance from word boundary +// INT16 shift; // relative position (modulo a memory word) between both rectangles + // in bits + INT16 current_src_dy,current_dst_dy; + INT16 temp,dstcounter,srccounter; + + + register UINT32 dstvalue,dst_current; + register UINT32 src_current;//srcvalue; + INT32 h_direction,v_direction; + INT16 x,y; + T_R2D_DRAWING_MODE mode; + T_R2D_DRAWING_OP dop; + BOOLEAN compensate=TRUE; + + + dop=((T_R2D_GC*)dst_gc)->drawing_op; + + + + { + + p_src=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->p_memory_words; + p_dst=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_memory_words; + + rect_width=r2d_get_xmax(src_rectangle)-r2d_get_xmin(src_rectangle); + rect_height=r2d_get_ymax(src_rectangle)-r2d_get_ymin(src_rectangle); + if ((rect_width<=0) || (rect_height<=0)) + goto end_blit; + + mode=IND_r2d_get_drawing_mode(dst_gc); + + + src_x=r2d_get_xmin(src_rectangle); + src_y=r2d_get_ymin(src_rectangle); + + dst_x=r2d_get_xmin(dst_rectangle); + dst_y=r2d_get_ymin(dst_rectangle); + + src_dy=(src_y & R2D_WORD_POSITION_MASK); + dst_dy=(dst_y & R2D_WORD_POSITION_MASK); + + // Clipping convention such end_dst_dy is the first y position which must not + // be copied at the end of a column + //printf("dest y max=%d\n",r2d_get_ymax(dst_rectangle)); + end_dst_dy=((r2d_get_ymax(dst_rectangle)-1) & R2D_WORD_POSITION_MASK) ; + end_src_dy=((r2d_get_ymax(src_rectangle)-1) & R2D_WORD_POSITION_MASK) ; + + //printf("dst_dy, end_dst_dy before reverse=%d,%d\n",dst_dy,end_dst_dy); + // Number of rows is word containing last point - word containing first point + // + 1 + + // We remove - 1 because last PIXEL is at 1 from the frontier line + dst_nb_rows=R2D_ALIGNED_MWLENGTH(r2d_get_ymax(dst_rectangle)-1)-R2D_ALIGNED_MWLENGTH(dst_y)+1; + src_nb_rows=R2D_ALIGNED_MWLENGTH(r2d_get_ymax(src_rectangle)-1)-R2D_ALIGNED_MWLENGTH(src_y)+1; + + //printf("src_nb_rows %d\n",src_nb_rows); + //printf("dst_nb_rows %d\n",dst_nb_rows); + + + h_direction=1; + v_direction=1; + if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))== + ((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))) + r2d_check_rectangle_overlap(src_x,src_y,dst_x,dst_y, + rect_width,rect_height,&h_direction,&v_direction); + + //printf("h,v=%d,%d\n",h_direction,v_direction); + + +#if (R2D_REFRESH == R2D_VERTICAL) + src_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->height; + dst_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->height; +#else + src_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->width; + dst_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->width; +#endif + + src_offset=R2D_ALIGNED_MWLENGTH(src_height); + dst_offset=R2D_ALIGNED_MWLENGTH(dst_height); + + //printf("%08X,dst offset=%08X\n",p_dst,dst_offset); + + p_src_start=p_src + +((src_x*src_offset+(src_y>>R2D_PIXELS_PER_MEMORY_WORD))); + p_dst_start=p_dst + +((dst_x*dst_offset+(dst_y>>R2D_PIXELS_PER_MEMORY_WORD))); + + xnb=rect_width; + + //printf("src start %08X contains %08X\n",p_src_start,*p_src_start); + //printf("dst start %08X contains %08X\n",p_dst_start,*p_dst_start); + + //printf("rect_width %d\n",rect_width); + if (h_direction==-1) + { + x=r2d_get_xmax(dst_rectangle)-1; + p_src_start+=(rect_width-1)*src_offset; + p_dst_start+=(rect_width-1)*dst_offset; + } + else + x=r2d_get_xmin(dst_rectangle); + + //printf("src start %08X contains %08X\n",p_src_start,*p_src_start); + //printf("dst start %08X contains %08X\n",p_dst_start,*p_dst_start); + + if (v_direction==-1) + { + p_src_start+=src_nb_rows-1; + p_dst_start+=dst_nb_rows-1; + + temp=src_dy; + src_dy=end_src_dy; + end_src_dy=temp; + + temp=dst_dy; + dst_dy=end_dst_dy; + end_dst_dy=temp; + } + + + //printf("src start %08X contains %08X\n",p_src_start,*p_src_start); + //printf("dst start %08X contains %08X\n",p_dst_start,*p_dst_start); + + //printf("dst_start=%08X contains %08X\n",p_dst_start,*p_dst_start); + while(xnb!=0) + { + p_dst_current=p_dst_start; + p_src_current=p_src_start; + + //printf("xnb=%d\n",xnb); + //printf("src start %08X contains %08X\n",p_src_start,*p_src_start); + //printf("dst start %08X contains %08X\n",p_dst_start,*p_dst_start); + + + ynb=dst_nb_rows-1; + + if (v_direction==-1) + { + y=r2d_get_ymax(dst_rectangle) - 1; + current_src_dy=(1<<R2D_PIXELS_PER_MEMORY_WORD)-1; + current_dst_dy=(1<<R2D_PIXELS_PER_MEMORY_WORD)-1; + } + else + { + current_src_dy=0; + current_dst_dy=0; + y=r2d_get_ymin(dst_rectangle); + } + + dstcounter=(1<<R2D_PIXELS_PER_MEMORY_WORD); + srccounter=(1<<R2D_PIXELS_PER_MEMORY_WORD); + + dst_current=*p_dst_current; + src_current=*p_src_current; + + //printf("src_current=%08X, dst_current=%08X\n",src_current,dst_current); + temp=0; + //printf("new column\n dst=%08X\n",p_dst_current); + //printf("current_dst_dy =%d, dst_dy=%d\n",current_dst_dy,dst_dy); + dstvalue=0; + if (v_direction==-1) + { + while(current_dst_dy!=dst_dy) + { + r2d_shift_pixel_up(dstvalue,dst_current,dstcounter,p_dst_current); + current_dst_dy--; + //printf("dstcounter=%d\n",dstcounter); + y--; + } + while(current_src_dy!=src_dy) + { + + //printf("current_src_dy=%d\n",current_src_dy); + //printf("srccounter=%d\n",srccounter); + + r2d_shift_pixel_up(temp,src_current,srccounter,p_src_current); + current_src_dy--; + //printf("src_current=%08X\n",src_current); + + + } + while(ynb!=0) + { + + r2d_shift_pixel_up_and_write(dst,src); + //printf("srccounter=%d\n",srccounter); + y--; + + if (dstcounter==(1<<R2D_PIXELS_PER_MEMORY_WORD)) + { + ynb--; + + *p_dst_current--=dstvalue; + +#if (R2D_DEBUG == R2D_ON) +#if (R2D_DEBUG_WARNING == R2D_DEBUG_HIGH) + if ((p_dst_current<((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_memory_words) + || (p_dst_current>((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_frame_buffer_end)) + { + //printf("Error : frame_buffer overflow\n"); + IND_rvf_send_trace("R2D : Framebuffer overflow1",27, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + } +#endif +#endif + + current_dst_dy=(1<<R2D_PIXELS_PER_MEMORY_WORD)-1; + + dst_current=*p_dst_current; + + //printf("%08X <- %08X\n",p_dst_current,dstvalue); + + dstvalue=0; + } + + } + current_dst_dy++; + while(current_dst_dy!=end_dst_dy) + { + + r2d_shift_pixel_up_and_write(dst,src); + current_dst_dy--; + //printf("Last row %08X, %08X\n",p_dst_current,current_dst_dy); + y--; + + } + if (dstcounter==(1<<R2D_PIXELS_PER_MEMORY_WORD)) + compensate=FALSE; + while(dstcounter!=(1<<R2D_PIXELS_PER_MEMORY_WORD)) + { + + r2d_shift_pixel_up(dstvalue,dst_current,dstcounter,p_dst_current); + current_dst_dy--; + //printf(" Last row %08X\n",p_src_current); + //printf("dstcounter=%d\n",dstcounter); + y--; + + + + } + if (compensate==TRUE) + { + *++p_dst_current=dstvalue; + + } + else + { + *p_dst_current=dstvalue; + + } +#if (R2D_DEBUG == R2D_ON) +#if (R2D_DEBUG_WARNING == R2D_DEBUG_HIGH) + if ((p_dst_current<((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_memory_words) + || (p_dst_current>((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_frame_buffer_end)) + { + //printf("Error : frame_buffer overflow\n"); + IND_rvf_send_trace("R2D : Framebuffer overflow2",27, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + } +#endif +#endif + + + } + else + { + while(current_dst_dy!=dst_dy) + { + r2d_shift_pixel_down(dstvalue,dst_current,dstcounter,p_dst_current); + current_dst_dy++; + y++; + //printf("dstcounter=%d\n",dstcounter); + } + while(current_src_dy!=src_dy) + { + + r2d_shift_pixel_down(temp,src_current,srccounter,p_src_current); + current_src_dy++; + + + } + while(ynb!=0) + { + + r2d_shift_pixel_down_and_write(dst,src); + y++; + + if (dstcounter==(1<<R2D_PIXELS_PER_MEMORY_WORD)) + { + ynb--; + + + *p_dst_current++=dstvalue; +#if (R2D_DEBUG == R2D_ON) +#if (R2D_DEBUG_WARNING == R2D_DEBUG_HIGH) + if ((p_dst_current<((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_memory_words) + || (p_dst_current>((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_frame_buffer_end)) + { + char error[256]; + T_R2D_RECT *dst; + + //dst=(T_R2D_RECT*)dst_rectangle; + //sprintf(error,"%d %d %d %d",dst->ul_x,dst->ul_y, + // dst->br_x,dst->br_y); + //IND_rvf_send_trace(error,strlen(error), NULL_PARAM, + // RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + //printf("Error : frame_buffer overflow\n"); + IND_rvf_send_trace("R2D : Framebuffer overflow3",27, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + } +#endif +#endif + + current_dst_dy=0; + + dst_current=*p_dst_current; + + //printf("%08X <- %08X\n",p_dst_current,dstvalue); + + dstvalue=0; + } + + } + + current_dst_dy--; + while(current_dst_dy!=end_dst_dy) + { + + r2d_shift_pixel_down_and_write(dst,src); + current_dst_dy++; + //printf("Last row %08X\n",p_dst_current); + y++; + + } + if (dstcounter==(1<<R2D_PIXELS_PER_MEMORY_WORD)) + compensate=FALSE; + while(dstcounter!=(1<<R2D_PIXELS_PER_MEMORY_WORD)) + { + + r2d_shift_pixel_down(dstvalue,dst_current,dstcounter,p_dst_current); + current_dst_dy++; + //printf("Last row %08X\n",p_dst_current); + y++; + + } + if (compensate==TRUE) + { + *--p_dst_current=dstvalue; + } + else + { + *p_dst_current=dstvalue; + } +#if (R2D_DEBUG == R2D_ON) +#if (R2D_DEBUG_WARNING == R2D_DEBUG_HIGH) + if ((p_dst_current<((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_memory_words) + || (p_dst_current>((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_frame_buffer_end)) + { + //printf("Error : frame_buffer overflow\n"); + IND_rvf_send_trace("R2D : Framebuffer overflow4",27, NULL_PARAM, + RV_TRACE_LEVEL_ERROR, R2D_USE_ID ); + } +#endif +#endif + + } + + + dstvalue=0; + + + if (h_direction==-1) + { + p_src_start-=src_offset; + p_dst_start-=dst_offset; + x--; + } + else + { + p_src_start+=src_offset; + p_dst_start+=dst_offset; + x++; + } + + xnb--; + } + + + + + } +end_blit: dstvalue=0; +} + + +#undef r2d_shift_pixel_down_and_write +#undef r2d_shift_pixel_up_and_write + +#define r2d_shift_pixel_down_and_write(dst,src) {\ + dst##value =R2D_PIXEL_DOWN_OUT(dst##value); \ + dst##value|=dop((dst##_current & R2D_PIXEL_MASK), \ + r2d_convert_from_color_to_color(use_foreground_color,\ + src##_current & R2D_PIXEL_MASK,src_gc,dst_gc,x,y)) \ + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH) ; \ + src##_current=R2D_PIXEL_DOWN_OUT(src##_current); \ + dst##_current=R2D_PIXEL_DOWN_OUT(dst##_current); \ + dst##counter--; \ + src##counter--; \ + if (src##counter==0) \ + { \ + src##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + src##_current=*++p_##src##_current; \ + } \ + if (dst##counter==0) \ + { \ + dst##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + } \ + } + +#define r2d_shift_pixel_up_and_write(dst,src) {\ + dst##value =R2D_PIXEL_UP_OUT(dst##value); \ + dst##value |=dop( \ + (dst##_current >> ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) & R2D_PIXEL_MASK, \ + r2d_convert_from_color_to_color(use_foreground_color,\ + (src##_current >> ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) & R2D_PIXEL_MASK, \ + src_gc,dst_gc,x,y)); \ + src##_current=R2D_PIXEL_UP_OUT(src##_current); \ + dst##_current=R2D_PIXEL_UP_OUT(dst##_current); \ + dst##counter--; \ + src##counter--; \ + if (src##counter==0) \ + { \ + src##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + src##_current=*--p_##src##_current; \ + } \ + if (dst##counter==0) \ + { \ + dst##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + } \ + } + + + +// Requires shapes in graphic context coordinates +void r2d_blit_color_to_color(T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc, + T_R2D_SHAPE_PTR src_rectangle, + T_R2D_SHAPE_PTR dst_rectangle, + R2D_BOOLEAN use_foreground_color) +{ + UINT32 *p_src,*p_dst,*p_src_current,*p_dst_current,*p_src_start,*p_dst_start,value; + INT16 rect_width,rect_height,src_x,src_y,dst_x,dst_y; + INT16 src_offset,dst_offset,src_height,dst_height; + INT16 xnb,ynb,nb_rows; + INT16 x,y;//,temp; + + + INT32 h_direction,v_direction; + T_R2D_DRAWING_MODE mode; + T_R2D_DRAWING_OP dop; + + + dop=((T_R2D_GC*)dst_gc)->drawing_op; + + + + { + + p_src=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->p_memory_words; + p_dst=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_memory_words; + + rect_width=r2d_get_xmax(src_rectangle)-r2d_get_xmin(src_rectangle); + rect_height=r2d_get_ymax(src_rectangle)-r2d_get_ymin(src_rectangle); + + if ((rect_width<=0) || (rect_height<=0)) + goto end_blit_c; + + mode=IND_r2d_get_drawing_mode(dst_gc); + + + src_x=r2d_get_xmin(src_rectangle); + src_y=r2d_get_ymin(src_rectangle); + + dst_x=r2d_get_xmin(dst_rectangle); + dst_y=r2d_get_ymin(dst_rectangle); + + + // Number of rows is word containing last point - word containing first point + // + 1 + nb_rows=(r2d_get_ymax(dst_rectangle)-1)-(dst_y)+1; + //printf("nb_rows %d\n",nb_rows); + + h_direction=1; + v_direction=1; + if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))== + ((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))) + r2d_check_rectangle_overlap(src_x,src_y,dst_x,dst_y, + rect_width,rect_height,&h_direction,&v_direction); + + //printf("h,v=%d,%d\n",h_direction,v_direction); + + + #if (R2D_REFRESH == R2D_VERTICAL) + src_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->height; + dst_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->height; +#else + src_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->width; + dst_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->width; +#endif + + src_offset=(src_height); + dst_offset=(dst_height); + + //printf("%08X,dst offset=%08X\n",p_dst,dst_offset); + + p_src_start=p_src + +((src_x*src_offset+(src_y))); + p_dst_start=p_dst + +((dst_x*dst_offset+(dst_y))); + + xnb=rect_width; + + //printf("start %08X contains %08X\n",p_dst_start,*p_dst_start); + + if (h_direction==-1) + { + x=r2d_get_xmax(dst_rectangle)-1; + p_src_start+=(rect_width-1)*src_offset; + p_dst_start+=(rect_width-1)*dst_offset; + } + else + x=r2d_get_xmin(dst_rectangle); + + if (v_direction==-1) + { + p_src_start+=nb_rows-1; + p_dst_start+=nb_rows-1; + + } + + //printf("dst_start=%08X contains %08X\n",p_dst_start,*p_dst_start); + while(xnb!=0) + { + p_dst_current=p_dst_start; + p_src_current=p_src_start; + + ynb=nb_rows; // Not using - 1 since not different processing of ending word + // (which is here a pixel instead of being only a memory word) + + + + //printf("src_current=%08X, dst_current=%08X\n",src_current,dst_current); + //printf("new column\n dst=%08X\n",p_dst_current); + + if (v_direction==-1) + { + while(ynb!=0) + { + + value=*p_dst_current; + *p_dst_current--=dop(value,*p_src_current--); + y--; + + ynb--; + } + } + else + { + while(ynb!=0) + { + + value=*p_dst_current; + *p_dst_current++=dop(value,*p_src_current++); + y++; + + ynb--; + } + } + + + + if (h_direction==-1) + { + p_src_start-=src_offset; + p_dst_start-=dst_offset; + x--; + } + else + { + p_src_start+=src_offset; + p_dst_start+=dst_offset; + x++; + } + + xnb--; + } + + + + + } +end_blit_c:ynb=0; +} + + +#undef r2d_shift_pixel_down_and_write +#undef r2d_shift_pixel_up_and_write + +#define r2d_shift_pixel_down_and_write(dst,src) {\ + dst##value =r2d_convert_from_lcd_to_color(use_foreground_color,\ + src##_current & R2D_PIXEL_MASK,src_gc,dst_gc,x,y); \ + dst##value =dop(*p_dst_current,dst##value); \ + *p_##dst##_current++=dst##value;\ + src##_current=R2D_PIXEL_DOWN_OUT(src##_current); \ + src##counter--; \ + if (src##counter==0) \ + { \ + src##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + src##_current=*++p_##src##_current; \ + } \ + } + + +#define r2d_shift_pixel_up_and_write(dst,src) {\ + dst##value =r2d_convert_from_lcd_to_color(use_foreground_color,\ + src##_current & R2D_PIXEL_MASK,src_gc,dst_gc,x,y); \ + dst##value =dop(*p_dst_current,dst##value); \ + *p_##dst##_current--=dst##value;\ + src##_current=R2D_PIXEL_UP_OUT(src##_current); \ + src##counter--; \ + if (src##counter==0) \ + { \ + src##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + src##_current=*--p_##src##_current; \ + } \ + } + +// Requires shapes in graphic context coordinates +void r2d_blit_lcd_to_color(T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc, + T_R2D_SHAPE_PTR src_rectangle, + T_R2D_SHAPE_PTR dst_rectangle, + R2D_BOOLEAN use_foreground_color) +{ + UINT32 *p_src,*p_dst,*p_src_current,*p_dst_current,*p_src_start,*p_dst_start; + INT16 rect_width,rect_height,src_x,src_y,dst_x,dst_y; + INT16 src_offset,dst_offset,src_height,dst_height; + INT16 xnb,ynb,src_nb_rows,dst_nb_rows; + INT16 src_dy,dst_dy,end_dst_dy,end_src_dy; // distance from word boundary +// INT16 shift; // relative position (modulo a memory word) between both rectangles + // in bits + INT16 current_src_dy;//,current_dst_dy; + INT16 temp,srccounter;//,dstcounter; + + + register UINT32 dstvalue;//,dst_current; + register UINT32 src_current;//,srcvalue; + INT32 h_direction,v_direction; + INT16 x,y; + T_R2D_DRAWING_MODE mode; + T_R2D_DRAWING_OP dop; + + dop=((T_R2D_GC*)dst_gc)->drawing_op; + + + + + { + + p_src=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->p_memory_words; + p_dst=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_memory_words; + + rect_width=r2d_get_xmax(src_rectangle)-r2d_get_xmin(src_rectangle); + rect_height=r2d_get_ymax(src_rectangle)-r2d_get_ymin(src_rectangle); + + if ((rect_width<=0) || (rect_height<=0)) + goto end_blit_d; + + mode=IND_r2d_get_drawing_mode(dst_gc); + + + src_x=r2d_get_xmin(src_rectangle); + src_y=r2d_get_ymin(src_rectangle); + + dst_x=r2d_get_xmin(dst_rectangle); + dst_y=r2d_get_ymin(dst_rectangle); + + src_dy=src_y & R2D_WORD_POSITION_MASK; + dst_dy=dst_y & R2D_WORD_POSITION_MASK; + + // Clipping convention such end_dst_dy is the first y position which must not + // be copied at the end of a column + end_dst_dy=(r2d_get_ymax(dst_rectangle)-1) & R2D_WORD_POSITION_MASK; + end_src_dy=(r2d_get_ymax(src_rectangle)-1) & R2D_WORD_POSITION_MASK ; + + // Number of rows is word containing last point - word containing first point + // + 1 + src_nb_rows=R2D_ALIGNED_MWLENGTH(r2d_get_ymax(src_rectangle)-1)-R2D_ALIGNED_MWLENGTH(src_y) + 1; + + dst_nb_rows=(r2d_get_ymax(dst_rectangle))-(dst_y); + //printf("nb_rows %d\n",nb_rows); + + h_direction=1; + v_direction=1; + if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))== + ((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))) + r2d_check_rectangle_overlap(src_x,src_y,dst_x,dst_y, + rect_width,rect_height,&h_direction,&v_direction); + + //printf("h,v=%d,%d\n",h_direction,v_direction); + + + +#if (R2D_REFRESH == R2D_VERTICAL) + src_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->height; + dst_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->height; +#else + src_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->width; + dst_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->width; +#endif + + src_offset=R2D_ALIGNED_MWLENGTH(src_height); + dst_offset=dst_height; + + //printf("%08X,dst offset=%08X\n",p_dst,dst_offset); + + p_src_start=p_src + +((src_x*src_offset+(src_y>>R2D_PIXELS_PER_MEMORY_WORD))); + p_dst_start=p_dst + +((dst_x*dst_offset+(dst_y))); + + xnb=rect_width; + + //printf("start %08X contains %08X\n",p_dst_start,*p_dst_start); + + if (h_direction==-1) + { + x=r2d_get_xmax(dst_rectangle)-1; + p_src_start+=(rect_width-1)*src_offset; + p_dst_start+=(rect_width-1)*dst_offset; + } + else + x=r2d_get_xmin(dst_rectangle); + + if (v_direction==-1) + { + p_src_start+=src_nb_rows-1; + p_dst_start+=dst_nb_rows-1; + + temp=src_dy; + src_dy=end_src_dy; + end_src_dy=temp; + + } + + //printf("dst_start=%08X contains %08X\n",p_dst_start,*p_dst_start); + while(xnb!=0) + { + p_dst_current=p_dst_start; + p_src_current=p_src_start; + + ynb=dst_nb_rows; // No -1 since no different processing for last word + + if (v_direction==-1) + { + current_src_dy=(1<<R2D_PIXELS_PER_MEMORY_WORD)-1; + y=r2d_get_ymax(dst_rectangle)-1; + } + else + { + current_src_dy=0; + y=r2d_get_ymin(dst_rectangle); + } + + srccounter=(1<<R2D_PIXELS_PER_MEMORY_WORD); + + src_current=*p_src_current; + //printf("src_current=%08X, dst_current=%08X\n",src_current,dst_current); + temp=0; + //printf("new column\n dst=%08X\n",p_dst_current); + + //printf("src_dy=%d\n",src_dy); + + if (v_direction==-1) + { + while(current_src_dy!=src_dy) + { + + //printf("current_src_dy=%d\n",current_src_dy); + r2d_shift_pixel_up(temp,src_current,srccounter,p_src_current); + current_src_dy--; + + //printf("src_current=%08X\n",src_current); + + } + //printf("src_current=%08X, dst_current=%08X, dstvalue=%08X\n dstcounter=%08X, srccounter=%08X\n", + //src_current,dst_current,dstvalue,dstcounter,srccounter); + while(ynb!=0) + { + + r2d_shift_pixel_up_and_write(dst,src); + y--; + + ynb--; + + } + } + else + { + while(current_src_dy!=src_dy) + { + + r2d_shift_pixel_down(temp,src_current,srccounter,p_src_current); + current_src_dy++; + + + } + //printf("src_current=%08X, dst_current=%08X, dstvalue=%08X\n dstcounter=%08X, srccounter=%08X\n", + //src_current,dst_current,dstvalue,dstcounter,srccounter); + while(ynb!=0) + { + + r2d_shift_pixel_down_and_write(dst,src); + y++; + + ynb--; + + } + } + + + + + + if (h_direction==-1) + { + p_src_start-=src_offset; + p_dst_start-=dst_offset; + x--; + } + else + { + p_src_start+=src_offset; + p_dst_start+=dst_offset; + x++; + } + + xnb--; + } + + + + + } +end_blit_d:ynb=0; +} + + + +#undef r2d_shift_pixel_down_and_write +#undef r2d_shift_pixel_up_and_write + +#define r2d_shift_pixel_down_and_write(dst,src) {\ + dst##value =R2D_PIXEL_DOWN_OUT(dst##value); \ + src##_current=r2d_convert_from_color_to_lcd(use_foreground_color,\ + *p_##src##_current++,src_gc,dst_gc,x,y); \ + dst##value|=dop((dst##_current & R2D_PIXEL_MASK), \ + src##_current) \ + << ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH) ; \ + dst##_current=R2D_PIXEL_DOWN_OUT(dst##_current); \ + dst##counter--; \ + if (dst##counter==0) \ + { \ + dst##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + } \ + } + + +#define r2d_shift_pixel_up_and_write(dst,src) {\ + dst##value =R2D_PIXEL_UP_OUT(dst##value); \ + src##_current=r2d_convert_from_color_to_lcd(use_foreground_color,\ + *p_##src##_current--,src_gc,dst_gc,x,y); \ + dst##value |=dop( \ + (dst##_current >> ((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH)) & R2D_PIXEL_MASK, \ + src##_current); \ + dst##_current=R2D_PIXEL_UP_OUT(dst##_current); \ + dst##counter--; \ + if (dst##counter==0) \ + { \ + dst##counter=(1<<R2D_PIXELS_PER_MEMORY_WORD); \ + } \ + } + +// Requires shapes in graphic context coordinates +void r2d_blit_color_to_lcd(T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc, + T_R2D_SHAPE_PTR src_rectangle, + T_R2D_SHAPE_PTR dst_rectangle, + R2D_BOOLEAN use_foreground_color) +{ + UINT32 *p_src,*p_dst,*p_src_current,*p_dst_current,*p_src_start,*p_dst_start; + INT16 rect_width,rect_height,src_x,src_y,dst_x,dst_y; + INT16 src_offset,dst_offset,src_height,dst_height; + INT16 xnb,ynb,dst_nb_rows,src_nb_rows; + INT16 src_dy,dst_dy,end_dst_dy,end_src_dy; // distance from word boundary +// INT16 shift; // relative position (modulo a memory word) between both rectangles + // in bits + INT16 current_dst_dy;//,current_src_dy; + INT16 temp,dstcounter,srccounter; + + + register UINT32 dstvalue,dst_current; + register UINT32 src_current;//,srcvalue; + INT32 h_direction,v_direction; + INT16 x,y; + T_R2D_DRAWING_MODE mode; + T_R2D_DRAWING_OP dop; + BOOLEAN compensate=TRUE; + + dop=((T_R2D_GC*)dst_gc)->drawing_op; + + + + + { + + p_src=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->p_memory_words; + p_dst=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->p_memory_words; + + rect_width=r2d_get_xmax(src_rectangle)-r2d_get_xmin(src_rectangle); + rect_height=r2d_get_ymax(src_rectangle)-r2d_get_ymin(src_rectangle); + + if ((rect_width<=0) || (rect_height<=0)) + goto end_blit_e; + + mode=IND_r2d_get_drawing_mode(dst_gc); + + + src_x=r2d_get_xmin(src_rectangle); + src_y=r2d_get_ymin(src_rectangle); + + dst_x=r2d_get_xmin(dst_rectangle); + dst_y=r2d_get_ymin(dst_rectangle); + + src_dy=src_y & R2D_WORD_POSITION_MASK; + dst_dy=dst_y & R2D_WORD_POSITION_MASK; + + // Clipping convention such end_dst_dy is the first y position which must not + // be copied at the end of a column + end_dst_dy=(r2d_get_ymax(dst_rectangle)-1) & R2D_WORD_POSITION_MASK ; + end_src_dy=(r2d_get_ymax(src_rectangle)-1) & R2D_WORD_POSITION_MASK ; + + // Number of rows is word containing last point - word containing first point + // + 1 + dst_nb_rows=R2D_ALIGNED_MWLENGTH(r2d_get_ymax(dst_rectangle)-1)-R2D_ALIGNED_MWLENGTH(dst_y) + 1; + src_nb_rows=(r2d_get_ymax(src_rectangle))-(src_y); + + //printf("src_nb_rows %d\n",src_nb_rows); + //printf("dst_nb_rows %d\n",dst_nb_rows); + + h_direction=1; + v_direction=1; + if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))== + ((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))) + r2d_check_rectangle_overlap(src_x,src_y,dst_x,dst_y, + rect_width,rect_height,&h_direction,&v_direction); + + //printf("h,v=%d,%d\n",h_direction,v_direction); + + + + +#if (R2D_REFRESH == R2D_VERTICAL) + src_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->height; + dst_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->height; +#else + src_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)src_gc)->p_frame_buffer))->width; + dst_height=((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)dst_gc)->p_frame_buffer))->width; +#endif + + src_offset=src_height; + dst_offset=R2D_ALIGNED_MWLENGTH(dst_height); + + //printf("%08X,dst offset=%08X\n",p_dst,dst_offset); + + p_src_start=p_src + +((src_x*src_offset+(src_y))); + p_dst_start=p_dst + +((dst_x*dst_offset+(dst_y>>R2D_PIXELS_PER_MEMORY_WORD))); + + xnb=rect_width; + + //printf("start %08X contains %08X\n",p_dst_start,*p_dst_start); + + if (h_direction==-1) + { + x=r2d_get_xmax(dst_rectangle)-1; + p_src_start+=(rect_width-1)*src_offset; + p_dst_start+=(rect_width-1)*dst_offset; + } + else + x=r2d_get_xmin(dst_rectangle); + + if (v_direction==-1) + { + p_src_start+=src_nb_rows-1; + p_dst_start+=dst_nb_rows-1; + + temp=dst_dy; + dst_dy=end_dst_dy; + end_dst_dy=temp; + } + + + //printf("dst_start=%08X contains %08X\n",p_dst_start,*p_dst_start); + while(xnb!=0) + { + p_dst_current=p_dst_start; + p_src_current=p_src_start; + + ynb=dst_nb_rows-1; + + if (v_direction==-1) + { + y=r2d_get_ymax(dst_rectangle) - 1; + current_dst_dy=(1<<R2D_PIXELS_PER_MEMORY_WORD)-1; + } + else + { + current_dst_dy=0; + y=r2d_get_ymin(dst_rectangle); + } + + dstcounter=(1<<R2D_PIXELS_PER_MEMORY_WORD); + srccounter=(1<<R2D_PIXELS_PER_MEMORY_WORD); + + dst_current=*p_dst_current; + //printf("src_current=%08X, dst_current=%08X\n",src_current,dst_current); + temp=0; + //printf("new column\n dst=%08X\n",p_dst_current); + dstvalue=0; + //printf("current_dst_dy=%08X,dst_dy=%08X\n",current_dst_dy,dst_dy); + + if (v_direction==-1) + { + while(current_dst_dy!=dst_dy) + { + + r2d_shift_pixel_up(dstvalue,dst_current,dstcounter,p_dst_current); + current_dst_dy--; + y--; + //printf("dstcounter=%d\n",dstcounter); + + } + while(ynb!=0) + { + + r2d_shift_pixel_up_and_write(dst,src); + y--; + + if (dstcounter==(1<<R2D_PIXELS_PER_MEMORY_WORD)) + { + ynb--; + + + + *p_dst_current--=dstvalue; + current_dst_dy=(1<<R2D_PIXELS_PER_MEMORY_WORD)-1; + + dst_current=*p_dst_current; + + //printf("%08X <- %08X\n",p_dst_current,dstvalue); + + dstvalue=0; + } + + } + current_dst_dy++; + + while(current_dst_dy!=end_dst_dy) + { + + r2d_shift_pixel_up_and_write(dst,src); + current_dst_dy--; + y--; + //printf("Last row %08X, %08X\n",p_dst_current,current_dst_dy); + + } + if (dstcounter==(1<<R2D_PIXELS_PER_MEMORY_WORD)) + compensate=FALSE; + while(dstcounter!=(1<<R2D_PIXELS_PER_MEMORY_WORD)) + { + + r2d_shift_pixel_up(dstvalue,dst_current,dstcounter,p_dst_current); + current_dst_dy--; + //printf("Last row %08X\n",p_dst_current); + //printf("dstcounter=%d\n",dstcounter); + y--; + + + + } + if (compensate==TRUE) + { + *++p_dst_current=dstvalue; + + } + else + { + *p_dst_current=dstvalue; + + } + + } + else + { + while(current_dst_dy!=dst_dy) + { + + r2d_shift_pixel_down(dstvalue,dst_current,dstcounter,p_dst_current); + current_dst_dy++; + y++; + //printf("dstcounter=%d\n",dstcounter); + + } + while(ynb!=0) + { + + r2d_shift_pixel_down_and_write(dst,src); + y++; + + if (dstcounter==(1<<R2D_PIXELS_PER_MEMORY_WORD)) + { + ynb--; + + + + + *p_dst_current++=dstvalue; + current_dst_dy=0; + + dst_current=*p_dst_current; + + //printf("%08X <- %08X\n",p_dst_current,dstvalue); + + dstvalue=0; + } + + } + current_dst_dy--; + + while(current_dst_dy!=end_dst_dy) + { + + r2d_shift_pixel_down_and_write(dst,src); + current_dst_dy++; + y++; + //printf("Last row %08X\n",p_dst_current); + + } + if (dstcounter==(1<<R2D_PIXELS_PER_MEMORY_WORD)) + compensate=FALSE; + while(dstcounter!=(1<<R2D_PIXELS_PER_MEMORY_WORD)) + { + + r2d_shift_pixel_down(dstvalue,dst_current,dstcounter,p_dst_current); + current_dst_dy++; + //printf("Last row %08X\n",p_dst_current); + y++; + + + } + if (compensate==TRUE) + { + *--p_dst_current=dstvalue; + } + else + { + *p_dst_current=dstvalue; + } + } + + + //printf("src_current=%08X, dst_current=%08X, dstvalue=%08X\n dstcounter=%08X, srccounter=%08X\n", + //src_current,dst_current,dstvalue,dstcounter,srccounter); + + // One need a different processing for last word + //printf("Last row %08X,end_dst_dy=%08X,current_dy=%08X\n",p_dst_current,end_dst_dy,current_dst_dy); + + + //end_dst_dy MUST be copied + // It is at 1 from the copy bit rectangle frontier + + + + //printf("dstvalue: %08X <- %08X\n",p_dst_current,dstvalue); + + dstvalue=0; + + + if (h_direction==-1) + { + x--; + p_src_start-=src_offset; + p_dst_start-=dst_offset; + } + else + { + x++; + p_src_start+=src_offset; + p_dst_start+=dst_offset; + } + + xnb--; + } + + + + + } +end_blit_e:dstvalue=0; +} + +#endif + +/********************* + + R2D ASM MODE + +**********************/ + +#if (R2D_ASM == R2D_ON) + +#define R2D_BRANCH_INST 0xFF000000 + +/* +Patch a block of 3 instructions with a block defined +by the user. The block does not contain any branch instruction. +The branch must use a special syntax introduced by the long word +R2D_BRANCH_INST +*/ +void r2d_patch_code_block(UINT32* src,UINT32 *dst) +{ + + + if (*src == R2D_BRANCH_INST) + { + *dst++ = *(&r2d_start_branch_inst); + src++; + // PC is ahead of 8 bytes of current instruction because of prefetch + // So -8 must be used + *dst = (((((*src) - ((UINT32)dst)) - 8)>>2) & 0x0FFFFFF) | 0xEB000000; + *++dst= *(&r2d_stop_branch_inst); + } + else + { + + *dst++=*src++; + *dst++=*src++; + *dst++=*src++; + } +} + +/* +Copy one instruction of code +*/ +void r2d_patch_inst(UINT32* src,UINT32 *dst) +{ + *dst++ = *src++; +} + + +/* +Patch the sequence of instructions reading the foreground +background colors. It copies a sequence containing +two LDR and update the LDR offsets +*/ +void r2d_patch_get_color(UINT32* src,UINT32 *dst) +{ + UINT32 r,offset; + INT16 delta; + + delta=(((INT32)src-(INT32)dst)); + + r=*src++; + offset=r & 0xFFF; + offset+=delta; + offset=offset & 0xFFF; + *dst++ = (r & 0xFFFFF000) | offset; + + r=*src++; + offset=r & 0xFFF; + offset+=delta; + offset=offset & 0xFFF; + *dst++ = (r & 0xFFFFF000) | offset; + + *dst++ = *src++; +} + +/* +Patch with a branch if f is true or add a NOP +*/ +void r2d_patch_branch(UINT32 *src,UINT32 *dst,BOOLEAN f) +{ + INT32 offset; + if (f) + { + offset=(((((INT32)dst-(INT32)src))-8)>>2) & 0x00FFFFFF; + *src=(0xEA<<24) | offset; + } + else + { + *src=0xe1a0b00b; + } +} + + +/* +Replace the shift value by another one +*/ +#define R2D_MOV_OPCODE 0xD +void r2d_patch_shift(UINT32 *src,UINT32 shift,INT16 left) +{ + UINT32 data; + + data=*src; + + + // Shift addressing by default + data=data & 0xFDFFFFFF ; + + + if ((shift !=0) && (shift != 32)) + { + data=data & 0xFFFFF00F; + if (left==1) + data=data|(((shift&0x01F)<<7)&0x0F80); // LSL + else + data=data|(((shift&0x01F)<<7)&0x0F80)| 0x20; // LSR + } + else if (shift != 32) + { + data=data & 0xFFFFF00F; + data=data|(((shift&0x01F)<<7)&0x0F80); // LSL 0 + + } + else + { + data=(data & 0xFFFFF07F); // LSR 0 + + } + *src=data; +} + +void r2d_patch_moveshift(UINT32 *src,UINT32 shift,INT16 left) +{ + UINT32 data; + UINT32 dstreg; + UINT32 opcode; + + data=*src; + + dstreg=(data & 0x0F000); + dstreg=dstreg>>12; + + opcode=data & 0x01E00000; + opcode=opcode>>21; + if (opcode!=R2D_MOV_OPCODE) + dstreg=0; + + // Shift addressing by default + data=data & 0xF1FFFFFF ; + + + if ((shift !=0) && (shift != 32)) + { + if (opcode==R2D_MOV_OPCODE) + data=data & 0xFFFFF000; + else + data=data & 0xFFFFF00F; + if (left==1) + data=data|(((shift&0x01F)<<7)&0x0F80)|dstreg; // LSL + else + data=data|(((shift&0x01F)<<7)&0x0F80)| 0x20|dstreg; // LSR + } + else if (shift != 32) + { + if (opcode==R2D_MOV_OPCODE) + data=data & 0xFFFFF000; + else + data=data & 0xFFFFF00F; + data=data|(((shift&0x01F)<<7)&0x0F80)|dstreg; // LSL 0 + + } + else + { + //data=(data & 0xFFFFF07F); // LSR 32 + data=(data & 0xFFFFF000) | 0x02000000; // LSR 32 + + } + *src=data; +} +/* +Patch the const table contained in the .text section +with the new foreground and background values +*/ +void r2d_patch_color_conversion(T_R2D_GC_PTR gc) +{ + UINT32 *p; + + p=&r2d_blit_foreground; + *p=((T_R2D_GC*)gc)->foreground_pixel_value; + + p=&r2d_blit_background; + *p=((T_R2D_GC*)gc)->background_pixel_value; + +} + +void r2d_patch_blit(T_R2D_GC_PTR dst_gc,T_R2D_DRAWING_MODE mode, + R2D_BOOLEAN use_foreground_color,INT32 srcdst) +{ + // Patch mode + +extern R2D_BOOLEAN r2d_g_old_use_foreground; +extern INT32 r2d_g_old_srcdst; + + if (r2d_g_old_mode != mode) + { + r2d_g_old_mode=mode; + r2d_patch_code_block(r2d_get_asm_drawing_op(dst_gc,mode),&r2d_sb_down1); + r2d_patch_code_block(r2d_get_asm_drawing_op(dst_gc,mode),&r2d_sb_down2); + r2d_patch_code_block(r2d_get_asm_drawing_op(dst_gc,mode),&r2d_sa_up1); + r2d_patch_code_block(r2d_get_asm_drawing_op(dst_gc,mode),&r2d_sa_up2); + } + + // Meaning of variables names + // Last word is [ab]_(down1|down2|up1|up2) + // a or b is the blit version (blit_a oe blit_b) + // down described which version of the macro is used + // (down or up one) and the number is used to differentiate + // the calls to the macro + + // For the prefix, sft_ is for part of the code where a shift must be + // patched. For instance: sft_dst_n_a_up1 + // The second part says if the shift is for a src, dst or other + // n means noraml shift like R2D_PIXEL_DEPTH + // The n means complementd for shift as (1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH + + // Patch color detection + if (r2d_g_old_use_foreground != use_foreground_color) + { + r2d_g_old_use_foreground=use_foreground_color; + if (use_foreground_color) + { + if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC *)dst_gc)->p_frame_buffer))->kind!=R2D_FULL_KIND) + { + r2d_patch_code_block(&r2d_lcd_start_foreground_pixel,&r2d_sdb_down1); + r2d_patch_code_block(&r2d_lcd_start_foreground_pixel,&r2d_sdb_down2); + r2d_patch_code_block(&r2d_lcd_start_foreground_pixel,&r2d_sda_up1); + r2d_patch_code_block(&r2d_lcd_start_foreground_pixel,&r2d_sda_up2); + } + else + { + r2d_patch_code_block(&r2d_color_start_foreground_pixel,&r2d_sdb_down1); + r2d_patch_code_block(&r2d_color_start_foreground_pixel,&r2d_sdb_down2); + r2d_patch_code_block(&r2d_color_start_foreground_pixel,&r2d_sda_up1); + r2d_patch_code_block(&r2d_color_start_foreground_pixel,&r2d_sda_up2); + } + + r2d_patch_color_conversion(dst_gc); + r2d_g_old_foreground_pixelvalue=((T_R2D_GC*)dst_gc)->foreground_pixel_value; + r2d_g_old_background_pixelvalue=((T_R2D_GC*)dst_gc)->background_pixel_value; + + + r2d_patch_get_color(&r2d_start_get_color,&r2d_scb_down1); + r2d_patch_get_color(&r2d_start_get_color,&r2d_scb_down2); + r2d_patch_get_color(&r2d_start_get_color,&r2d_sca_up1); + r2d_patch_get_color(&r2d_start_get_color,&r2d_sca_up2); + } + else + { + + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sdb_down1); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sdb_down2); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sda_up1); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sda_up2); + + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_scb_down1); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_scb_down2); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sca_up1); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sca_up2); + } + } + else + { + if (use_foreground_color) + { + if ((r2d_g_old_foreground_pixelvalue != ((T_R2D_GC*)dst_gc)->foreground_pixel_value) + || + (r2d_g_old_background_pixelvalue != ((T_R2D_GC*)dst_gc)->background_pixel_value)) + { + r2d_patch_color_conversion(dst_gc); + r2d_g_old_foreground_pixelvalue=((T_R2D_GC*)dst_gc)->foreground_pixel_value; + r2d_g_old_background_pixelvalue=((T_R2D_GC*)dst_gc)->background_pixel_value; + } + + } + } + + if (r2d_g_old_srcdst != srcdst) + { + r2d_g_old_srcdst=srcdst; + + // Path color conversion + if (srcdst==R2D_LCDLCD) + { + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sconvcolb_down1); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sconvcolb_down2); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sconvcola_up1); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sconvcola_up2); + + // write_shift_pixel_down + r2d_patch_branch(&r2d_skip_load_src_a_up1,&r2d_no_null_src_counter_a,FALSE);//src + r2d_patch_branch(&r2d_skip_load_src_a_up2,&r2d_end_a_up2,FALSE);//src + + // write_shift_pixel_up + r2d_patch_branch(&r2d_skip_load_src_b_down1,&r2d_no_null_src_counter_b,FALSE);//src + r2d_patch_branch(&r2d_skip_load_src_b_down2,&r2d_end_b_down2,FALSE);//src + + + + r2d_patch_branch(&r2d_skip_shift_down_downa,&r2d_end_downa,FALSE);// dst + r2d_patch_branch(&r2d_skip_shift_down_downb,&r2d_end_downb,FALSE);//src + r2d_patch_branch(&r2d_skip_shift_down_downb,&r2d_end_downc,FALSE);//dst + + r2d_patch_branch(&r2d_skip_shift_up_upa,&r2d_end_upa,FALSE);//dst + r2d_patch_branch(&r2d_skip_shift_up_upb,&r2d_end_upb,FALSE);//src + r2d_patch_branch(&r2d_skip_shift_up_upc,&r2d_end_upc,FALSE);//dst + + r2d_patch_inst(&r2d_never_write,&r2d_always_read_b_down1); + r2d_patch_inst(&r2d_never_write,&r2d_always_read_b_down2); + r2d_patch_inst(&r2d_never_write,&r2d_always_read_a_up1); + r2d_patch_inst(&r2d_never_write,&r2d_always_read_a_up2); + + + } + + if (srcdst==R2D_COLORCOLOR) + { + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sconvcolb_down1); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sconvcolb_down2); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sconvcola_up1); + r2d_patch_code_block(&r2d_lcd_start_nothing,&r2d_sconvcola_up2); + + // write_shift_pixel_down + r2d_patch_branch(&r2d_skip_load_src_a_up1,&r2d_no_null_src_counter_a,TRUE);//src + r2d_patch_branch(&r2d_skip_load_src_a_up2,&r2d_end_a_up2,TRUE);//src + + // write_shift_pixel_up + r2d_patch_branch(&r2d_skip_load_src_b_down1,&r2d_no_null_src_counter_b,TRUE);//src + r2d_patch_branch(&r2d_skip_load_src_b_down2,&r2d_end_b_down2,TRUE);//src + + + + r2d_patch_branch(&r2d_skip_shift_down_downa,&r2d_end_downa,TRUE);// dst + r2d_patch_branch(&r2d_skip_shift_down_downb,&r2d_end_downb,TRUE);//src + r2d_patch_branch(&r2d_skip_shift_down_downb,&r2d_end_downc,TRUE);//dst + + r2d_patch_branch(&r2d_skip_shift_up_upa,&r2d_end_upa,TRUE);//dst + r2d_patch_branch(&r2d_skip_shift_up_upb,&r2d_end_upb,TRUE);//src + r2d_patch_branch(&r2d_skip_shift_up_upc,&r2d_end_upc,TRUE);//dst + + r2d_patch_inst(&r2d_always_read_down,&r2d_always_read_b_down1); + r2d_patch_inst(&r2d_always_read_down,&r2d_always_read_b_down2); + r2d_patch_inst(&r2d_always_read_up,&r2d_always_read_a_up1); + r2d_patch_inst(&r2d_always_read_up,&r2d_always_read_a_up2); + } + + if ((srcdst==R2D_COLORLCD)) + { + r2d_patch_code_block(&r2d_start_color_to_lcd,&r2d_sconvcolb_down1); + r2d_patch_code_block(&r2d_start_color_to_lcd,&r2d_sconvcolb_down2); + r2d_patch_code_block(&r2d_start_color_to_lcd,&r2d_sconvcola_up1); + r2d_patch_code_block(&r2d_start_color_to_lcd,&r2d_sconvcola_up2); + + // write_shift_pixel_down + r2d_patch_branch(&r2d_skip_load_src_a_up1,&r2d_no_null_src_counter_a,TRUE);//src + r2d_patch_branch(&r2d_skip_load_src_a_up2,&r2d_end_a_up2,TRUE);//src + + // write_shift_pixel_up + r2d_patch_branch(&r2d_skip_load_src_b_down1,&r2d_no_null_src_counter_b,TRUE);//src + r2d_patch_branch(&r2d_skip_load_src_b_down2,&r2d_end_b_down2,TRUE);//src + + + + r2d_patch_branch(&r2d_skip_shift_down_downa,&r2d_end_downa,FALSE);// dst + r2d_patch_branch(&r2d_skip_shift_down_downb,&r2d_end_downb,TRUE);//src + r2d_patch_branch(&r2d_skip_shift_down_downb,&r2d_end_downc,FALSE);//dst + + r2d_patch_branch(&r2d_skip_shift_up_upa,&r2d_end_upa,FALSE);//dst + r2d_patch_branch(&r2d_skip_shift_up_upb,&r2d_end_upb,TRUE);//src + r2d_patch_branch(&r2d_skip_shift_up_upc,&r2d_end_upc,FALSE);//dst + + r2d_patch_inst(&r2d_always_read_down,&r2d_always_read_b_down1); + r2d_patch_inst(&r2d_always_read_down,&r2d_always_read_b_down2); + r2d_patch_inst(&r2d_always_read_up,&r2d_always_read_a_up1); + r2d_patch_inst(&r2d_always_read_up,&r2d_always_read_a_up2); + } + + + + if ((srcdst==R2D_LCDCOLOR)) + { + r2d_patch_code_block(&r2d_start_lcd_to_color,&r2d_sconvcolb_down1); + r2d_patch_code_block(&r2d_start_lcd_to_color,&r2d_sconvcolb_down2); + r2d_patch_code_block(&r2d_start_lcd_to_color,&r2d_sconvcola_up1); + r2d_patch_code_block(&r2d_start_lcd_to_color,&r2d_sconvcola_up2); + + // write_shift_pixel_down + r2d_patch_branch(&r2d_skip_load_src_a_up1,&r2d_no_null_src_counter_a,FALSE);//src + r2d_patch_branch(&r2d_skip_load_src_a_up2,&r2d_end_a_up2,FALSE);//src + + // write_shift_pixel_up + r2d_patch_branch(&r2d_skip_load_src_b_down1,&r2d_no_null_src_counter_b,FALSE);//src + r2d_patch_branch(&r2d_skip_load_src_b_down2,&r2d_end_b_down2,FALSE);//src + + + + r2d_patch_branch(&r2d_skip_shift_down_downa,&r2d_end_downa,TRUE);// dst + r2d_patch_branch(&r2d_skip_shift_down_downb,&r2d_end_downb,FALSE);//src + r2d_patch_branch(&r2d_skip_shift_down_downb,&r2d_end_downc,TRUE);//dst + + r2d_patch_branch(&r2d_skip_shift_up_upa,&r2d_end_upa,TRUE);//dst + r2d_patch_branch(&r2d_skip_shift_up_upb,&r2d_end_upb,FALSE);//src + r2d_patch_branch(&r2d_skip_shift_up_upc,&r2d_end_upc,TRUE);//dst + + r2d_patch_inst(&r2d_never_write,&r2d_always_read_b_down1); + r2d_patch_inst(&r2d_never_write,&r2d_always_read_b_down2); + r2d_patch_inst(&r2d_never_write,&r2d_always_read_a_up1); + r2d_patch_inst(&r2d_never_write,&r2d_always_read_a_up2); + } + + // Patch writing subroutines + // Remove part of code not required when dst is R2D color + // framebuffer (some branch are used to skip the parts) + if ((srcdst==R2D_COLORCOLOR) || (srcdst==R2D_LCDCOLOR)) + { + r2d_patch_inst(&r2d_always_write_down,&r2d_swb_down1); + r2d_patch_inst(&r2d_always_write_down,&r2d_swb_down2); + r2d_patch_inst(&r2d_always_write_up,&r2d_swa_up1); + r2d_patch_inst(&r2d_always_write_up,&r2d_swa_up2); + + r2d_patch_branch(&r2d_skip_color_proc_a,&r2d_end_ynb_color_dst_a,TRUE); + r2d_patch_branch(&r2d_skip_color_proc_b,&r2d_end_ynb_color_dst_b,TRUE); + r2d_patch_branch(&r2d_skip_color_dst_a,&r2d_enda,TRUE); + r2d_patch_branch(&r2d_skip_color_dst_b,&r2d_endb,TRUE); + } + else + { + r2d_patch_inst(&r2d_never_write,&r2d_swb_down1); + r2d_patch_inst(&r2d_never_write,&r2d_swb_down2); + r2d_patch_inst(&r2d_never_write,&r2d_swa_up1); + r2d_patch_inst(&r2d_never_write,&r2d_swa_up2); + + r2d_patch_branch(&r2d_skip_color_proc_a,&r2d_end_ynb_color_dst_a,FALSE); + r2d_patch_branch(&r2d_skip_color_proc_b,&r2d_end_ynb_color_dst_b,FALSE); + r2d_patch_branch(&r2d_skip_color_dst_a,&r2d_enda,FALSE); + r2d_patch_branch(&r2d_skip_color_dst_b,&r2d_endb,FALSE); + } + + + // Update or restore shifts related to src + if ((srcdst==R2D_COLORCOLOR) || (srcdst==R2D_COLORLCD)) + { + // Patch list for write_shift_pixel_down + r2d_patch_shift(&r2d_sft_src_c_b_down1,0,1); + r2d_patch_shift(&r2d_sft_src_c_b_down2,0,1); + + r2d_patch_shift(&r2d_sft_b_c_b_down1,0,0); + r2d_patch_shift(&r2d_sft_b_c_b_down2,0,0); + + r2d_patch_shift(&r2d_sft_srcb__b_down1,0,0); // Read already done + r2d_patch_shift(&r2d_sft_srcb__b_down2,0,0); // No need to make free area + + // Patch list for write_shift_pixel_up + r2d_patch_shift(&r2d_sft_src_c_a_up1,0,0); + r2d_patch_shift(&r2d_sft_src_c_a_up2,0,0); + + r2d_patch_shift(&r2d_sft_b_c_a_up1,0,0); + r2d_patch_shift(&r2d_sft_b_c_a_up2,0,0); + + r2d_patch_shift(&r2d_sft_srcb__a_up1,0,1); // Read already done + r2d_patch_shift(&r2d_sft_srcb__a_up2,0,1); // No need to make free area + + // Patch list for shift_pixel_down + r2d_patch_shift(&r2d_sft_src_c_downb,0,1); + r2d_patch_moveshift(&r2d_sft_srcb_n_downb,32,0); + + // Patch list for shift_pixel_up + r2d_patch_shift(&r2d_sft_src_c_upb,0,0); + r2d_patch_moveshift(&r2d_sft_srcb_n_upb,32,1); + + } + else + { + // Patch list for write_shift_pixel_down + r2d_patch_shift(&r2d_sft_src_c_b_down1,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,1); + r2d_patch_shift(&r2d_sft_src_c_b_down2,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,1); + + r2d_patch_shift(&r2d_sft_b_c_b_down1,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + r2d_patch_shift(&r2d_sft_b_c_b_down2,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + + r2d_patch_shift(&r2d_sft_srcb__b_down1,R2D_PIXEL_DEPTH,0); + r2d_patch_shift(&r2d_sft_srcb__b_down2,R2D_PIXEL_DEPTH,0); + + // Patch list for write_shift_pixel_up + r2d_patch_shift(&r2d_sft_src_c_a_up1,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + r2d_patch_shift(&r2d_sft_src_c_a_up2,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + + r2d_patch_shift(&r2d_sft_b_c_a_up1,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + r2d_patch_shift(&r2d_sft_b_c_a_up2,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + + r2d_patch_shift(&r2d_sft_srcb__a_up1,R2D_PIXEL_DEPTH,1); + r2d_patch_shift(&r2d_sft_srcb__a_up2,R2D_PIXEL_DEPTH,1); + + // Patch list for shift_pixel_down + r2d_patch_shift(&r2d_sft_src_c_downb,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,1); + r2d_patch_moveshift(&r2d_sft_srcb_n_downb,R2D_PIXEL_DEPTH,0); + + // Patch list for shift_pixel_up + r2d_patch_shift(&r2d_sft_src_c_upb,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + r2d_patch_moveshift(&r2d_sft_srcb_n_upb,R2D_PIXEL_DEPTH,1); + } + + + + // Update (or restore) shifts related to dst + if ((srcdst==R2D_COLORCOLOR) || (srcdst==R2D_LCDCOLOR)) + { + // Patch list for write_shift_pixel_down + r2d_patch_moveshift(&r2d_sft_dst_n_b_down1,32,0); // Shift when dst is R2D color + // framebuffer. + // Only instructions using dst + // are impacted + r2d_patch_moveshift(&r2d_sft_dst_n_b_down2,32,0); + + r2d_patch_shift(&r2d_sft_dstc__b_down1,0,0); // Already read + r2d_patch_shift(&r2d_sft_dstc__b_down2,0,0); // No need to make free area + + r2d_patch_shift(&r2d_sft_dstb_c_b_down1,0,1); + r2d_patch_shift(&r2d_sft_dstb_c_b_down2,0,1); + r2d_patch_shift(&r2d_sft_d_c_b_down1,0,0); + r2d_patch_shift(&r2d_sft_d_c_b_down2,0,0); + r2d_patch_shift(&r2d_sft_dstc_c_b_down1,0,1); + r2d_patch_shift(&r2d_sft_dstc_c_b_down2,0,1); + + + + // Patch list for write_shift_pixel_up + r2d_patch_moveshift(&r2d_sft_dst_n_a_up1,32,1); + r2d_patch_moveshift(&r2d_sft_dst_n_a_up2,32,1); + + r2d_patch_shift(&r2d_sft_dstc__a_up1,0,1); // Already read + r2d_patch_shift(&r2d_sft_dstc__a_up2,0,1); // No need to make free area + + r2d_patch_shift(&r2d_sft_b_c_a_up1,0,0); + r2d_patch_shift(&r2d_sft_b_c_a_up2,0,0); + + + + // Patch list for shift_pixel_down + r2d_patch_moveshift(&r2d_sft_dst_n_downa,32,0); + r2d_patch_moveshift(&r2d_sft_dst_n_downb,32,0); + r2d_patch_moveshift(&r2d_sft_dst_n_downc,32,0); + + r2d_patch_shift(&r2d_sft_src_c_downa,0,1); + r2d_patch_moveshift(&r2d_sft_srcb_n_downa,32,0); + r2d_patch_shift(&r2d_sft_src_c_downc,0,1); + r2d_patch_moveshift(&r2d_sft_srcb_n_downc,32,0); + + + // Patch list for shift_pixel_up + r2d_patch_moveshift(&r2d_sft_dst_n_upa,32,1); + r2d_patch_moveshift(&r2d_sft_dst_n_upb,32,1); + r2d_patch_moveshift(&r2d_sft_dst_n_upc,32,1); + + r2d_patch_shift(&r2d_sft_src_c_upa,0,0); + r2d_patch_moveshift(&r2d_sft_srcb_n_upa,32,1); + r2d_patch_shift(&r2d_sft_src_c_upc,0,0); + r2d_patch_moveshift(&r2d_sft_srcb_n_upc,32,1); + + + } + else + { + + + // Patch list for write_shift_pixel_down + r2d_patch_moveshift(&r2d_sft_dst_n_b_down1,R2D_PIXEL_DEPTH,0); // Shift when dst is R2D color + // framebuffer. + // Only instructions using dst + // are impacted + r2d_patch_moveshift(&r2d_sft_dst_n_b_down2,R2D_PIXEL_DEPTH,0); + + r2d_patch_shift(&r2d_sft_dstc__b_down1,R2D_PIXEL_DEPTH,0); + r2d_patch_shift(&r2d_sft_dstc__b_down2,R2D_PIXEL_DEPTH,0); + + r2d_patch_shift(&r2d_sft_dstb_c_b_down1,((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH),1); + r2d_patch_shift(&r2d_sft_dstb_c_b_down2,((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH),1); + r2d_patch_shift(&r2d_sft_d_c_b_down1,((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH),0); + r2d_patch_shift(&r2d_sft_d_c_b_down2,((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH),0); + r2d_patch_shift(&r2d_sft_dstc_c_b_down1,((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH),1); + r2d_patch_shift(&r2d_sft_dstc_c_b_down2,((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH),1); + + // Patch list for write_shift_pixel_up + r2d_patch_moveshift(&r2d_sft_dst_n_a_up1,R2D_PIXEL_DEPTH,1); + r2d_patch_moveshift(&r2d_sft_dst_n_a_up2,R2D_PIXEL_DEPTH,1); + + r2d_patch_shift(&r2d_sft_dstc__a_up1,R2D_PIXEL_DEPTH,1); + r2d_patch_shift(&r2d_sft_dstc__a_up2,R2D_PIXEL_DEPTH,1); + + r2d_patch_shift(&r2d_sft_b_c_a_up1,((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH),0); + r2d_patch_shift(&r2d_sft_b_c_a_up2,((1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH),0); + + + // Patch list for shift_pixel_down + r2d_patch_moveshift(&r2d_sft_dst_n_downa,R2D_PIXEL_DEPTH,0); + r2d_patch_moveshift(&r2d_sft_dst_n_downb,R2D_PIXEL_DEPTH,0); + r2d_patch_moveshift(&r2d_sft_dst_n_downc,R2D_PIXEL_DEPTH,0); + + r2d_patch_shift(&r2d_sft_src_c_downa,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,1); + r2d_patch_moveshift(&r2d_sft_srcb_n_downa,R2D_PIXEL_DEPTH,0); + r2d_patch_shift(&r2d_sft_src_c_downc,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,1); + r2d_patch_moveshift(&r2d_sft_srcb_n_downc,R2D_PIXEL_DEPTH,0); + + + // Patch list for shift_pixel_up + r2d_patch_moveshift(&r2d_sft_dst_n_upa,R2D_PIXEL_DEPTH,1); + r2d_patch_moveshift(&r2d_sft_dst_n_upb,R2D_PIXEL_DEPTH,1); + r2d_patch_moveshift(&r2d_sft_dst_n_upc,R2D_PIXEL_DEPTH,1); + + r2d_patch_shift(&r2d_sft_src_c_upa,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + r2d_patch_moveshift(&r2d_sft_srcb_n_upa,R2D_PIXEL_DEPTH,1); + r2d_patch_shift(&r2d_sft_src_c_upc,(1<<R2D_MEMORY_WORD) - R2D_PIXEL_DEPTH,0); + r2d_patch_moveshift(&r2d_sft_srcb_n_upc,R2D_PIXEL_DEPTH,1); + + } + + } +} + + +#endif