LCD13XX.c
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:110k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/GUI
  4. *                        Universal graphic software for embedded applications
  5. *
  6. *                       (c) Copyright 2002, Micrium Inc., Weston, FL
  7. *                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
  8. *
  9. *              礐/GUI is protected by international copyright laws. Knowledge of the
  10. *              source code may not be used to write a similar product. This file may
  11. *              only be used in accordance with a license and should not be redistributed
  12. *              in any way. We appreciate your understanding and fairness.
  13. *
  14. ----------------------------------------------------------------------
  15. File        : LCD13XX.C
  16. Purpose     : Driver for LCDs using a single Seiko Epson SED13XX controllers
  17.               This version supports a single LCD controller
  18.               in (almost) any hardware configuration. The following
  19.               derivatives are currently supported:
  20.               SED1352
  21.               SED1354
  22.               SED1356     (With/Without BitBlt engine support)
  23.               SED1374
  24.               SED1375
  25.               SED13806
  26.               Other Epson LCD controllers are very similar and could
  27.               be covered by this driver as well, but have not been
  28.               tested.
  29. ----------------------------------------------------------------------   
  30. ---------------------------LIST OF CONFIG SWITCHES--------------------
  31. The following is a list of additional configuration switches for this
  32. driver. These switches might not be listed in the manual, because
  33. the manual mainly covers the general config switches which are
  34. supported by all drivers.
  35. ----------------------------------------------------------------------
  36. define ----------------------Explanation------------------------------
  37. LCD_SWAP_BYTE_ORDER          Activate if high low bytes are swapped
  38.                              Default: 0
  39. LCD_WRITE_MEM32(Off,Data32)  This macro accelerates display access
  40.                              if defined by allowing the CPU to write
  41.                              32 bits at a time to the controller.
  42.                              (For 32 bits CPUs only and only if the
  43.                              BUS interface unit can automatically
  44.                              convert this to 2 16 bit accesses
  45. LCD_OPTIMIZE                 Controls the use of optimized routines.
  46.                              If 1, several (speed) optimizations are used.
  47.                              Default: ON (1)
  48. LCD_USE_BITBLT               This switch controls the use of optimized routines
  49.                               with SED1356 bitblt engine.
  50.                              If 1, the optimized routines with bitblt access are used.
  51.                              The default value depends of LCD_BITSPERPIXEL: (4  ) -> 0, (8,15) -> 1
  52. LCD_ENABLE_REG_ACCESS()    
  53. LCD_ENABLE_MEM_ACCESS()      In most systems (and with most LCD-controllers)
  54.                              registers / memory can be accessed at
  55.                              different addresses. However, in some
  56.                              systems, it could be necessary to exec
  57.                              code in order to be able to access the
  58.                              registers or memory. This code should
  59.                              then be placed in these macros (rather
  60.                              than the actual access macros, which
  61.                              would be slowed down)
  62. LCD_DATAADR                  define adress if video memory can be treated
  63.                              like regular memory
  64.                              (will speed up driver)
  65. ----------------------------------------------------------------------
  66. Known problems or limitations with current version
  67. ----------------------------------------------------------------------
  68. none
  69. ----------------------------------------------------------------------
  70. Open issues
  71. ----------------------------------------------------------------------
  72. None
  73. ---------------------------END-OF-HEADER------------------------------
  74. */
  75. #include <stddef.h>           /* needed for definition of NULL */
  76. #include "LCD_Private.H"      /* private modul definitions & config */
  77. #include "GUI_Private.H"
  78. #include "GUIDebug.h"
  79. #include "LCD_0.h"            /* Defines for first display */
  80. // extern U8  LCD_Buffer [LCD_XSIZE*LCD_YSIZE];
  81. extern U8  LCD_Buffer [];
  82. // 对 Video RAM 区的读写操作.
  83. #define LCD_READ_MEM(Off)            LCD_Buffer[Off]
  84. #define LCD_WRITE_MEM(Off,data)      LCD_Buffer[Off]=data
  85. #define LCD_READ_REG(Off)            0
  86. #define LCD_WRITE_REG(Off,data)      
  87. #if (LCD_CONTROLLER/100 == 13) && (LCD_CONTROLLER/10 != 133) 
  88.       && (!defined(WIN32) | defined(LCD_SIMCONTROLLER))
  89. /*
  90.         *********************************************************
  91.         *                                                       *
  92.         *           Compiler specific settings                  *
  93.         *                                                       *
  94.         *********************************************************
  95. */
  96. #ifdef WIN32   /* Avoid warnings in MS-compiler */
  97.   #pragma warning(disable : 4244)  // warning C4244: '=' : conversion from 'long ' to 'unsigned char ', possible loss of data
  98.   #pragma warning(disable : 4761)  // warning C4761: integral size mismatch in argument; conversion supplied
  99. #endif
  100. /*
  101. *********************************************************
  102. *
  103. *           Controller renumbering
  104. *
  105. *********************************************************
  106.   EPSON decided to rename all of their controllers. In order to
  107.   be able to work with old and new numbers, we simply map the old ones
  108.   to the new ones.
  109. */
  110. #if LCD_CONTROLLER == 1386
  111.   #undef LCD_CONTROLLER
  112.   #define LCD_CONTROLLER 13806
  113. #endif
  114. /*
  115.         *********************************************************
  116.         *                                                       *
  117.         *           Defaults for configuration                  *
  118.         *                                                       *
  119.         *********************************************************
  120. */
  121. /* Switch for support of multiple pages.
  122.  Only available with certain LCD-controllers */
  123. #ifndef LCD_SUPPORT_PAGING
  124.   #define LCD_SUPPORT_PAGING            (0)
  125. #endif
  126. #ifndef LCD_SCHEDULE_CNT
  127.   #define LCD_SCHEDULE_CNT              (0)
  128. #endif
  129. #ifndef LCD_NUM_CONTROLLERS
  130.   #define LCD_NUM_CONTROLLERS           (1)
  131. #endif
  132. #ifndef LCD_BUSWIDTH
  133.   #define LCD_BUSWIDTH                  (16)
  134. #endif
  135. #ifndef LCD_OPTIMIZE
  136.   #define LCD_OPTIMIZE                (1)
  137. #endif
  138. #if (LCD_CONTROLLER == 1356) || (LCD_CONTROLLER == 13806)
  139.   #ifndef LCD_USE_BITBLT
  140.     #if ((LCD_BITSPERPIXEL == 16) || (LCD_BITSPERPIXEL == 8 )) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY  == 0)
  141.       #define LCD_USE_BITBLT            (1)
  142.     #else
  143.       #define LCD_USE_BITBLT            (0)
  144.     #endif
  145.   #else
  146.     #if (LCD_MIRROR_Y)
  147.       #error BITBLT engine does not support LCD_MIRROR_Y = 1!
  148.     #endif
  149.     #if (LCD_SWAP_XY)
  150.       #error BITBLT engine does not support LCD_SWAP_XY = 1!
  151.     #endif
  152.   #endif
  153. #else
  154.   #define LCD_USE_BITBLT                (0)
  155. #endif
  156. #ifndef LCD_ENABLE_REG_ACCESS
  157.   #define LCD_ENABLE_REG_ACCESS()
  158. #endif
  159. #ifndef LCD_ENABLE_MEM_ACCESS
  160.   #define LCD_ENABLE_MEM_ACCESS()
  161. #endif
  162. #ifndef STATIC
  163.   #define STATIC static
  164. #endif
  165. /*
  166.         *********************************************************
  167.         *                                                       *
  168.         *           Defines for configuration simulation        *
  169.         *                                                       *
  170.         *********************************************************
  171. */
  172. #if defined(WIN32) && !defined(USE_PC_HARDWARE)
  173.   void SIM_WriteMem8(unsigned int Off, int Data);
  174.   void SIM_WriteReg8(unsigned int Off, int Data);
  175.   int  SIM_ReadMem8(unsigned int Off);
  176.   int  SIM_ReadReg8(unsigned int Off);
  177.   void SIM_WriteMem16(unsigned int Off, int Data);
  178.   void SIM_WriteReg16(unsigned int Off, int Data);
  179.   int  SIM_ReadMem16(unsigned int Off);
  180.   int  SIM_ReadReg16(unsigned int Off);
  181.   #undef  LCD_READ_MEM
  182.   #undef  LCD_READ_REG
  183.   #undef  LCD_WRITE_MEM
  184.   #undef  LCD_WRITE_REG
  185.   #if LCD_BUSWIDTH==8
  186.     #define LCD_READ_MEM(Off)       SIM_ReadMem8(Off)
  187.     #define LCD_WRITE_MEM(Off,Data) SIM_WriteMem8(Off, Data)
  188.     #define LCD_READ_REG(Off)       SIM_ReadReg8(Off)
  189.     #define LCD_WRITE_REG(Off,Data) SIM_WriteReg8(Off, Data)
  190.   #elif LCD_BUSWIDTH==16
  191.     #define LCD_READ_MEM(Off)       SIM_ReadMem16(Off)
  192.     #define LCD_WRITE_MEM(Off,Data) SIM_WriteMem16(Off, Data)
  193.     #define LCD_READ_REG(Off)       SIM_ReadReg16(Off)
  194.     #define LCD_WRITE_REG(Off,Data) SIM_WriteReg16(Off, Data)
  195.   #endif
  196. #elif defined(WIN32) && defined(USE_PC_HARDWARE)
  197.   void PC_WriteMem8(unsigned int Off, int Data);
  198.   void PC_WriteReg8(unsigned int Off, int Data);
  199.   int  PC_ReadMem8(unsigned int Off);
  200.   int  PC_ReadReg8(unsigned int Off);
  201.   void PC_WriteMem16(unsigned int Off, int Data);
  202.   void PC_WriteReg16(unsigned int Off, int Data);
  203.   int  PC_ReadMem16(unsigned int Off);
  204.   int  PC_ReadReg16(unsigned int Off);
  205.   #undef  LCD_READ_MEM
  206.   #undef  LCD_READ_REG
  207.   #undef  LCD_WRITE_MEM
  208.   #undef  LCD_WRITE_REG
  209.   #if LCD_BUSWIDTH==8
  210.     #define LCD_READ_MEM(Off)       PC_ReadMem8(Off)
  211.     #define LCD_WRITE_MEM(Off,Data) PC_WriteMem8(Off, Data)
  212.     #define LCD_READ_REG(Off)       PC_ReadReg8(Off)
  213.     #define LCD_WRITE_REG(Off,Data) PC_WriteReg8(Off, Data)
  214.   #else
  215.     #define LCD_READ_MEM(Off)       PC_ReadMem16(Off)
  216.     #define LCD_WRITE_MEM(Off,Data) PC_WriteMem16(Off, Data)
  217.     #define LCD_READ_REG(Off)       PC_ReadReg16(Off)
  218.     #define LCD_WRITE_REG(Off,Data) PC_WriteReg16(Off, Data)
  219.   #endif
  220. #endif
  221. /********************************************************
  222. *
  223. *           Remap Hardware macros
  224. *
  225. *********************************************************
  226. */
  227. #if LCD_NUM_DISPLAYS ==1 /* Use single display macros */
  228. #else
  229.   #if LCD_DISPLAY_INDEX == 0     /* First display in a multi-display configuration */
  230.     #define LCD_READ_MEM(Off)       LCD_READ_MEM_0(Off)
  231.     #define LCD_WRITE_MEM(Off,Data) LCD_WRITE_MEM_0(Off,Data)
  232.     #define LCD_READ_REG(Off)       LCD_READ_REG_0(Off)
  233.     #define LCD_WRITE_REG(Off,Data) LCD_WRITE_REG_0(Off,Data)
  234.     #define LCD_INIT_CONTROLLER     LCD_INIT_CONTROLLER_0
  235.   #else
  236.     #define LCD_READ_MEM(Off)       LCD_READ_MEM_1(Off)
  237.     #define LCD_WRITE_MEM(Off,Data) LCD_WRITE_MEM_1(Off,Data)
  238.     #define LCD_READ_REG(Off)       LCD_READ_REG_1(Off)
  239.     #define LCD_WRITE_REG(Off,Data) LCD_WRITE_REG_1(Off,Data)
  240.     #define LCD_INIT_CONTROLLER     LCD_INIT_CONTROLLER_1
  241.   #endif
  242. #endif
  243. /*
  244.         *********************************************************
  245.         *                                                       *
  246.         *          Internal types                               *
  247.         *                                                       *
  248.         *********************************************************
  249. */
  250. /*
  251.         *********************************************************
  252.         *                                                       *
  253.         *          SCHEDULING                                   *
  254.         *                                                       *
  255.         *********************************************************
  256. */
  257. #if (LCD_SCHEDULE_CNT !=0)
  258.   static int ScheduleCntRem=LCD_SCHEDULE_CNT;
  259.   #define CHECK_SCHEDULE(PixelCnt)                              
  260.           if ((ScheduleCntRem-=(PixelCnt)) <=0) {               
  261.             ScheduleCntRem=LCD_SCHEDULE_CNT;                    
  262.             LCD_SCHEDULE();                                     
  263.           }
  264. #else
  265.   #define CHECK_SCHEDULE(PixelCnt)
  266. #endif
  267. /*
  268.         *********************************************************
  269.         *                                                       *
  270.         *           Macro calculations                          *
  271.         *                                                       *
  272.         *********************************************************
  273. */
  274. /* To make life easier, assign physical x/y size */
  275. #if !LCD_SWAP_XY
  276.   #define LCD_XSIZE_P   LCD_XSIZE
  277.   #define LCD_YSIZE_P   LCD_YSIZE
  278.   #define LCD_VXSIZE_P  LCD_VXSIZE
  279.   #define LCD_VYSIZE_P  LCD_VYSIZE
  280. #else
  281.   #define LCD_XSIZE_P   LCD_YSIZE
  282.   #define LCD_YSIZE_P   LCD_XSIZE
  283.   #define LCD_VXSIZE_P  LCD_VYSIZE
  284.   #define LCD_VYSIZE_P  LCD_VXSIZE
  285. #endif
  286. #if   LCD_BITSPERPIXEL == 1
  287.   #define BYTESPERLINE  (LCD_VXSIZE_P/8)
  288.   #define WORDSPERLINE  (LCD_VXSIZE_P/16)
  289. #elif   LCD_BITSPERPIXEL == 2
  290.   #define BYTESPERLINE  (LCD_VXSIZE_P/4)
  291.   #define WORDSPERLINE  (LCD_VXSIZE_P/8)
  292. #elif   LCD_BITSPERPIXEL == 4
  293.   #define BYTESPERLINE  (LCD_VXSIZE_P/2)
  294.   #define WORDSPERLINE  (LCD_VXSIZE_P/4)
  295. #elif LCD_BITSPERPIXEL == 8
  296.   #define BYTESPERLINE  (LCD_VXSIZE_P)
  297.   #define WORDSPERLINE  (LCD_VXSIZE_P/2)
  298. #elif  (LCD_BITSPERPIXEL == 15)
  299.   #define BYTESPERLINE  (LCD_VXSIZE_P*2)
  300.   #define WORDSPERLINE  (LCD_VXSIZE_P)
  301. #elif  (LCD_BITSPERPIXEL == 16)
  302.   #define BYTESPERLINE  (LCD_VXSIZE_P*2)
  303.   #define WORDSPERLINE  (LCD_VXSIZE_P)
  304. #else
  305.   #error This colordepth is not supported !!!
  306. #endif
  307. #ifndef LCD_USE_32BIT_OFF
  308.   #if ((WORDSPERLINE * LCD_YSIZE) > 0xFFFF)
  309.     #define LCD_USE_32BIT_OFF 1
  310.   #else
  311.     #define LCD_USE_32BIT_OFF 0
  312.   #endif
  313. #endif
  314. #if LCD_USE_32BIT_OFF
  315.   typedef unsigned long tOff;
  316. #else
  317.   typedef unsigned int  tOff;
  318. #endif
  319. /*
  320.         *********************************************************
  321.         *                                                       *
  322.         *              Macros, standard                         *
  323.         *                                                       *
  324.         *********************************************************
  325. These macros can be found in any LCD-driver as they serve purposes
  326. that can be found in any class of LCD-driver (Like clipping).
  327. */
  328. #define BKCOLOR LCD_BKCOLORINDEX
  329. #define   COLOR LCD_COLORINDEX
  330. /*
  331.         *********************************************************
  332.         *                                                       *
  333.         *      Configuration switch checking                    *
  334.         *                                                       *
  335.         *********************************************************
  336. Please be aware that not all configuration errors can be captured !
  337. */
  338. /* Check number of controllers */
  339. #if ((LCD_NUM_CONTROLLERS >1) || (LCD_NUM_CONTROLLERS <0))
  340.   #error "More than 1 controller not supported by this driver"
  341. #endif
  342. #if ((LCD_CONTROLLER==1356)||(LCD_CONTROLLER==13806)) && (LCD_BUSWIDTH !=16)
  343.   #error This controller does not work with 8-bit bus
  344. #endif
  345. #if (((LCD_CONTROLLER==1356)||(LCD_CONTROLLER==13806)) && LCD_USE_BITBLT && ((LCD_BITSPERPIXEL != 8) && (LCD_BITSPERPIXEL != 16)))
  346.   #error BitBlt-Access only available for 8bpp and 16bpp mode
  347. #endif
  348. #if (LCD_CONTROLLER==1374)
  349.   #if (LCD_BITSPERPIXEL == 8)
  350.     #if (LCD_FIXEDPALETTE != 233)
  351.       #error This controller supports only 233 palette in 8 bpp mode !
  352.     #endif
  353.   #endif
  354. #endif
  355. /*
  356.         *********************************************************
  357.         *                                                       *
  358.         *       Macros for internal use                         *
  359.         *                                                       *
  360.         *********************************************************
  361. */
  362. #if !defined (LCD_LUT_COM)
  363.   #define LINE2COM(y) y
  364. #else
  365.   #define LINE2COM(y) LCD__aLine2Com0[y]
  366. #endif
  367. #if LCD_BUSWIDTH == 16
  368.   #if   (LCD_BITSPERPIXEL == 16)
  369.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)WORDSPERLINE+(x))
  370.   #elif (LCD_BITSPERPIXEL == 15)
  371.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)WORDSPERLINE+(x))
  372.   #elif (LCD_BITSPERPIXEL ==  8)
  373.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)WORDSPERLINE+(x>>1))
  374.   #elif (LCD_BITSPERPIXEL ==  4)
  375.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)WORDSPERLINE+(x>>2))
  376.   #elif (LCD_BITSPERPIXEL ==  2)
  377.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)WORDSPERLINE+((x)>>3))
  378.   #elif (LCD_BITSPERPIXEL ==  1)
  379.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)WORDSPERLINE+((x)>>4))
  380.   #endif
  381. #else
  382.   #if   (LCD_BITSPERPIXEL == 16)
  383.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)BYTESPERLINE+((x)<<1))
  384.   #elif (LCD_BITSPERPIXEL == 15)
  385.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)BYTESPERLINE+((x)<<1))
  386.   #elif (LCD_BITSPERPIXEL ==  8)
  387.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)BYTESPERLINE+(x))
  388.   #elif (LCD_BITSPERPIXEL ==  4)
  389.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)BYTESPERLINE+((x)>>1))
  390.   #elif (LCD_BITSPERPIXEL ==  2)
  391.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)BYTESPERLINE+((x)>>2))
  392.   #elif (LCD_BITSPERPIXEL ==  1)
  393.     #define XY2OFF(x,y)    (tOff)((tOff)LINE2COM(y)*(tOff)BYTESPERLINE+((x)>>3))
  394.   #endif
  395. #endif
  396. //#if ((LCD_SWAP_BYTE_ORDER) && (LCD_BITSPERPIXEL <=8)) | ((LCD_SWAP_BYTE_ORDER==0) && (LCD_BITSPERPIXEL  > 8))
  397. //  #define READ_MEM(Off, Data)  Data = LCD_READ_MEM(Off); Data = ((Data & 0xff) << 8) + (Data >> 8)
  398. //  #define WRITE_MEM(Off, Data) LCD_WRITE_MEM(Off, (U16)(((Data & 0xff) << 8) + ((Data & 0xff00) >> 8)))
  399. //#else
  400.   #define READ_MEM(Off, Data)  Data = LCD_READ_MEM(Off)
  401.   #define WRITE_MEM(Off, Data) LCD_WRITE_MEM(Off, Data)
  402. //#endif
  403. #if (LCD_SWAP_BYTE_ORDER)
  404.   #define READ_REG(Off, Data)  Data = LCD_READ_REG(Off)
  405.   #define WRITE_REG(Off, Data) LCD_WRITE_REG(Off, Data)
  406. #else
  407.   #define READ_REG(Off, Data)  { Data = Swap(LCD_READ_REG(Off)); }
  408.   #define WRITE_REG(Off, Data) { LCD_WRITE_REG(Off, Swap(Data)); }
  409.   #define REQUIRE_SWAP
  410. #endif
  411. /* No use of LCD_WRITE_MEM, LCD_READ_MEM, LCD_WRITE_REG, LCD_READ_REG from this point */
  412. #if defined (LCD_LUT_COM)
  413.   #if (LCD_MIRROR_Y)
  414.     #error LCD_MIRROR_Y not supported with COMTrans !
  415.   #endif
  416.   #if (LCD_MIRROR_X)
  417.     #error LCD_MIRROR_X not supported with COMTrans !
  418.   #endif
  419. #endif
  420. #if (!defined(LCD_LUT_SEG))
  421.   #if   (!LCD_MIRROR_X && !LCD_MIRROR_Y && !LCD_SWAP_XY) 
  422.     #define PHYS2LOG(x, y) x, y
  423.   #elif (!LCD_MIRROR_X && !LCD_MIRROR_Y &&  LCD_SWAP_XY) 
  424.     #define PHYS2LOG(x, y) y, x
  425.   #elif (!LCD_MIRROR_X &&  LCD_MIRROR_Y && !LCD_SWAP_XY) 
  426.     #define PHYS2LOG(x, y) x, LCD_YSIZE - 1 - (y)
  427.   #elif (!LCD_MIRROR_X &&  LCD_MIRROR_Y &&  LCD_SWAP_XY) 
  428.     #define PHYS2LOG(x, y) LCD_YSIZE - 1 - (y), x
  429.   #elif ( LCD_MIRROR_X && !LCD_MIRROR_Y && !LCD_SWAP_XY) 
  430.     #define PHYS2LOG(x, y) LCD_XSIZE - 1 - (x), y
  431.   #elif ( LCD_MIRROR_X && !LCD_MIRROR_Y &&  LCD_SWAP_XY) 
  432.     #define PHYS2LOG(x, y) LCD_YSIZE - 1 - (y), x
  433.   #elif ( LCD_MIRROR_X &&  LCD_MIRROR_Y && !LCD_SWAP_XY) 
  434.     #define PHYS2LOG(x, y) LCD_XSIZE - 1 - (x), LCD_YSIZE - 1 - (y)
  435.   #elif ( LCD_MIRROR_X &&  LCD_MIRROR_Y &&  LCD_SWAP_XY) 
  436.     #error This combination of mirroring/swapping not yet supported
  437.   #endif
  438. #else
  439.   #define PHYS2LOG(x, y) LCD__aCol2Seg0[x], y
  440. #endif
  441. #define SETPIXEL(x, y, c)  _SetPixel    (PHYS2LOG(x, y), c)
  442. #define GETPIXEL(x, y)     GetPixelIndex(PHYS2LOG(x, y))
  443. #define XORPIXEL(x, y)     XorPixel     (PHYS2LOG(x, y))
  444. /*
  445.         *********************************************************
  446.         *                                                       *
  447.         *       Register access routines                        *
  448.         *                                                       *
  449.         *********************************************************
  450. */
  451. #if defined(LCD_READ_REG)
  452. #if (LCD_BUSWIDTH == 8)
  453.   #define READ_REG_BYTE(Off) LCD_READ_REG(Off)
  454. #else
  455.   #define READ_REG_BYTE(Off) ReadRegByte(Off)
  456. U8 ReadRegByte(int Off) {
  457.   U16 Data = LCD_READ_REG((Off>>1));
  458.   #if LCD_SWAP_BYTE_ORDER
  459.     return (Off&1) ? Data>>8 : Data&255;
  460.   #else
  461.     return (Off&1) ? Data&255 : Data>>8;
  462.   #endif
  463. }
  464. #endif  
  465. #endif
  466. /*
  467. *********************************************************
  468. *                                                       *
  469. *       Static routines
  470. *                                                       *
  471. *********************************************************
  472. */
  473. #ifdef REQUIRE_SWAP
  474. U16 Swap(U16 Data) {
  475.   return (Data<<8) | (Data>>8);
  476. }
  477. #endif
  478. /*
  479.         *********************************************************
  480.         *                                                       *
  481.         *       Next pixel routines                             *
  482.         *                                                       *
  483.         *********************************************************
  484. */
  485. #if      (LCD_OPTIMIZE)             
  486.       && (LCD_BUSWIDTH == 8)        
  487.       && (!LCD_MIRROR_X)             
  488.       && (!LCD_MIRROR_Y)            
  489.       && (LCD_SWAP_XY)              
  490.       && (!defined (LCD_LUT_COM))    
  491.       && (!defined (LCD_LUT_SEG))    
  492.       && (LCD_BITSPERPIXEL == 4)
  493. static int CurPosY;    /* Physical x position !!! */
  494. static tOff CurOff;
  495. static void SetPosXY(int x, int y) {
  496.   y = LCD_YSIZE-1-y;
  497.   CurPosY = y;
  498.   CurOff = XY2OFF(y,x);
  499. }
  500. static void SetNextPixel(LCD_PIXELINDEX c) {
  501.   U8 Data;
  502.   READ_MEM(CurOff, Data);
  503.   if (CurPosY&1) {
  504.     Data = (Data & ~(15<<0)) | (c<<0);
  505.     CurOff++;
  506.   } else {
  507.     Data = (Data & ~(15<<4)) | (c<<4);
  508.   }
  509.   WRITE_MEM(CurOff, Data);
  510.   CurPosY++;
  511. }
  512. #elif      (LCD_OPTIMIZE)           
  513.       && (LCD_BUSWIDTH == 8)        
  514.       && (!LCD_MIRROR_X)            
  515.       && (!LCD_MIRROR_Y)            
  516.       && (!LCD_SWAP_XY)              
  517.       && (!defined (LCD_LUT_COM))    
  518.       && (!defined (LCD_LUT_SEG))    
  519.       && (LCD_BITSPERPIXEL == 4)
  520. static int CurPosX;    /* Physical x position !!! */
  521. static tOff CurOff;
  522. static U8  CurData;
  523. static void SetPosXY(int x, int y) {
  524.   CurPosX = x;
  525.   CurOff = XY2OFF(x,y);
  526.   CurData = LCD_READ_MEM(CurOff);
  527. }
  528. #define SETNEXTPIXEL(c) {                           
  529.   if (CurPosX&1) {                                  
  530.     CurData = (CurData & ~(15<<0)) | (c<<0);        
  531.     WRITE_MEM(CurOff, CurData);                     
  532.     CurOff++;                                       
  533.     READ_MEM(CurOff, CurData);                      
  534.   } else {                                          
  535.     CurData = (CurData & ~(15<<4)) | (c<<4);        
  536.   }                                                 
  537.   CurPosX++;                                        
  538. }
  539. void SetNextPixel(int c) {
  540.   SETNEXTPIXEL(c);
  541. }
  542. #define END_SETNEXTPIXEL() if (CurPosX&1) WRITE_MEM(CurOff, CurData);
  543. #else
  544.   #define END_SETNEXTPIXEL()
  545. #endif
  546. /*
  547.         *********************************************************
  548.         *                                                       *
  549.         *       BitBlt access for SED1356/SED13806              *
  550.         *                                                       *
  551.         *********************************************************
  552. */
  553. #if LCD_USE_BITBLT                  
  554.     && (LCD_BUSWIDTH==16)           
  555.     && (!defined (LCD_LUT_COM))     
  556.     && (!defined (LCD_LUT_SEG))     
  557.     && ((LCD_CONTROLLER == 1356)||(LCD_CONTROLLER == 13806))
  558. #if LCD_BITSPERPIXEL == 8
  559.   #define BITBLT_SET_DESTINATION(x,y)     WRITE_REG(0x108 / 2, (((tOff)y * (tOff)BYTESPERLINE) + x)); 
  560.                                           WRITE_REG(0x10a / 2, (U32)(((tOff)y * (tOff)BYTESPERLINE) + x) >> 16)
  561.   #define BITBLT_SET_ACTIVE()             WRITE_REG(0x100 / 2, 0x0000); WRITE_REG(0x100 / 2, 0x0080)
  562. #elif LCD_BITSPERPIXEL == 16
  563.   #define BITBLT_SET_DESTINATION(x,y)     WRITE_REG(0x108 / 2, (((tOff)y * (tOff)BYTESPERLINE) + (x << 1))); 
  564.                                           WRITE_REG(0x10a / 2, (((tOff)y * (tOff)BYTESPERLINE) + (x << 1)) >> 16)
  565.   #define BITBLT_SET_ACTIVE()             WRITE_REG(0x100 / 2, 0x0100); WRITE_REG(0x100 / 2, 0x0180)
  566. #endif
  567. static void WaitForBltEnd(void) {
  568.   volatile U16 tmp;
  569.   do {
  570.     READ_REG(0x100 / 2, tmp);
  571.   } while (tmp & 0x80);
  572.   READ_REG(0x100000 / 2, tmp);                                            /* dummy read */
  573. }
  574. static void LCD_FillRectBB(int x0, int y0, int x1, int y1) {
  575.   LCD_ENABLE_REG_ACCESS(); {
  576.     for (;x0 <= x1; x0 += 1024) {
  577.       int _y0 = y0;
  578.       int _x1 = x1;
  579.       if (_x1 > (x0 + 1023)) {
  580.         _x1 = x0 + 1023;
  581.       }
  582.       for (;_y0 <= y1; _y0 += 1024) {
  583.         int _y1 = y1;
  584.         if (_y1 > (_y0 + 1023)) {
  585.           _y1 = _y0 + 1023;
  586.         }
  587.         BITBLT_SET_DESTINATION(x0, _y0);                                  /* set destination start address */
  588.         WRITE_REG(0x110 / 2, (_x1 - x0));                                 /* set width */
  589.         WRITE_REG(0x112 / 2, (_y1 - _y0));                                /* set height */
  590.         WRITE_REG(0x118 / 2, (COLOR));                                    /* set foreground color  */
  591.         if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  592.           WRITE_REG(0x102 / 2, 0x0605);                                   /* pattern fill, ~D   */
  593.         } else {
  594.           WRITE_REG(0x102 / 2, 0x0c00);                                   /* solid fill, no ROP */
  595.         }
  596.         BITBLT_SET_ACTIVE();                                              /* engage bitblt engine */
  597.         WaitForBltEnd();                                                  /* wait for pending blit to end */
  598.       }
  599.     }
  600.   } LCD_ENABLE_MEM_ACCESS();
  601. }
  602. static void LCD_DrawBitmap1BPPBB(int x, int y, U8 const*p, int Diff, int xsize, int ysize, int BytesPerLine, const LCD_PIXELINDEX*pTrans) {
  603.   volatile U16 tmp;
  604.   x+= Diff;
  605.   LCD_ENABLE_REG_ACCESS(); {
  606.     U16 StartBit = 7 - (Diff & 7);
  607.     U16 Data = StartBit | ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) ? 0x900 : 0x800);
  608.     int NumWords = ((Diff & 7) + xsize + 15) >> 4;
  609.     WRITE_REG(0x102 / 2, Data);                                           /* set start bit and operation */
  610.     WRITE_REG(0x104 / 2, 0);                                              /* set source start address */
  611.     BITBLT_SET_DESTINATION(x, y);                                         /* set destination start address */
  612.     WRITE_REG(0x110 / 2, (xsize - 1));                                    /* set width */
  613.     WRITE_REG(0x112 / 2, (ysize - 1));                                    /* set height */
  614.     WRITE_REG(0x114 / 2, (*(pTrans + 0)));                                /* set background color */
  615.     WRITE_REG(0x118 / 2, (*(pTrans + 1)));                                /* set foreground color  */
  616.     BITBLT_SET_ACTIVE();                                                  /* engage bitblt engine */
  617.     do {
  618.       READ_REG(0x100 / 2, tmp);
  619.     } while ((tmp & 0x80) == 0);
  620.     for (;ysize; ysize--, p += BytesPerLine) {
  621.       U8 const *pLine= p;
  622.       int i;
  623.       for (i = NumWords; i; i--, pLine += 2) {
  624.         do {
  625.           READ_REG(0x100 / 2, tmp);
  626.         } while ((tmp & 0x40) == 0x40);
  627.         WRITE_REG(0x100000 / 2, ((*pLine) | ((*(pLine + 1)) << 8)));      /* write data into FIFO */
  628.       }
  629.     }
  630.     WaitForBltEnd();                                                      /* wait for pending blit to end */
  631.   } LCD_ENABLE_MEM_ACCESS();
  632. }
  633. #endif
  634. /*
  635.         *********************************************************
  636.         *                                                       *
  637.         *       Internal set pixel routines                     *
  638.         *                                                       *
  639.         *********************************************************
  640. */
  641. static void _SetPixel(int x, int y, LCD_PIXELINDEX c) {
  642.   tOff Off = XY2OFF(x,y);
  643. #if LCD_BUSWIDTH == 16
  644.   #if LCD_BITSPERPIXEL == 1
  645.     U8 BitNo = (~x)&15;
  646.     U16 Data;
  647.     READ_MEM(Off, Data);
  648.     if (c)
  649.       Data |= c<<BitNo;
  650.     else
  651.       Data &= ~(1<<BitNo);      
  652.     WRITE_MEM(Off, Data);
  653.   #elif LCD_BITSPERPIXEL == 2
  654.     U16 Data;
  655.     U8 Shift = 14 - ((x & 7) << 1);
  656.     READ_MEM(Off, Data);
  657.     Data = (Data & ~(3 << Shift)) | (c << Shift);
  658.     WRITE_MEM(Off, Data);
  659.   #elif LCD_BITSPERPIXEL == 4
  660.     U8 Shift = ((~x)&3)<<2;         /* 12,8,4 or 0 */
  661.     U16 Data;
  662.     READ_MEM(Off, Data);
  663.     Data &= ~(15<<Shift);
  664. Data |= c<<Shift;
  665.     WRITE_MEM(Off, Data);
  666.   #elif LCD_BITSPERPIXEL == 8
  667.     U16 Data; 
  668.     READ_MEM(Off, Data);
  669.     switch (x&1) {
  670.     case 1:
  671.       Data = (Data & ~(0xff   )) | (c   );
  672.       break;
  673.     case 0:
  674.       Data = (Data & ~(0xff<<8)) | (c<<8);
  675.       break;
  676.     }
  677.     WRITE_MEM(Off, Data);
  678.   #elif (LCD_BITSPERPIXEL == 15) | (LCD_BITSPERPIXEL == 16)
  679.     WRITE_MEM(Off, c);
  680.   #else
  681.     #error unsupported LCD_BITSPERPIXEL
  682.   #endif
  683. #elif LCD_BUSWIDTH == 8
  684.   #if LCD_BITSPERPIXEL == 1
  685.     U8 Data;
  686.     U8 BitNo;
  687.     READ_MEM(Off, Data);
  688.     BitNo = 7-(x&7);
  689.     if (c)
  690.       Data |= c<<BitNo;
  691.     else
  692.       Data &= ~(1<<BitNo);      
  693.     WRITE_MEM(Off, Data);
  694.   #elif LCD_BITSPERPIXEL == 2
  695.     U8 Data;
  696.     READ_MEM(Off, Data);
  697.     switch (x&3) {
  698.     case 3:
  699.       Data = (Data & ~(3<<0)) | (c<<0);
  700.       break;
  701.     case 2:
  702.       Data = (Data & ~(3<<2)) | (c<<2);
  703.       break;
  704.     case 1:
  705.       Data = (Data & ~(3<<4)) | (c<<4);
  706.       break;
  707.     case 0:
  708.       Data = (Data & ~(3<<6)) | (c<<6);
  709.       break;
  710.     }
  711.     WRITE_MEM(Off, Data);
  712.   #elif LCD_BITSPERPIXEL == 4
  713.     U8 Data;
  714.     READ_MEM(Off, Data);
  715.     switch (x&1) {
  716.     case 1:
  717.       Data = (Data & ~(15<<0)) | (c<<0);
  718.       break;
  719.     case 0:
  720.       Data = (Data & ~(15<<4)) | (c<<4);
  721.       break;
  722.     }
  723.     WRITE_MEM(Off, Data);
  724.   #elif LCD_BITSPERPIXEL == 8
  725.     WRITE_MEM(Off, c);
  726.   #else
  727.     #error TBD
  728.   #endif
  729. #else
  730.   #error unsupported LCD_BUSWIDTH
  731. #endif
  732. }
  733. unsigned int GetPixelIndex(int x, int y) {
  734.   LCD_PIXELINDEX col;
  735.   tOff Off = XY2OFF(x,y);
  736. #if LCD_BUSWIDTH == 16
  737.   U16 Data;
  738.   READ_MEM(Off,Data);
  739.   #if LCD_BITSPERPIXEL == 1
  740.     col = (Data >> (15-(x&15))) &1;
  741.   #elif LCD_BITSPERPIXEL == 2
  742.     col = (Data >> (14-((x&7)<<1))) &3;
  743.   #elif LCD_BITSPERPIXEL == 4
  744.     col = (Data >> (12-((x&3)<<2))) &15;
  745.   #elif LCD_BITSPERPIXEL == 8
  746.     col = ((x&1) ==0) ? Data>>8 : Data;
  747.   #elif LCD_BITSPERPIXEL == 15
  748.     col = Data;
  749.   #elif LCD_BITSPERPIXEL == 16
  750.     col = Data;
  751.   #endif
  752. #else
  753.   U8 Data;
  754.   READ_MEM(Off,Data);
  755.   #if LCD_BITSPERPIXEL == 1
  756.     col = (Data >> (7-(x&7))) &1;
  757.   #elif LCD_BITSPERPIXEL == 2
  758.     col = (Data >> (6-((x&3)<<1))) &3;
  759.   #elif LCD_BITSPERPIXEL == 4
  760.     col = (x&1) ? Data&15 : Data>>4;
  761.   #elif LCD_BITSPERPIXEL == 8
  762.     col = Data;
  763.   #endif
  764. #endif
  765.   return col;
  766. }
  767. static void XorPixel   (int x, int y) {
  768.   LCD_PIXELINDEX Index = GetPixelIndex(x,y);
  769.   _SetPixel(x,y,LCD_NUM_COLORS-1-Index);
  770. }
  771. /*
  772.         *********************************************************
  773.         *                                                       *
  774.         *       LCD_L0_XorPixel                                 *
  775.         *                                                       *
  776.         *********************************************************
  777. Purpose:  This routine is called by emWin. It writes 1 pixel into the
  778.           display.
  779. */
  780. void LCD_L0_XorPixel(int x, int y) {
  781.   XORPIXEL(x, y);
  782. }
  783. /*
  784.         *********************************************************
  785.         *                                                       *
  786.         *       LCD_L0_SetPixelIndex                            *
  787.         *                                                       *
  788.         *********************************************************
  789. Purpose:  This routine is called by emWin. It writes 1 pixel into the
  790.           display.
  791. */
  792. void LCD_L0_SetPixelIndex(int x, int y, int ColorIndex) {
  793.   SETPIXEL(x, y, ColorIndex);
  794. }
  795. /*
  796.         *********************************************************
  797.         *                                                       *
  798.         *          LCD_L0_DrawHLine optimized                      *
  799.         *                                                       *
  800.         *          16 bit bus, Using BITBLT                     *
  801.         *                                                       *
  802.         *********************************************************
  803. */
  804. #if (LCD_USE_BITBLT)           
  805.     && (!LCD_SWAP_XY)          
  806.     && (LCD_BUSWIDTH==16)      
  807.     && (!defined (LCD_LUT_COM))   
  808.     && (!defined (LCD_LUT_SEG))   
  809.     && ((LCD_CONTROLLER == 1356)||(LCD_CONTROLLER == 13806))
  810. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  811.   #if LCD_MIRROR_X
  812.     #define X0 (LCD_XSIZE-1-(x1))
  813.     #define X1 (LCD_XSIZE-1-(x0))
  814.   #else
  815.     #define X0 x0
  816.     #define X1 x1
  817.   #endif
  818.   #if LCD_MIRROR_Y
  819.     #define Y0 (LCD_YSIZE-1-(y))
  820.   #else
  821.     #define Y0 y
  822.   #endif
  823.   if (x0>x1) return;
  824.   LCD_FillRectBB(X0,Y0,X1,Y0);
  825.   #undef X0
  826.   #undef X1
  827.   #undef Y0
  828. }
  829. /*
  830.         *********************************************************
  831.         *                                                       *
  832.         *          LCD_L0_DrawHLine optimized                      *
  833.         *                                                       *
  834.         *          16 bit bus, 16 bpp                           *
  835.         *                                                       *
  836.         *********************************************************
  837. */
  838. #elif (LCD_OPTIMIZE)             
  839.       && (!LCD_SWAP_XY)          
  840.       && (!LCD_MIRROR_Y)         
  841.       && (LCD_BUSWIDTH==16)      
  842.       && (!defined (LCD_LUT_COM))   
  843.       && (!defined (LCD_LUT_SEG))   
  844.       && ((LCD_BITSPERPIXEL == 16) || (LCD_BITSPERPIXEL == 15))
  845. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  846.   #if LCD_MIRROR_X
  847.     #define X0 (LCD_XSIZE-1-(x1))
  848.   #else
  849.     #define X0 x0
  850.   #endif
  851.   if (x0>x1) return;
  852.   {
  853.     register tOff Off = XY2OFF(X0,y);
  854.     register int Rem = x1-x0+1;
  855.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  856.       for (; Rem--; Off++) {
  857.         U16 Data;
  858.         READ_MEM(Off, Data);
  859.         Data = LCD_NUM_COLORS-1-Data;
  860.         WRITE_MEM(Off,Data);
  861.       }
  862.     } else {
  863.       for (; Rem >= 8; Off += 8) {
  864.         WRITE_MEM(Off,COLOR);
  865.         WRITE_MEM(Off+1,COLOR);
  866.         WRITE_MEM(Off+2,COLOR);
  867.         WRITE_MEM(Off+3,COLOR);
  868.         WRITE_MEM(Off+4,COLOR);
  869.         WRITE_MEM(Off+5,COLOR);
  870.         WRITE_MEM(Off+6,COLOR);
  871.         WRITE_MEM(Off+7,COLOR);
  872.         Rem -=8;
  873.       }
  874.       for (; Rem--; Off++) {
  875.         WRITE_MEM(Off,COLOR);
  876.       }
  877.     }
  878.   }
  879.   #undef X0
  880. }
  881. /*
  882.         *********************************************************
  883.         *                                                       *
  884.         *          LCD_L0_DrawHLine optimized                   *
  885.         *                                                       *
  886.         *          16 bit bus, 8 bpp                            *
  887.         *                                                       *
  888.         *********************************************************
  889. */
  890. #elif (LCD_OPTIMIZE)             
  891.       && (!LCD_SWAP_XY)          
  892.       && (LCD_BUSWIDTH==16)      
  893.       && (!defined (LCD_LUT_SEG))   
  894.       && (LCD_BITSPERPIXEL == 8)
  895.       
  896. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  897.   #if LCD_MIRROR_X
  898.   {
  899.     int t = (LCD_XSIZE-1-(x0));
  900.     x0 = (LCD_XSIZE-1-(x1));
  901.     x1 = t;
  902.   }
  903.   #endif
  904.   #if LCD_MIRROR_Y
  905.     y = (LCD_YSIZE-1-(y));
  906.   #endif
  907.   {
  908.     register tOff Off = XY2OFF(x0,y);
  909.     /* register */ U16 Data;
  910. /* XOR mode */
  911.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  912.       if (x0&1) {
  913.         READ_MEM(Off, Data);
  914.         Data ^= ((unsigned int)255);
  915.         WRITE_MEM(Off,Data);
  916.         x0++;
  917.         Off++;
  918.       }
  919.       for (; x0<x1; x0+=2, Off++) {
  920.         READ_MEM(Off,Data);
  921.         Data ^= 0xffff;
  922.         WRITE_MEM(Off,Data);
  923.       }      
  924.       if ((x1&1)==0) {
  925.         READ_MEM(Off,Data);
  926.         Data ^=  (U16)255<<8;
  927.         WRITE_MEM(Off,Data);
  928.       }
  929. /* WRITE mode */
  930.     } else {
  931.       if (x0&1) {
  932.         READ_MEM(Off,Data);
  933.         Data = (Data&((U16)0xff<<8)) | (COLOR);
  934.         WRITE_MEM(Off,Data);
  935.         x0++;
  936.         Off++;
  937.       }
  938.       Data = COLOR|((U16)COLOR<<8);
  939.       /* Optimization for longer lines ... */
  940.       #ifdef LCD_WRITE_MEM32
  941.       if ((x0<x1-4) && (x0&2)) { /* Write 16 bits if necessary */
  942.         WRITE_MEM(Off,Data);
  943.         x0+=2;
  944.         Off++;
  945.       }
  946.       /* write 4 pixels at a time, loop unrolled  */
  947.       { register U32 Data32 = Data| (Data<<16);
  948.         for (;x0<x1-32-2; x0+=32, Off+=16) {
  949.           LCD_WRITE_MEM32(Off+0,Data32);
  950.           LCD_WRITE_MEM32(Off+2,Data32);
  951.           LCD_WRITE_MEM32(Off+4,Data32);
  952.           LCD_WRITE_MEM32(Off+6,Data32);
  953.           LCD_WRITE_MEM32(Off+8,Data32);
  954.           LCD_WRITE_MEM32(Off+10,Data32);
  955.           LCD_WRITE_MEM32(Off+12,Data32);
  956.           LCD_WRITE_MEM32(Off+14,Data32);
  957.         }
  958.       }
  959.       { register U32 Data32 = Data| (Data<<16);
  960.         for (;x0<x1-16-2; x0+=16, Off+=8) {
  961.           LCD_WRITE_MEM32(Off+0,Data32);
  962.           LCD_WRITE_MEM32(Off+2,Data32);
  963.           LCD_WRITE_MEM32(Off+4,Data32);
  964.           LCD_WRITE_MEM32(Off+6,Data32);
  965.         }
  966.       }
  967.       { register U32 Data32 = Data| (Data<<16);
  968.         for (;x0<x1-8-2; x0+=8, Off+=4) {
  969.           LCD_WRITE_MEM32(Off+0,Data32);
  970.           LCD_WRITE_MEM32(Off+2,Data32);
  971.         }
  972.       }
  973.       #else
  974.       for (;x0<x1-10; x0+=12, Off+=6) {
  975.         /* swapping can be ignored, so use faster LCD_WRITE_MEM */
  976.         LCD_WRITE_MEM(Off,Data); 
  977.         LCD_WRITE_MEM(Off+1,Data);
  978.         LCD_WRITE_MEM(Off+2,Data);
  979.         LCD_WRITE_MEM(Off+3,Data);
  980.         LCD_WRITE_MEM(Off+4,Data);
  981.         LCD_WRITE_MEM(Off+5,Data);
  982.       }
  983.       #endif
  984.       /* write the last pixels 2 at a time */
  985.       for (; x0<x1; x0+=2, Off++) {
  986.         /* swapping can be ignored, so use faster LCD_WRITE_MEM */
  987.         LCD_WRITE_MEM(Off,Data);
  988.       }      
  989.       if ((x1&1)==0) {
  990.         READ_MEM(Off, Data);
  991.         Data = (Data&((unsigned int)0xff)) | ((U16)COLOR<<8);
  992.         WRITE_MEM(Off,Data);
  993.       }
  994.     }
  995.   }
  996. }
  997. /*
  998.         *********************************************************
  999.         *                                                       *
  1000.         *          LCD_L0_DrawHLine optimized                   *
  1001.         *                                                       *
  1002.         *          16 bit bus, 4 bpp                            *
  1003.         *                                                       *
  1004.         *********************************************************
  1005. */
  1006. #elif (LCD_OPTIMIZE)             
  1007.       && (!LCD_SWAP_XY)          
  1008.       && (LCD_BUSWIDTH==16)      
  1009.       && (!defined (LCD_LUT_SEG))   
  1010.       && (LCD_BITSPERPIXEL == 4)
  1011. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  1012.   #if LCD_MIRROR_X
  1013.     #define X0 (LCD_XSIZE-1-(x1))
  1014.   #else
  1015.     #define X0 x0
  1016.   #endif
  1017.   #if LCD_MIRROR_Y
  1018.     #define Y (LCD_YSIZE - 1 - y)
  1019.   #else
  1020.     #define Y y
  1021.   #endif
  1022.   if (x0>x1) return;
  1023.   {
  1024.     register tOff Off;
  1025.     register int Rem;
  1026.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1027.       for (; (x0&3    )&&(x0<=x1); x0++) XORPIXEL(x0, y);
  1028.       for (; ((x1+1)&3)&&(x0<=x1); x1--) XORPIXEL(x1, y);
  1029.       Off = XY2OFF(X0,Y);
  1030.       Rem = (x1-x0+4)>>2;
  1031.       for (; Rem--; Off++) {
  1032.         U16 c;
  1033.         READ_MEM(Off, c);
  1034.         c ^= 0xffff; 
  1035.         WRITE_MEM(Off,c);
  1036.       }
  1037.     } else {
  1038.       U16 col = COLOR+(COLOR<<4)+(COLOR<<8)+(COLOR<<12);
  1039.       for (; (x0&3    )&&(x0<=x1); x0++)
  1040.         SETPIXEL(x0, y, COLOR);
  1041.       for (; ((x1+1)&3)&&(x0<=x1); x1--)
  1042.         SETPIXEL(x1, y, COLOR);
  1043.       Off = XY2OFF(X0,Y);
  1044.       Rem = (x1-x0+4)>>2;
  1045.       for (; Rem--; Off++) {
  1046.         /* swapping can be ignored, so use faster LCD_WRITE_MEM */
  1047.         LCD_WRITE_MEM(Off,col);
  1048.       }
  1049.     }
  1050.   }
  1051.   #undef X0
  1052. }
  1053. /*
  1054.         *********************************************************
  1055.         *                                                       *
  1056.         *          LCD_L0_DrawHLine optimized                   *
  1057.         *                                                       *
  1058.         *          16 bit bus, 1 bpp                            *
  1059.         *                                                       *
  1060.         *********************************************************
  1061. */
  1062. #elif (LCD_OPTIMIZE)             
  1063.       && (!LCD_SWAP_XY)          
  1064.       && (LCD_BUSWIDTH==16)      
  1065.       && (!defined (LCD_LUT_SEG))   
  1066.       && (LCD_BITSPERPIXEL == 1)
  1067. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  1068.   #if LCD_MIRROR_X
  1069.   {
  1070.     int temp = x0;
  1071.     x0 = (LCD_XSIZE-1-(x1));
  1072.     x1 = (LCD_XSIZE-1-(temp));
  1073.   }
  1074.   #endif
  1075.   #if LCD_MIRROR_Y
  1076.   {
  1077.     y = (LCD_YSIZE - 1 - y);
  1078.   }
  1079.   #endif
  1080.   {
  1081.     register tOff Off = XY2OFF(x0,y);
  1082.     int iWord = x0>>4;
  1083.     int Word1 = x1>>4;
  1084.     U16 Mask   =  0xffff   >> (x0&15);
  1085.     U16 EndMask = 0xffff8000 >> (x1&15);
  1086.     U16 Data;
  1087.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1088.       for (; iWord<Word1; iWord++) {
  1089.         READ_MEM(Off,Data);
  1090.         Data ^= Mask; 
  1091.         WRITE_MEM(Off++,Data);
  1092.         Mask = 0xffff;
  1093.       }
  1094.       Mask &= EndMask;
  1095.       READ_MEM(Off,Data);
  1096.       Data ^= Mask; 
  1097.       WRITE_MEM(Off++,Data);
  1098.     } else {                                  /* Clear pixels in line */
  1099.       int NumWords = Word1-iWord;
  1100.       if (COLOR==0) {
  1101.         if (NumWords) {
  1102.           READ_MEM(Off,Data);
  1103.           Data &= ~Mask;
  1104.           WRITE_MEM(Off++,Data);
  1105.           NumWords--;
  1106.           /* Fill Words in 2 loops for speed reasons ... */
  1107.           for (; NumWords>=4; NumWords-=4) {
  1108.             /* swapping can be ignored, so use faster LCD_WRITE_MEM */
  1109.             LCD_WRITE_MEM(Off++,0);
  1110.             LCD_WRITE_MEM(Off++,0);
  1111.             LCD_WRITE_MEM(Off++,0);
  1112.             LCD_WRITE_MEM(Off++,0);
  1113.           }
  1114.           for (; NumWords; NumWords--) {
  1115.             /* swapping can be ignored, so use faster LCD_WRITE_MEM */
  1116.             LCD_WRITE_MEM(Off++,0);
  1117.           }
  1118.           Mask = 0xffff;
  1119.         }
  1120.         Mask &= EndMask;
  1121.         READ_MEM(Off, Data);
  1122.         Data &= ~Mask; 
  1123.         WRITE_MEM(Off++,Data);
  1124.       } else {                                  /* Set pixels in line */
  1125.         if (NumWords) {
  1126.           READ_MEM(Off, Data); 
  1127.           Data |= Mask; 
  1128.           WRITE_MEM(Off++,Data);
  1129.           NumWords--;
  1130.         /* Fill Words in 2 loops for speed reasons ... */
  1131.           for (; NumWords>=4; NumWords-=4) {
  1132.             /* swapping can be ignored, so use faster LCD_WRITE_MEM */
  1133.             LCD_WRITE_MEM(Off++,0xffff);
  1134.             LCD_WRITE_MEM(Off++,0xffff);
  1135.             LCD_WRITE_MEM(Off++,0xffff);
  1136.             LCD_WRITE_MEM(Off++,0xffff);
  1137.           }
  1138.           for (; NumWords; NumWords--) {
  1139.             /* swapping can be ignored, so use faster LCD_WRITE_MEM */
  1140.             LCD_WRITE_MEM(Off++,0xffff);
  1141.           }
  1142.           Mask = 0xffff;
  1143.         }
  1144.         Mask &= EndMask;
  1145.         READ_MEM(Off, Data); 
  1146.         Data |= Mask; 
  1147.         WRITE_MEM(Off++,Data);
  1148.       }
  1149.     }
  1150.   }
  1151. }
  1152. /*
  1153.         *********************************************************
  1154.         *                                                       *
  1155.         *          LCD_L0_DrawHLine optimized                      *
  1156.         *                                                       *
  1157.         *          8 bit bus, 8 bpp                             *
  1158.         *                                                       *
  1159.         *********************************************************
  1160. */
  1161. #elif (LCD_OPTIMIZE)             
  1162.       && (!LCD_SWAP_XY)          
  1163.       && (LCD_BUSWIDTH==8)      
  1164.       && (!defined (LCD_LUT_SEG))   
  1165.       && (LCD_BITSPERPIXEL == 8)
  1166. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  1167.   #if LCD_MIRROR_X
  1168.     #define X0 (LCD_XSIZE-1-(x1))
  1169.   #else
  1170.     #define X0 x0
  1171.   #endif
  1172.   #if LCD_MIRROR_Y
  1173.     y = LCD_YSIZE - 1 - y;
  1174.   #endif
  1175.   if (x0>x1) return;
  1176.   {
  1177.     register tOff Off = XY2OFF(X0,y);
  1178.     register int Rem = x1-x0+1;
  1179.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1180.       for (; (--Rem)>=0; Off++) {
  1181.         U16 c;
  1182.         READ_MEM(Off,c);
  1183.         c ^= 0xff; 
  1184.         WRITE_MEM(Off,c);
  1185.       }
  1186.     } else {
  1187.       for (;Rem>=4;Off+=4,Rem-=4) {
  1188.         WRITE_MEM(Off,COLOR);
  1189.         WRITE_MEM(Off+1,COLOR);
  1190.         WRITE_MEM(Off+2,COLOR);
  1191.         WRITE_MEM(Off+3,COLOR);
  1192.   }
  1193.       for (; (--Rem)>=0; Off++) {
  1194.         WRITE_MEM(Off,COLOR);
  1195.       }
  1196.     }
  1197.   }
  1198.   #undef X0
  1199. }
  1200. /*
  1201.         *********************************************************
  1202.         *                                                       *
  1203.         *          LCD_L0_DrawHLine optimized                      *
  1204.         *                                                       *
  1205.         *          8 bit bus, 4 bpp                            *
  1206.         *                                                       *
  1207.         *********************************************************
  1208. */
  1209. #elif (LCD_OPTIMIZE)             
  1210.       && (!LCD_SWAP_XY)          
  1211.       && (!LCD_MIRROR_Y)         
  1212.       && (LCD_BUSWIDTH==8)       
  1213.       && (!defined (LCD_LUT_SEG))   
  1214.       && (LCD_BITSPERPIXEL == 4)
  1215. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  1216.   #if LCD_MIRROR_X
  1217.     #define X0 (LCD_XSIZE-1-(x1))
  1218.   #else
  1219.     #define X0 x0
  1220.   #endif
  1221.   if (x0>x1) return;
  1222.   {
  1223.     register tOff Off;
  1224.     register int Rem;
  1225.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1226.       for (;  (x0&1)      &&(x0<=x1); x0++) XORPIXEL(x0, y);
  1227.       for (; ((x1&1)!=1)  &&(x0<=x1); x1--) XORPIXEL(x1, y);
  1228.       Off = XY2OFF(X0,y);
  1229.       Rem = (x1-x0+2)>>1;
  1230.       for (; Rem--; Off++) {
  1231.         U16 c;
  1232.         READ_MEM(Off,c);
  1233.         c ^= 0xff; 
  1234.         WRITE_MEM(Off,c);
  1235.       }
  1236.     } else {
  1237.       U8 col = COLOR+(COLOR<<4);
  1238.       /* Draw pixels left of fill area */
  1239.       for (; (x0&1) && (x0<=x1); x0++)   SETPIXEL(x0, y, COLOR);
  1240.       /* Draw pixels right of fill area */
  1241.       for (; ((x1+1)&1)&&(x0<=x1); x1--) SETPIXEL(x1, y, COLOR);
  1242.       Off = XY2OFF(X0,y);
  1243.       Rem = (x1-x0+2)>>1;
  1244.       for (; Rem--; Off++) {
  1245.         WRITE_MEM(Off,col);
  1246.       }
  1247.     }
  1248.   }
  1249.   #undef X0
  1250. }
  1251. /*
  1252.         *********************************************************
  1253.         *                                                       *
  1254.         *          LCD_L0_DrawHLine optimized                      *
  1255.         *                                                       *
  1256.         *          8 bit bus, 1 bpp                             *
  1257.         *                                                       *
  1258.         *********************************************************
  1259. */
  1260. #elif (LCD_OPTIMIZE)             
  1261.       && (!LCD_SWAP_XY)          
  1262.       && (!LCD_MIRROR_Y)         
  1263.       && (!LCD_MIRROR_X)         
  1264.       && (LCD_BUSWIDTH==8)       
  1265.       && (!defined (LCD_LUT_SEG))   
  1266.       && (LCD_BITSPERPIXEL == 1)
  1267. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  1268.   register tOff Off = XY2OFF(x0,y);
  1269.   int iByte = x0>>3;
  1270.   int Byte1 = x1>>3;
  1271.   U8 Mask =    0xff   >> (x0&7);
  1272.   U8 EndMask = 0xff80 >> (x1&7);
  1273.   U8 Data;
  1274.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1275.     for (; iByte<Byte1; iByte++) {
  1276.       READ_MEM(Off,Data);
  1277.       Data ^= Mask; 
  1278.       WRITE_MEM(Off,Data);
  1279.       Mask = 0xff;
  1280.       Off++;
  1281.     }
  1282.     Mask &= EndMask;
  1283.     READ_MEM(Off,Data);
  1284.     Data ^= Mask; 
  1285.     WRITE_MEM(Off,Data);
  1286.   } else {                                  /* Clear pixels in line */
  1287.     int NumBytes = Byte1-iByte;
  1288.     if (COLOR==0) {
  1289.       if (NumBytes) {
  1290.         READ_MEM(Off,Data);
  1291.         Data &= (~Mask);
  1292.         WRITE_MEM(Off,Data);
  1293.         Off++; NumBytes--;
  1294.       /* Fill bytes in 2 loops for speed reasons ... */
  1295.         for (; NumBytes>=4; NumBytes-=4, Off+=4) {
  1296.           WRITE_MEM(Off,0);
  1297.           WRITE_MEM(Off+1,0);
  1298.           WRITE_MEM(Off+2,0);
  1299.           WRITE_MEM(Off+3,0);
  1300.         }
  1301.         for (; NumBytes; NumBytes--, Off++) {
  1302.           WRITE_MEM(Off,0);
  1303.         }
  1304.         Mask = 0xff;
  1305.       }
  1306.       Mask &= EndMask;
  1307.       READ_MEM(Off,Data);
  1308.       Data &= ~Mask; 
  1309.       WRITE_MEM(Off,Data);
  1310.     } else {                                  /* Set pixels in line */
  1311.       if (NumBytes) {
  1312.         READ_MEM(Off,Data); 
  1313.         Data |= Mask;
  1314.         WRITE_MEM(Off,Data);
  1315.         Off++; NumBytes--;
  1316.       /* Fill bytes in 2 loops for speed reasons ... */
  1317.         for (; NumBytes>=4; NumBytes-=4, Off+=4) {
  1318.           WRITE_MEM(Off,  0xff);
  1319.           WRITE_MEM(Off+1,0xff);
  1320.           WRITE_MEM(Off+2,0xff);
  1321.           WRITE_MEM(Off+3,0xff);
  1322.         }
  1323.         for (; NumBytes; NumBytes--, Off++) {
  1324.           WRITE_MEM(Off,0xff);
  1325.         }
  1326.         Mask = 0xff;
  1327.       }
  1328.       Mask &= EndMask;
  1329.       READ_MEM(Off,Data);
  1330.       Data |= Mask;
  1331.       WRITE_MEM(Off,Data);
  1332.     }
  1333.   }
  1334. }
  1335. /*
  1336.         *********************************************************
  1337.         *                                                       *
  1338.         *          LCD_L0_DrawHLine unoptimized                    *
  1339.         *                                                       *
  1340.         *********************************************************
  1341. */
  1342. #else  /* Unoptimized variant */
  1343. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  1344.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1345.     while (x0 <= x1) {
  1346.       XORPIXEL(x0, y);
  1347.       x0++;
  1348.     }
  1349.   } else {
  1350.     while (x0 <= x1) {
  1351.       SETPIXEL(x0, y, COLOR);
  1352.       x0++;
  1353.     }
  1354.   }
  1355. }
  1356. #endif
  1357. /********************************************************
  1358. *
  1359. *          LCD_L0_DrawVLine optimized
  1360. *
  1361. *          16 bit bus, using BITBLT
  1362. *
  1363. *********************************************************
  1364. */
  1365. #if (LCD_USE_BITBLT)           
  1366.     && (!LCD_SWAP_XY)          
  1367.     && (LCD_BUSWIDTH==16)      
  1368.     && (!defined (LCD_LUT_COM))   
  1369.     && (!defined (LCD_LUT_SEG))   
  1370.     && ((LCD_CONTROLLER == 1356)||(LCD_CONTROLLER == 13806))
  1371. void LCD_L0_DrawVLine  (int x, int y0,  int y1) {
  1372.   #if LCD_MIRROR_X
  1373.     #define X0 (LCD_XSIZE-1-(x))
  1374.   #else
  1375.     #define X0 x
  1376.   #endif
  1377.   #if LCD_MIRROR_Y
  1378.     #define Y0 (LCD_YSIZE-1-(y1))
  1379.     #define Y1 (LCD_YSIZE-1-(y0))
  1380.   #else
  1381.     #define Y0 y0
  1382.     #define Y1 y1
  1383.   #endif
  1384.   if (y0>y1) return;
  1385.   LCD_FillRectBB(X0,Y0,X0,Y1);
  1386.   #undef X0
  1387.   #undef Y0
  1388.   #undef Y1
  1389. }
  1390. /********************************************************
  1391. *
  1392. *          LCD_L0_DrawVLine optimized
  1393. *
  1394. *          8 bit bus, 4 bpp, SWAP_XY, MIRROR_Y
  1395. *
  1396. *********************************************************
  1397. */
  1398. #elif (LCD_OPTIMIZE)             
  1399.       && (LCD_SWAP_XY)          
  1400.       && (LCD_MIRROR_Y)         
  1401.       && (LCD_BUSWIDTH==8)       
  1402.       && (!defined (LCD_LUT_COM))   
  1403.       && (!defined (LCD_LUT_SEG))   
  1404.       && (LCD_BITSPERPIXEL == 4)
  1405.       
  1406. void LCD_L0_DrawVLine  (int x, int y0,  int y1) {
  1407.   #if !LCD_MIRROR_X
  1408.     int y_P = x;
  1409.   #else
  1410.     int y_P = (LCD_XSIZE-1-(x1));
  1411.   #endif
  1412.   #if !LCD_MIRROR_Y
  1413.     int x0_P = y0;
  1414.     int x1_P = y1;
  1415.   #else
  1416.     int x0_P = (LCD_YSIZE-1-(y1));
  1417.     int x1_P = (LCD_YSIZE-1-(y0));
  1418.   #endif
  1419.   register tOff Off = XY2OFF(x0_P, y_P);
  1420.   register int Rem;
  1421.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1422.     if (x0_P & 3)
  1423.       while (x0_P <= x1_P)
  1424.         XorPixel(x0_P++, y_P);
  1425.     if ((x1_P + 1) & 3)
  1426.       while (x1_P >= x0_P)
  1427.         XorPixel(x1_P--, y_P);
  1428.     Rem = (x1_P - x0_P + 1) >> 1;
  1429.     for (; Rem-- > 0; Off++) {
  1430.       U8 Contents;
  1431.       READ_MEM(Off,Contents);
  1432.       Contents ^= 0xff;
  1433.       WRITE_MEM(Off,Contents);
  1434.     }
  1435.   } else {
  1436.     U8 col = COLOR+(COLOR<<4);
  1437.     if (x0_P & 3)
  1438.       while (x0_P <= x1_P)
  1439.         _SetPixel(x0_P++, y_P, COLOR);
  1440.     if ((x1_P + 1) & 3)
  1441.       while (x1_P >= x0_P)
  1442.         _SetPixel(x1_P--, y_P, COLOR);
  1443.     Rem = (x1_P - x0_P + 1) >> 1;
  1444.     for (; Rem-- > 0; Off++)
  1445.       WRITE_MEM(Off,col);
  1446.   }
  1447.   #if 0
  1448.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1449. //      for (;  y0<=y1; y0++) XORPIXEL(x0, y0);
  1450.   } else {
  1451.     U8 col = COLOR+(COLOR<<4);
  1452.     /* Draw pixels left of fill area */
  1453.     for (; (x0_P&1) && (x0_P<=x1_P); x0_P++)
  1454.       _SetPixel(x0_P, y_P, COLOR);
  1455.     /* Draw pixels right of fill area */
  1456.     for (; ((x1_P+1)&1)&&(x0_P<=x1_P); x1_P--)
  1457.       _SetPixel(x0_P, y_P, COLOR);
  1458.     Rem = (x1_P+1-x0_P)>>1;
  1459.     for (; Rem--; Off++) {
  1460.       WRITE_MEM(Off,col);
  1461.     }
  1462.   }
  1463.   #endif
  1464. }
  1465. /*
  1466. *********************************************************
  1467. *
  1468. *          LCD_L0_DrawVLine optimized
  1469. *
  1470. *          16 bit bus, 4 bpp, SWAP_XY
  1471. *
  1472. *********************************************************
  1473. */
  1474. #elif (LCD_OPTIMIZE)               
  1475.       && (LCD_SWAP_XY)             
  1476.       && (!defined (LCD_LUT_COM))  
  1477.       && (!defined (LCD_LUT_SEG))  
  1478.       && (LCD_BITSPERPIXEL == 4)   
  1479.       && (LCD_BUSWIDTH==16)
  1480. void LCD_L0_DrawVLine  (int x, int y0,  int y1) {
  1481.   int y_P = x;
  1482.   #if (!LCD_MIRROR_Y) && (!LCD_MIRROR_X)
  1483.     int x0_P = y0;
  1484.     int x1_P = y1;
  1485.   #else
  1486.     int x0_P = (LCD_YSIZE-1-(y1));
  1487.     int x1_P = (LCD_YSIZE-1-(y0));
  1488.   #endif
  1489.   register tOff Off;
  1490.   register int Rem;
  1491.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1492.     if (x0_P & 3)
  1493.       while ((x0_P <= x1_P) && (x0_P & 3))
  1494.         XorPixel(x0_P++, y_P);
  1495.     if ((x1_P + 1) & 3)
  1496.       while ((x1_P >= x0_P) && ((x1_P + 1) & 3))
  1497.         XorPixel(x1_P--, y_P);
  1498.     Off = XY2OFF(x0_P, y_P);
  1499.     Rem = (x1_P - x0_P + 3) >> 2;
  1500.     for (; Rem-- > 0; Off++) {
  1501.       U16 Contents;
  1502.       Contents = LCD_READ_MEM(Off);
  1503.       Contents ^= 0xffff;
  1504.       LCD_WRITE_MEM(Off,Contents);
  1505.     }
  1506.   } else {
  1507.     U16 col = COLOR+(COLOR<<4)+(COLOR<<8)+(COLOR<<12);
  1508.     if (x0_P & 3)
  1509.       while ((x0_P <= x1_P) && (x0_P & 3))
  1510.         _SetPixel(x0_P++, y_P, COLOR);
  1511.     if ((x1_P + 1) & 3)
  1512.       while ((x1_P >= x0_P) && ((x1_P + 1) & 3))
  1513.         _SetPixel(x1_P--, y_P, COLOR);
  1514.     Off = XY2OFF(x0_P, y_P);
  1515.     Rem = (x1_P - x0_P + 3) >> 2;
  1516.     for (; Rem-- > 0; Off++) {
  1517.       LCD_WRITE_MEM(Off,col);
  1518.     }
  1519.   }
  1520. }
  1521. /*
  1522. *********************************************************
  1523. *
  1524. *          LCD_L0_DrawVLine optimized
  1525. *
  1526. *          16 bit bus, 8 bpp
  1527. *
  1528. *********************************************************
  1529. */
  1530. #elif (LCD_OPTIMIZE)              
  1531.       && (!LCD_SWAP_XY)          
  1532.       && (!LCD_MIRROR_Y)          
  1533.       && (!defined (LCD_LUT_COM))  
  1534.       && (!defined (LCD_LUT_SEG))  
  1535.       && (LCD_BITSPERPIXEL == 8)  
  1536.       && (LCD_BUSWIDTH==16)
  1537. void LCD_L0_DrawVLine  (int x, int y0,  int y1) {
  1538.   #if LCD_MIRROR_X
  1539.     #define X0 (LCD_XSIZE-1-(x))
  1540.   #else
  1541.     #define X0 x
  1542.   #endif
  1543.   {
  1544.     register int shift;
  1545.     register U16 AndMask, OrMask;
  1546.     register tOff Off = XY2OFF((X0),y0);
  1547.   #if LCD_MIRROR_X
  1548.     switch (x&1) {
  1549.   #else
  1550.     switch (1-(x&1)) {
  1551.   #endif
  1552.     case 0:
  1553.       shift = 0;
  1554.       break;
  1555.     case 1:
  1556.       shift = 8;
  1557.     }
  1558.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1559.       AndMask = 0xffff;
  1560.       OrMask =  (0xff << shift);
  1561.     } else {
  1562.       AndMask = ~(0xff << shift);
  1563.       OrMask = ((U16)COLOR << shift);
  1564.     }
  1565.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1566.       register U16 Mask = (0xff << shift);
  1567.       for (;y0<=y1;y0++) {
  1568.         U16 Data;
  1569.         READ_MEM(Off,Data);
  1570.         Data ^= Mask;
  1571.         WRITE_MEM(Off,Data);
  1572.         Off+= WORDSPERLINE;
  1573.       }
  1574.     } else {
  1575.       for (;y0<=y1;y0++) {
  1576.         U16 Data;
  1577.         READ_MEM(Off,Data);
  1578.         Data &= AndMask;
  1579.         Data |= OrMask;
  1580.         WRITE_MEM(Off,Data);
  1581.         Off+= WORDSPERLINE;
  1582.       }
  1583.     }
  1584.   }
  1585.   #undef X0
  1586. }
  1587. /*
  1588. *********************************************************
  1589. *
  1590. *          LCD_L0_DrawVLine no optimization
  1591. *
  1592. *          8 bit bus, 1 bpp
  1593. *
  1594. *********************************************************
  1595. */
  1596. #else  /* No optimization */
  1597. void LCD_L0_DrawVLine  (int x, int y0,  int y1) {
  1598.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1599.     while (y0 <= y1) {
  1600.       XORPIXEL(x, y0);
  1601.       y0++;
  1602.     }
  1603.   } else {
  1604.     while (y0 <= y1) {
  1605.       SETPIXEL(x, y0, COLOR);
  1606.       y0++;
  1607.     }
  1608.   }
  1609. }
  1610. #endif
  1611. /*
  1612.         *********************************************************
  1613.         *                                                       *
  1614.         *          LCD_FillRect Optimized                       *
  1615.         *                                                       *
  1616.         *          16 bit bus, Using BITBLT                     *
  1617.         *                                                       *
  1618.         *********************************************************
  1619. */
  1620. #if (LCD_USE_BITBLT)           
  1621.     && (!LCD_SWAP_XY)          
  1622.     && (LCD_BUSWIDTH==16)      
  1623.     && (!defined (LCD_LUT_COM))   
  1624.     && (!defined (LCD_LUT_SEG))   
  1625.     && ((LCD_CONTROLLER == 1356)||(LCD_CONTROLLER == 13806))
  1626. void LCD_L0_FillRect(int x0, int y0, int x1, int y1) {
  1627.   #if LCD_MIRROR_X
  1628.     #define X0 (LCD_XSIZE-1-(x1))
  1629.     #define X1 (LCD_XSIZE-1-(x0))
  1630.   #else
  1631.     #define X0 x0
  1632.     #define X1 x1
  1633.   #endif
  1634.   #if LCD_MIRROR_Y
  1635.     #define Y0 (LCD_YSIZE-1-(y1))
  1636.     #define Y1 (LCD_YSIZE-1-(y0))
  1637.   #else
  1638.     #define Y0 y0
  1639.     #define Y1 y1
  1640.   #endif
  1641.   if ((x0>x1) | (y0>y1)) return;
  1642.   LCD_FillRectBB(X0,Y0,X1,Y1);
  1643.   #undef X0
  1644.   #undef X1
  1645.   #undef Y0
  1646.   #undef Y1
  1647. }
  1648. #else
  1649. /*
  1650.         *********************************************************
  1651.         *                                                       *
  1652.         *          LCD_FillRect                                 *
  1653.         *                                                       *
  1654.         *********************************************************
  1655. */
  1656. void LCD_L0_FillRect(int x0, int y0, int x1, int y1) {
  1657. #if !LCD_SWAP_XY
  1658.   for (; y0 <= y1; y0++) {
  1659.     LCD_L0_DrawHLine(x0,y0, x1);
  1660.   }
  1661. #else
  1662.   for (; x0 <= x1; x0++) {
  1663.     LCD_L0_DrawVLine(x0,y0, y1);
  1664.   }
  1665. #endif
  1666. }
  1667. #endif
  1668. /********************************************************
  1669. *
  1670. *          Draw Bitmap 1 BPP Optimzed
  1671. *
  1672. *          8 bit bus, 1 bpp
  1673. *
  1674. *********************************************************
  1675. */
  1676. #if (LCD_OPTIMIZE)             
  1677.       && (!LCD_SWAP_XY)          
  1678.       && (!LCD_MIRROR_Y)         
  1679.       && (!LCD_MIRROR_X)         
  1680.       && (LCD_BUSWIDTH==8)       
  1681.       && (!defined (LCD_LUT_COM))   
  1682.       && (!defined (LCD_LUT_SEG))   
  1683.       && (LCD_BITSPERPIXEL == 1)
  1684. static void  DrawBitLine1BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  1685. /* only normal mode optimized */
  1686.   if (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR))
  1687.     goto DrawBitLine1BPP_NoOpt;
  1688.   {
  1689.     LCD_PIXELINDEX Index0 = *(pTrans+0);
  1690.     LCD_PIXELINDEX Index1 = *(pTrans+1);
  1691.     x+=Diff;
  1692.   /* Check if filling will do ... */
  1693.     if (Index0==Index1) {
  1694.       LCD_PIXELINDEX ColorIndexOld= COLOR;  /* Save forground color */
  1695.       COLOR = Index0;              /* Set foreground color */
  1696.       LCD_L0_DrawHLine(x,y,x+xsize-1);
  1697.       COLOR = ColorIndexOld;
  1698.       return;
  1699.     }  
  1700.     {
  1701.   /* O.K., we have to draw ... */
  1702.       tOff Off  = XY2OFF(x,y);
  1703.       int x1 = x+xsize-1;
  1704.       U8 Mask =    0xff   >> (x &7);
  1705.       U8 EndMask = 0xff80 >> (x1&7);
  1706.       U8 Data;
  1707.       U16 XorData = Index1 ? 0 : 0xffff;
  1708.       U16 PixelData;
  1709.       int NumBytes = (x1>>3) - (x>>3);
  1710.       if (NumBytes) {
  1711.   /* Write first byte (Needs to be masked) */
  1712.         READ_MEM(Off,Data);
  1713.         Data &= (~Mask);
  1714.         PixelData   = (*(p+1) | ((*p)<<8)) ^ XorData;
  1715.         PixelData >>= (8+(x&7)-(Diff&7));
  1716.         Data |= PixelData&Mask;
  1717.         WRITE_MEM(Off,Data);
  1718.         { int DiffOld = Diff;
  1719.           Diff+= 8-(x&7); 
  1720.           if ((DiffOld&~7) != (Diff&~7))
  1721.             p++;
  1722.         }
  1723.         x=0;
  1724.         Off++; NumBytes--;
  1725.   /* Write full byte */
  1726.         for (; NumBytes; NumBytes--, Off++) {
  1727.           PixelData   = (*(p+1) | ((*p)<<8))^XorData;
  1728.           PixelData >>= (8-(Diff&7));
  1729.           p++;
  1730.           WRITE_MEM(Off, PixelData);
  1731.         }
  1732.         Mask = 0xff;
  1733.       }
  1734.       PixelData   = (*(p+1) | ((*p)<<8))^XorData;
  1735.       PixelData >>= (8+(x&7)-(Diff&7));
  1736.       Mask &= EndMask;
  1737.       READ_MEM(Off,Data);
  1738.       Data &= (~Mask);
  1739.       Data |= PixelData&Mask;
  1740.       WRITE_MEM(Off,Data);
  1741.     }
  1742.     return;
  1743.   }
  1744. /* no optimization */
  1745. DrawBitLine1BPP_NoOpt:
  1746.   {
  1747.     LCD_PIXELINDEX pixels;
  1748.     LCD_PIXELINDEX Index0 = *(pTrans+0);
  1749.     LCD_PIXELINDEX Index1 = *(pTrans+1);
  1750.   /*
  1751.   // Jump to right entry point
  1752.   */
  1753.     pixels = *p;
  1754.     switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {
  1755.     case LCD_DRAWMODE_TRANS:
  1756.       switch (Diff&7) {
  1757.       case 0:
  1758.         goto WriteTBit0;
  1759.       case 1:
  1760.         goto WriteTBit1;
  1761.       case 2:
  1762.         goto WriteTBit2;
  1763.       case 3:
  1764.         goto WriteTBit3;
  1765.       case 4:
  1766.         goto WriteTBit4;
  1767.       case 5:   
  1768.         goto WriteTBit5;
  1769.       case 6:   
  1770.         goto WriteTBit6;
  1771.       case 7:   
  1772.         goto WriteTBit7;
  1773.       }
  1774.       break;
  1775.     case LCD_DRAWMODE_XOR:
  1776.       switch (Diff&7) {
  1777.       case 0:   
  1778.         goto WriteXBit0;
  1779.       case 1:   
  1780.         goto WriteXBit1;
  1781.       case 2:
  1782.         goto WriteXBit2;
  1783.       case 3:
  1784.         goto WriteXBit3;
  1785.       case 4:
  1786.         goto WriteXBit4;
  1787.       case 5:   
  1788.         goto WriteXBit5;
  1789.       case 6:   
  1790.         goto WriteXBit6;
  1791.       case 7:   
  1792.         goto WriteXBit7;
  1793.       }
  1794.     }
  1795.   /*
  1796.           Write with transparency
  1797.   */
  1798.     WriteTBit0:
  1799.       if (pixels&(1<<7)) SETPIXEL(x+0, y, Index1);
  1800.       if (!--xsize)
  1801.         return;
  1802.     WriteTBit1:
  1803.       if (pixels&(1<<6)) SETPIXEL(x+1, y, Index1);
  1804.       if (!--xsize)
  1805.         return;
  1806.     WriteTBit2:
  1807.       if (pixels&(1<<5)) SETPIXEL(x+2, y, Index1);
  1808.       if (!--xsize)
  1809.         return;
  1810.     WriteTBit3:
  1811.       if (pixels&(1<<4)) SETPIXEL(x+3, y, Index1);
  1812.       if (!--xsize)
  1813.         return;
  1814.     WriteTBit4:
  1815.       if (pixels&(1<<3)) SETPIXEL(x+4, y, Index1);
  1816.       if (!--xsize)
  1817.         return;
  1818.     WriteTBit5:
  1819.       if (pixels&(1<<2)) SETPIXEL(x+5, y, Index1);
  1820.       if (!--xsize)
  1821.         return;
  1822.     WriteTBit6:
  1823.       if (pixels&(1<<1)) SETPIXEL(x+6, y, Index1);
  1824.       if (!--xsize)
  1825.         return;
  1826.     WriteTBit7:
  1827.       if (pixels&(1<<0)) SETPIXEL(x+7, y, Index1);
  1828.       if (!--xsize)
  1829.         return;
  1830.       x+=8;
  1831.       pixels = *(++p);
  1832.       goto WriteTBit0;
  1833.   /*
  1834.           Write XOR mode
  1835.   */
  1836.     WriteXBit0:
  1837.       if (pixels&(1<<7))
  1838.         XORPIXEL(x+0, y);
  1839.       if (!--xsize)
  1840.         return;
  1841.     WriteXBit1:
  1842.       if (pixels&(1<<6))
  1843.         XORPIXEL(x+1, y);
  1844.       if (!--xsize)
  1845.         return;
  1846.     WriteXBit2:
  1847.       if (pixels&(1<<5))
  1848.         XORPIXEL(x+2, y);
  1849.       if (!--xsize)
  1850.         return;
  1851.     WriteXBit3:
  1852.       if (pixels&(1<<4))
  1853.         XORPIXEL(x+3, y);
  1854.       if (!--xsize)
  1855.         return;
  1856.     WriteXBit4:
  1857.       if (pixels&(1<<3))
  1858.         XORPIXEL(x+4, y);
  1859.       if (!--xsize)
  1860.         return;
  1861.     WriteXBit5:
  1862.       if (pixels&(1<<2))
  1863.         XORPIXEL(x+5, y);
  1864.       if (!--xsize)
  1865.         return;
  1866.     WriteXBit6:
  1867.       if (pixels&(1<<1))
  1868.         XORPIXEL(x+6, y);
  1869.       if (!--xsize)
  1870.         return;
  1871.     WriteXBit7:
  1872.       if (pixels&(1<<0))
  1873.         XORPIXEL(x+7, y);
  1874.       if (!--xsize)
  1875.         return;
  1876.       x+=8;
  1877.       pixels = *(++p);
  1878.       goto WriteXBit0;
  1879.   }
  1880. }
  1881. /********************************************************
  1882. *
  1883. *          Draw Bitmap 1 BPP Optimzed
  1884. *
  1885. *          16 bit bus, 4 bpp mode, SWAP_XY
  1886. *
  1887. *********************************************************
  1888. */
  1889. #elif (LCD_OPTIMIZE)               
  1890.     && (LCD_SWAP_XY)             
  1891.     && (!defined (LCD_LUT_COM))  
  1892.     && (!defined (LCD_LUT_SEG))  
  1893.     && (LCD_BITSPERPIXEL == 4)   
  1894.     && (LCD_BUSWIDTH==16)
  1895. static const U8 ShiftNibble[] = {
  1896.   12, 8, 4, 0
  1897. };
  1898. static void DrawBitLine1BPP_Swap(
  1899.   int x,
  1900.   int y,
  1901.   U8 const * pData,
  1902.   int ysize,
  1903.   const U8 * pTrans,
  1904.   int BytesPerLine,
  1905.   U8 Pos)
  1906. {
  1907.   int y0 = x;
  1908.   #if LCD_MIRROR_Y || LCD_MIRROR_X
  1909.     int x0 = LCD_YSIZE - y - 1;
  1910.   #else
  1911.     int x0 = y;
  1912.   #endif
  1913.   tOff Off = XY2OFF(x0,y0);
  1914.   U16 Buffer, Data;
  1915.   U8 Index, Pixel;
  1916.   U8 BufferValid = 0;
  1917.   U8 ShiftPos = 7 - (Pos & 7);
  1918.   U16 DataMask = 0x80 >> (7 -ShiftPos);
  1919.   #if LCD_MIRROR_Y || LCD_MIRROR_X
  1920.     for (; ysize; ysize--, pData += BytesPerLine, x0--) {
  1921.   #else
  1922.     for (; ysize; ysize--, pData += BytesPerLine, x0++) {
  1923.   #endif
  1924.     U8 Shift = ShiftNibble[x0 & 3];
  1925.     Pixel = (*pData & DataMask) >> ShiftPos;
  1926.     if (!BufferValid) {
  1927.       READ_MEM(Off,Buffer);
  1928.       BufferValid = 1;
  1929.     }
  1930.     switch (GUI_Context.DrawMode) {
  1931.     case LCD_DRAWMODE_NORMAL:
  1932.     case LCD_DRAWMODE_REV:
  1933.       Buffer &= ~(0xF << Shift);
  1934.       Index = *(pTrans + Pixel);
  1935.       Data = Index << Shift;
  1936.       Buffer |= Data;
  1937.       break;
  1938.     case LCD_DRAWMODE_XOR:
  1939.       if (Pixel)
  1940.         Buffer ^= (0xF << Shift);
  1941.       break;
  1942.     case LCD_DRAWMODE_TRANS:
  1943.       if (Pixel) {
  1944.         Buffer &= ~(0xF << Shift);
  1945.         Index = *(pTrans + Pixel);
  1946.         Data = Index << Shift;
  1947.         Buffer |= Data;
  1948.       }
  1949.       break;
  1950.     }
  1951.     #if LCD_MIRROR_Y || LCD_MIRROR_X
  1952.       if (!(x0 & 3)) {
  1953.         BufferValid = 0;
  1954.         WRITE_MEM(Off--, Buffer);
  1955.       }
  1956.     #else
  1957.       if ((x0 & 3) == 3) {
  1958.         BufferValid = 0;
  1959.         WRITE_MEM(Off++, Buffer);
  1960.       }
  1961.     #endif
  1962.   }
  1963.   if (BufferValid)
  1964.     WRITE_MEM(Off, Buffer);
  1965. }
  1966. /********************************************************
  1967. *
  1968. *          Draw Bitmap 1 BPP Optimzed
  1969. *
  1970. *          16 bit bus, 8 bpp mode
  1971. *
  1972. *********************************************************
  1973. */
  1974. #elif (LCD_OPTIMIZE)             
  1975.       && (!LCD_SWAP_XY)          
  1976.       && (!LCD_MIRROR_X)         
  1977.       && (LCD_BUSWIDTH==16)       
  1978.       && (!defined (LCD_LUT_SEG))   
  1979.       && (LCD_BITSPERPIXEL == 8)
  1980. static void  DrawBitLine1BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  1981.   U8 Pixels = *p;
  1982.   U8 RemPixels;
  1983.   x+= Diff;
  1984.   RemPixels = 8-Diff;
  1985.   Pixels <<= Diff;
  1986.   /* Handle transparent bitmaps */
  1987.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1988.     do {
  1989.       if (RemPixels==0) {
  1990.         Pixels = *(++p);
  1991.         RemPixels =8;
  1992.       }
  1993.       if (Pixels & 0x80) {
  1994.         XORPIXEL(x, y);
  1995.       }
  1996.       RemPixels--;
  1997.       Pixels <<=1;
  1998.       x++;
  1999.     } while (--xsize);
  2000.   } else if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) {
  2001.     do {
  2002.       if (RemPixels==0) {
  2003.         Pixels = *(++p);
  2004.         RemPixels =8;
  2005.       }
  2006.       if (Pixels & 0x80) {
  2007.         SETPIXEL(x, y, *(pTrans+1));
  2008.       }
  2009.       RemPixels--;
  2010.       Pixels <<=1;
  2011.       x++;
  2012.     } while (--xsize);
  2013.   } else {
  2014.     /* Handle solid bitmaps */
  2015.     tOff Off;
  2016.     #if LCD_MIRROR_Y
  2017.       y = (LCD_YSIZE-1-(y));
  2018.     #endif
  2019.     Off = XY2OFF(x,y);
  2020.     /* Handle left border (incomplete words) */
  2021.     if (x&1) {
  2022.       U16 Data, Pixel;
  2023.       READ_MEM(Off,Data);
  2024.       Pixel = *(pTrans+(Pixels>>7));
  2025.       Data = (Data &  ((unsigned)0xff<<8)) | (Pixel);
  2026.       WRITE_MEM(Off, Data);
  2027.       xsize--;
  2028.       RemPixels--;
  2029.       Pixels <<=1;
  2030.       Off++;
  2031.     }
  2032.     /* Handle solid middle area */
  2033.     while (xsize >=2) {
  2034.       U16 Data;
  2035.       U8 Data0,Data1;
  2036.       /* Load first pixel */
  2037.       if (RemPixels ==0) {
  2038.         Pixels = *++p;
  2039.         RemPixels =8;
  2040.       }
  2041.       Data0 = Pixels>>7;
  2042.       RemPixels--;
  2043.       Pixels <<= 1;
  2044.       /* Load second pixel */
  2045.       if (RemPixels ==0) {
  2046.         Pixels = *++p;
  2047.         RemPixels =8;
  2048.       }
  2049.       Data1 = Pixels>>7;
  2050.       RemPixels--;
  2051.       Pixels <<= 1;
  2052.       Data = ((*(pTrans+Data0)) <<8) | ((*(pTrans+Data1)));
  2053.       WRITE_MEM(Off, Data);
  2054.       xsize-=2;
  2055.       Off++;
  2056.     }
  2057.     /* Handle right border (single pixel) if necessary */
  2058.     if (xsize >0) {
  2059.       U16 Data;
  2060.       U16 Pixel;
  2061.       READ_MEM(Off,Data);
  2062.       if (RemPixels==0) {
  2063.         Pixels =*(p+1);
  2064.       }
  2065.       Pixel = *(pTrans+(Pixels>>7));
  2066.       Data = (Data & (U16)(0xff)) | (Pixel<<8);
  2067.       WRITE_MEM(Off, Data);
  2068.     }
  2069.   }
  2070. }
  2071. /********************************************************
  2072. *
  2073. *          Draw Bitmap 1 BPP Optimzed
  2074. *
  2075. *          16 bit bus, 4 bpp mode
  2076. *
  2077. *********************************************************
  2078. */
  2079. #elif (LCD_OPTIMIZE)             
  2080.       && (!LCD_SWAP_XY)          
  2081.       && (!LCD_MIRROR_X)         
  2082.       && (LCD_BUSWIDTH==16)       
  2083.       && (!defined (LCD_LUT_SEG))   
  2084.       && (LCD_BITSPERPIXEL == 4)
  2085. static void  DrawBitLine1BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  2086.   LCD_PIXELINDEX aColor[2];
  2087.   U16 Pixels = ((*p) << 8) | (*(p + 1));
  2088.   U8 RemPixels;
  2089.   p++;
  2090.   aColor[0] = *pTrans;
  2091.   aColor[1] = *(pTrans + 1);
  2092.   x += Diff;
  2093.   RemPixels = 16 - Diff;
  2094.   Pixels <<= Diff;
  2095.   /* Handle transparent bitmaps */
  2096.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  2097.     do {
  2098.       if (RemPixels==0) {
  2099.         Pixels = ((*(p + 1)) << 8) | (*(p + 2));
  2100.         p += 2;
  2101.         RemPixels = 16;
  2102.       }
  2103.       if (Pixels & 0x8000) {
  2104.         XORPIXEL(x, y);
  2105.       }
  2106.       RemPixels--;
  2107.       Pixels <<=1;
  2108.       x++;
  2109.     } while (--xsize);
  2110.   } else if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) {
  2111.     do {
  2112.       if (RemPixels==0) {
  2113.         Pixels = ((*(p + 1)) << 8) | (*(p + 2));
  2114.         p += 2;
  2115.         RemPixels = 16;
  2116.       }
  2117.       if (Pixels & 0x8000) {
  2118.         SETPIXEL(x, y, *(pTrans+1));
  2119.       }
  2120.       RemPixels--;
  2121.       Pixels <<=1;
  2122.       x++;
  2123.     } while (--xsize);
  2124.   } else {
  2125.     /* Handle solid bitmaps */
  2126.     tOff Off;
  2127.     #if LCD_MIRROR_Y
  2128.       y = (LCD_YSIZE-1-(y));
  2129.     #endif
  2130.     Off = XY2OFF(x,y);
  2131.     /* Handle left border (incomplete words) */
  2132.     if (x & 3) {
  2133.       U16 Data;
  2134.       U8 LeftRem = 4 - (x & 3);
  2135.       READ_MEM(Off, Data);
  2136.       if (LeftRem == 1) {
  2137.         Data &= 0xfff0;
  2138.         Data |= (Pixels & (U16)(1<<15)) ? aColor[1] : aColor[0];
  2139.       } else if (LeftRem == 2) {
  2140.         Data &= 0xff0f;
  2141.         Data |= ((Pixels & (U16)(1<<15)) ? aColor[1] : aColor[0]) << 4;
  2142.         if (xsize > 1) {
  2143.           Data &= 0xfff0;
  2144.           Data |= (Pixels & (1<<14)) ? aColor[1] : aColor[0];
  2145.         }
  2146.       } else if (LeftRem == 3) {
  2147.         Data &= 0xf0ff;
  2148.         Data |= ((Pixels & (U16)(1<<15)) ? aColor[1] : aColor[0]) << 8;
  2149.         if (xsize > 1) {
  2150.           Data &= 0xff0f;
  2151.           Data |= ((Pixels & (1<<14)) ? aColor[1] : aColor[0]) << 4;
  2152.           if (xsize > 2) {
  2153.             Data &= 0xfff0;
  2154.             Data |= (Pixels & (1<<13)) ? aColor[1] : aColor[0];
  2155.           }
  2156.         }
  2157.       }
  2158.       WRITE_MEM(Off, Data);
  2159.       xsize -= LeftRem;
  2160.       Off++;
  2161.       RemPixels -= LeftRem;
  2162.       Pixels <<= LeftRem;
  2163.     }
  2164.     /* Handle solid middle area */
  2165.     while (xsize >= 4) {
  2166.       U16 Data;
  2167.       Data  = ((Pixels & (U16)(1<<15)) ? aColor[1] : aColor[0]) << 12;
  2168.       Data |= ((Pixels & (1<<14)) ? aColor[1] : aColor[0]) << 8;
  2169.       Data |= ((Pixels & (1<<13)) ? aColor[1] : aColor[0]) << 4;
  2170.       Data |= ((Pixels & (1<<12)) ? aColor[1] : aColor[0]);
  2171.       RemPixels -= 4;
  2172.       Pixels <<= 4;
  2173.       WRITE_MEM(Off, Data);
  2174.       xsize -= 4;
  2175.       Off++;
  2176.       if (RemPixels <= 3) {
  2177.         U16 NewPixels;
  2178.         p++;
  2179.         NewPixels = ((*p) << 8) | (*(p + 1));
  2180.         NewPixels >>= RemPixels ;
  2181.         Pixels |= NewPixels;
  2182.         RemPixels += 8;
  2183.       }
  2184.     }
  2185.     /* Handle right border (single pixel) if necessary */
  2186.     if (xsize > 0) {
  2187.       U16 Data;
  2188.       READ_MEM(Off, Data);
  2189.       Data &= 0x0fff;
  2190.       Data |= ((Pixels & (U16)(1<<15)) ? aColor[1] : aColor[0]) << 12;
  2191.       if (xsize > 1) {
  2192.         Data &= 0xf0ff;
  2193.         Data |= ((Pixels & (1<<14)) ? aColor[1] : aColor[0]) << 8;
  2194.         if (xsize > 2) {
  2195.           Data &= 0xff0f;
  2196.           Data |= ((Pixels & (1<<13)) ? aColor[1] : aColor[0]) << 4;
  2197.         }
  2198.       }
  2199.       WRITE_MEM(Off, Data);
  2200.     }
  2201.   }
  2202. }
  2203. /*
  2204. *********************************************************
  2205. *
  2206. *          Draw Bitmap 1 BPP unoptimzed
  2207. *
  2208. *********************************************************
  2209. */
  2210. #else
  2211. static void  DrawBitLine1BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  2212.   LCD_PIXELINDEX pixels;
  2213.   LCD_PIXELINDEX Index0 = *(pTrans+0);
  2214.   LCD_PIXELINDEX Index1 = *(pTrans+1);
  2215. /*
  2216. // Jump to right entry point
  2217. */
  2218.   pixels = *p;
  2219.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {
  2220.   case 0:
  2221.     #if defined (SETNEXTPIXEL)   /* Optimization ! */
  2222.       x+=Diff;
  2223.       SetPosXY(x,y);
  2224.     #endif
  2225.     switch (Diff&7) {
  2226.     case 0:   
  2227.       goto WriteBit0;
  2228.     case 1:   
  2229.       goto WriteBit1;
  2230.     case 2:
  2231.       goto WriteBit2;
  2232.     case 3:
  2233.       goto WriteBit3;
  2234.     case 4:
  2235.       goto WriteBit4;
  2236.     case 5:   
  2237.       goto WriteBit5;
  2238.     case 6:   
  2239.       goto WriteBit6;
  2240.     case 7:   
  2241.       goto WriteBit7;
  2242.     }
  2243.     break;
  2244.   case LCD_DRAWMODE_TRANS:
  2245.     switch (Diff&7) {
  2246.     case 0:
  2247.       goto WriteTBit0;
  2248.     case 1:
  2249.       goto WriteTBit1;
  2250.     case 2:
  2251.       goto WriteTBit2;
  2252.     case 3:
  2253.       goto WriteTBit3;
  2254.     case 4:
  2255.       goto WriteTBit4;
  2256.     case 5:   
  2257.       goto WriteTBit5;
  2258.     case 6:   
  2259.       goto WriteTBit6;
  2260.     case 7:   
  2261.       goto WriteTBit7;
  2262.     }
  2263.     break;
  2264.   case LCD_DRAWMODE_XOR:
  2265.     switch (Diff&7) {
  2266.     case 0:   
  2267.       goto WriteXBit0;
  2268.     case 1:   
  2269.       goto WriteXBit1;
  2270.     case 2:
  2271.       goto WriteXBit2;
  2272.     case 3:
  2273.       goto WriteXBit3;
  2274.     case 4:
  2275.       goto WriteXBit4;
  2276.     case 5:   
  2277.       goto WriteXBit5;
  2278.     case 6:   
  2279.       goto WriteXBit6;
  2280.     case 7:   
  2281.       goto WriteXBit7;
  2282.     }
  2283.   }
  2284. /*
  2285.         Write with transparency
  2286. */
  2287.   WriteTBit0:
  2288.     if (pixels&(1<<7)) SETPIXEL(x+0, y, Index1);
  2289.     if (!--xsize)
  2290.       return;
  2291.   WriteTBit1:
  2292.     if (pixels&(1<<6)) SETPIXEL(x+1, y, Index1);
  2293.     if (!--xsize)
  2294.       return;
  2295.   WriteTBit2:
  2296.     if (pixels&(1<<5)) SETPIXEL(x+2, y, Index1);
  2297.     if (!--xsize)
  2298.       return;
  2299.   WriteTBit3:
  2300.     if (pixels&(1<<4)) SETPIXEL(x+3, y, Index1);
  2301.     if (!--xsize)
  2302.       return;
  2303.   WriteTBit4:
  2304.     if (pixels&(1<<3)) SETPIXEL(x+4, y, Index1);
  2305.     if (!--xsize)
  2306.       return;
  2307.   WriteTBit5:
  2308.     if (pixels&(1<<2)) SETPIXEL(x+5, y, Index1);
  2309.     if (!--xsize)
  2310.       return;
  2311.   WriteTBit6:
  2312.     if (pixels&(1<<1)) SETPIXEL(x+6, y, Index1);
  2313.     if (!--xsize)
  2314.       return;
  2315.   WriteTBit7:
  2316.     if (pixels&(1<<0)) SETPIXEL(x+7, y, Index1);
  2317.     if (!--xsize)
  2318.       return;
  2319.     x+=8;
  2320.     pixels = *(++p);
  2321.     goto WriteTBit0;
  2322. /*
  2323.         Write without transparency
  2324. */
  2325. #if defined (SETNEXTPIXEL)   /* Optimization ! */
  2326.   WriteBit0:
  2327.     SetNextPixel((pixels&(1<<7)) ? Index1 : Index0);
  2328.     if (!--xsize) {
  2329. End_WriteBit:
  2330.       END_SETNEXTPIXEL();
  2331.       return;
  2332.     }
  2333.   WriteBit1:
  2334.     SetNextPixel((pixels&(1<<6)) ? Index1 : Index0);
  2335.     if (!--xsize)
  2336.       goto End_WriteBit;
  2337.   WriteBit2:
  2338.     SetNextPixel((pixels&(1<<5)) ? Index1 : Index0);
  2339.     if (!--xsize)
  2340.       goto End_WriteBit;
  2341.   WriteBit3:
  2342.     SetNextPixel((pixels&(1<<4)) ? Index1 : Index0);
  2343.     if (!--xsize)
  2344.       goto End_WriteBit;
  2345.   WriteBit4:
  2346.     SetNextPixel((pixels&(1<<3)) ? Index1 : Index0);
  2347.     if (!--xsize)
  2348.       goto End_WriteBit;
  2349.   WriteBit5:
  2350.     SetNextPixel((pixels&(1<<2)) ? Index1 : Index0);
  2351.     if (!--xsize)
  2352.       goto End_WriteBit;
  2353.   WriteBit6:
  2354.     SetNextPixel((pixels&(1<<1)) ? Index1 : Index0);
  2355.     if (!--xsize)
  2356.       goto End_WriteBit;
  2357.   WriteBit7:
  2358.     SetNextPixel((pixels&(1<<0)) ? Index1 : Index0);
  2359.     if (!--xsize)
  2360.       goto End_WriteBit;
  2361.     x+=8;
  2362.     pixels = *(++p);
  2363.     goto WriteBit0;
  2364. #else
  2365.   WriteBit0:
  2366.     SETPIXEL(x+0, y, (pixels&(1<<7)) ? Index1 : Index0);
  2367.     if (!--xsize)
  2368.       return;
  2369.   WriteBit1:
  2370.     SETPIXEL(x+1, y, (pixels&(1<<6)) ? Index1 : Index0);
  2371.     if (!--xsize)
  2372.       return;
  2373.   WriteBit2:
  2374.     SETPIXEL(x+2, y, (pixels&(1<<5)) ? Index1 : Index0);
  2375.     if (!--xsize)
  2376.       return;
  2377.   WriteBit3:
  2378.     SETPIXEL(x+3, y, (pixels&(1<<4)) ? Index1 : Index0);
  2379.     if (!--xsize)
  2380.       return;
  2381.   WriteBit4:
  2382.     SETPIXEL(x+4, y, (pixels&(1<<3)) ? Index1 : Index0);
  2383.     if (!--xsize)
  2384.       return;
  2385.   WriteBit5:
  2386.     SETPIXEL(x+5, y, (pixels&(1<<2)) ? Index1 : Index0);
  2387.     if (!--xsize)
  2388.       return;
  2389.   WriteBit6:
  2390.     SETPIXEL(x+6, y, (pixels&(1<<1)) ? Index1 : Index0);
  2391.     if (!--xsize)
  2392.       return;
  2393.   WriteBit7:
  2394.     SETPIXEL(x+7, y, (pixels&(1<<0)) ? Index1 : Index0);
  2395.     if (!--xsize)
  2396.       return;
  2397.     x+=8;
  2398.     pixels = *(++p);
  2399.     goto WriteBit0;
  2400. #endif
  2401. /*
  2402.         Write XOR mode
  2403. */
  2404.   WriteXBit0:
  2405.     if (pixels&(1<<7))
  2406.       XORPIXEL(x+0, y);
  2407.     if (!--xsize)
  2408.       return;
  2409.   WriteXBit1:
  2410.     if (pixels&(1<<6))
  2411.       XORPIXEL(x+1, y);
  2412.     if (!--xsize)
  2413.       return;
  2414.   WriteXBit2:
  2415.     if (pixels&(1<<5))
  2416.       XORPIXEL(x+2, y);
  2417.     if (!--xsize)
  2418.       return;
  2419.   WriteXBit3:
  2420.     if (pixels&(1<<4))
  2421.       XORPIXEL(x+3, y);
  2422.     if (!--xsize)
  2423.       return;
  2424.   WriteXBit4:
  2425.     if (pixels&(1<<3))
  2426.       XORPIXEL(x+4, y);
  2427.     if (!--xsize)
  2428.       return;
  2429.   WriteXBit5:
  2430.     if (pixels&(1<<2))
  2431.       XORPIXEL(x+5, y);
  2432.     if (!--xsize)
  2433.       return;
  2434.   WriteXBit6:
  2435.     if (pixels&(1<<1))
  2436.       XORPIXEL(x+6, y);
  2437.     if (!--xsize)
  2438.       return;
  2439.   WriteXBit7:
  2440.     if (pixels&(1<<0))
  2441.       XORPIXEL(x+7, y);
  2442.     if (!--xsize)
  2443.       return;
  2444.     x+=8;
  2445.     pixels = *(++p);
  2446.     goto WriteXBit0;
  2447. }
  2448. #endif
  2449. /*
  2450.         *********************************************************
  2451.         *                                                       *
  2452.         *  Draw Bitmap 2 BPP                                    *
  2453.         *                                                       *
  2454.         *********************************************************
  2455. */
  2456. #if (LCD_MAX_LOG_COLORS > 2)
  2457. static void  DrawBitLine2BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  2458.   LCD_PIXELINDEX pixels;
  2459. /*
  2460. // Jump to right entry point
  2461. */
  2462.   pixels = *p;
  2463.   if (pTrans) {
  2464.     /*
  2465.       with palette
  2466.     */
  2467.     if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) switch (Diff&3) {
  2468.     case 0:
  2469.       goto WriteTBit0;
  2470.     case 1:
  2471.       goto WriteTBit1;
  2472.     case 2:
  2473.       goto WriteTBit2;
  2474.     default:
  2475.       goto WriteTBit3;
  2476.     } else switch (Diff&3) {
  2477.     case 0:
  2478.       goto WriteBit0;
  2479.     case 1:
  2480.       goto WriteBit1;
  2481.     case 2:
  2482.       goto WriteBit2;
  2483.     default:
  2484.       goto WriteBit3;
  2485.     }
  2486.   /*
  2487.           Write without transparency
  2488.   */
  2489.   WriteBit0:
  2490.     SETPIXEL(x+0, y, *(pTrans+(pixels>>6)));
  2491.     if (!--xsize)
  2492.       return;
  2493.   WriteBit1:
  2494.     SETPIXEL(x+1, y, *(pTrans+(3&(pixels>>4))));
  2495.     if (!--xsize)
  2496.       return;
  2497.   WriteBit2:
  2498.     SETPIXEL(x+2, y, *(pTrans+(3&(pixels>>2))));
  2499.     if (!--xsize)
  2500.       return;
  2501.   WriteBit3:
  2502.     SETPIXEL(x+3, y, *(pTrans+(3&(pixels))));
  2503.     if (!--xsize)
  2504.       return;
  2505.     pixels = *(++p);
  2506.     x+=4;
  2507.     goto WriteBit0;
  2508.   /*
  2509.           Write with transparency
  2510.   */
  2511.   WriteTBit0:
  2512.     if (pixels&(3<<6))
  2513.       SETPIXEL(x+0, y, *(pTrans+(pixels>>6)));
  2514.     if (!--xsize)
  2515.       return;
  2516.   WriteTBit1:
  2517.     if (pixels&(3<<4))
  2518.       SETPIXEL(x+1, y, *(pTrans+(3&(pixels>>4))));
  2519.     if (!--xsize)
  2520.       return;
  2521.   WriteTBit2:
  2522.     if (pixels&(3<<2))
  2523.       SETPIXEL(x+2, y, *(pTrans+(3&(pixels>>2))));
  2524.     if (!--xsize)
  2525.       return;
  2526.   WriteTBit3:
  2527.     if (pixels&(3<<0))
  2528.       SETPIXEL(x+3, y, *(pTrans+(3&(pixels))));
  2529.     if (!--xsize)
  2530.       return;
  2531.     pixels = *(++p);
  2532.     x+=4;
  2533.     goto WriteTBit0;
  2534.   } else { 
  2535.     /* 
  2536.       without palette 
  2537.     */
  2538.     if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) switch (Diff&3) {
  2539.     case 0:
  2540.       goto WriteDDPTBit0;
  2541.     case 1:
  2542.       goto WriteDDPTBit1;
  2543.     case 2:
  2544.       goto WriteDDPTBit2;
  2545.     default:
  2546.       goto WriteDDPTBit3;
  2547.     } else switch (Diff&3) {
  2548.     case 0:
  2549.       goto WriteDDPBit0;
  2550.     case 1:
  2551.       goto WriteDDPBit1;
  2552.     case 2:
  2553.       goto WriteDDPBit2;
  2554.     default:
  2555.       goto WriteDDPBit3;
  2556.     }
  2557.   /*
  2558.           Write without transparency
  2559.   */
  2560.   WriteDDPBit0:
  2561.     SETPIXEL(x+0, y, (pixels>>6));
  2562.     if (!--xsize)
  2563.       return;
  2564.   WriteDDPBit1:
  2565.     SETPIXEL(x+1, y, (3&(pixels>>4)));
  2566.     if (!--xsize)
  2567.       return;
  2568.   WriteDDPBit2:
  2569.     SETPIXEL(x+2, y, (3&(pixels>>2)));
  2570.     if (!--xsize)
  2571.       return;
  2572.   WriteDDPBit3:
  2573.     SETPIXEL(x+3, y, (3&(pixels)));
  2574.     if (!--xsize)
  2575.       return;
  2576.     pixels = *(++p);
  2577.     x+=4;
  2578.     goto WriteDDPBit0;
  2579.   /*
  2580.           Write with transparency
  2581.   */
  2582.   WriteDDPTBit0:
  2583.     if (pixels&(3<<6))
  2584.       SETPIXEL(x+0, y, (pixels>>6));
  2585.     if (!--xsize)
  2586.       return;
  2587.   WriteDDPTBit1:
  2588.     if (pixels&(3<<4))
  2589.       SETPIXEL(x+1, y, (3&(pixels>>4)));
  2590.     if (!--xsize)
  2591.       return;
  2592.   WriteDDPTBit2:
  2593.     if (pixels&(3<<2))
  2594.       SETPIXEL(x+2, y, (3&(pixels>>2)));
  2595.     if (!--xsize)
  2596.       return;
  2597.   WriteDDPTBit3:
  2598.     if (pixels&(3<<0))
  2599.       SETPIXEL(x+3, y, (3&(pixels)));
  2600.     if (!--xsize)
  2601.       return;
  2602.     pixels = *(++p);
  2603.     x+=4;
  2604.     goto WriteDDPTBit0;
  2605.   }
  2606. }
  2607. #endif
  2608. #if (LCD_MAX_LOG_COLORS > 4)
  2609. /**********************************************************
  2610. *
  2611. *          Draw Bitmap 4 BPP, optimized
  2612. *
  2613. *          16 bit bus, 4 bpp mode
  2614. *
  2615. *********************************************************
  2616. */
  2617. #if (LCD_OPTIMIZE)               
  2618.     && (LCD_MAX_LOG_COLORS > 4)  
  2619.     && (LCD_BITSPERPIXEL == 4)   
  2620.     && (LCD_MIRROR_X==0)         
  2621.     && (LCD_BUSWIDTH==16)        
  2622.     && (!LCD_SWAP_XY)            
  2623.     && (!defined (LCD_LUT_SEG))
  2624. static void  DrawBitLine4BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  2625.   U16 Data;
  2626.   U16 DataOut;
  2627.   U16 Mask;
  2628.   U8  Phase = x&1;
  2629.   x += Diff;   /* Set x back to the orignal position before clipping */
  2630.   if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) { 
  2631.     U8 Pixels;
  2632.     U8 RemPixels =0;
  2633.     if (Diff) {
  2634.       RemPixels = Diff;
  2635.       Pixels = (*p++) << (RemPixels<<2);
  2636.     }
  2637.     do {
  2638.       /* Load data if necessary */
  2639.       if (RemPixels == 0) {
  2640.         Pixels = *p++;
  2641.         RemPixels = 2;
  2642.       }
  2643.       /* Set pixel if index != 0 */
  2644.       if (Pixels & 0xf0) {
  2645.         if (pTrans) {
  2646.           SETPIXEL(x, y, *(pTrans + (Pixels >> 4)));
  2647.         } else {
  2648.           SETPIXEL(x, y, (Pixels >> 4));
  2649.         }
  2650.       }
  2651.       /* inc counters / ptrs etc. */
  2652.       RemPixels--;
  2653.       Pixels <<= 4;
  2654.       x++;
  2655.     } while (--xsize);
  2656.   } else { /* Handle non-transparent bitmaps */
  2657.     tOff Off;
  2658.     #if LCD_MIRROR_Y
  2659.       y = LCD_YSIZE - 1 - y;
  2660.     #endif
  2661.     Off = XY2OFF(x, y);
  2662.     /* Handle left border */
  2663.     if (x & 3) {
  2664.       U8 LeftRem = 4- (x & 3);
  2665.       /* Load data */
  2666.       if (Phase == 0) {
  2667.         Data = *p++ <<8;
  2668.         if (LeftRem >2) {
  2669.           Data |= *(p++);
  2670.         } else {
  2671.           Data >>= 8;
  2672.         }
  2673.       } else {
  2674.         Data = *p <<4;
  2675.         if (LeftRem >1) {
  2676.           Data |= (*++p >>4);
  2677.         } else {
  2678.           Data >>= 8;
  2679.         }
  2680.       }
  2681.       /* Convert logical indices to physical indices */
  2682.       if (pTrans) {
  2683.         DataOut  = *(pTrans + (Data & 0xf));
  2684.         if (LeftRem >1) {
  2685.           DataOut |= *(pTrans + ((Data>>4) & 0xf)) <<4;
  2686.           if (LeftRem >2) {
  2687.             DataOut |= *(pTrans + ((Data>>8) & 0xf)) <<8;
  2688.           }
  2689.         }
  2690.       } else {
  2691.         DataOut  = (Data & 0xf);
  2692.         if (LeftRem >1) {
  2693.           DataOut |= ((Data>>4) & 0xf) <<4;
  2694.           if (LeftRem >2) {
  2695.             DataOut |= ((Data>>8) & 0xf) <<8;
  2696.           }
  2697.         }
  2698.       }
  2699.       /* Mask output data */
  2700.       Mask =  0xffff >> (16-(LeftRem << 2));     /* Mask out pixels to the left */
  2701.       if (xsize < LeftRem) {
  2702.         Mask &= 0xffff << ((LeftRem-xsize) << 2);      /* Mask out pixels to the right */
  2703.       }
  2704.       DataOut &= Mask;
  2705.       /* Or unchanged pixels */
  2706.       READ_MEM(Off, Data);
  2707.       DataOut |= Data &~Mask;
  2708.       /* output data */
  2709.       WRITE_MEM(Off, DataOut);
  2710.       xsize -= LeftRem;
  2711.       Off++;
  2712.     }
  2713.     /* Handle solid middle area (4 pixels at a time)*/
  2714.     while (xsize >= 4) {
  2715.       /* Load data */
  2716.       if (Phase == 0) {
  2717.         Data = (*p <<8) | *(p+1) ;
  2718.       } else {
  2719.         Data = (*p <<12) | (*(p+1) <<4) | (*(p+2) >>4);
  2720.       }
  2721.       /* Convert logical indices to physical indices */
  2722.       if (pTrans) {
  2723.         DataOut  = *(pTrans + (Data & 0xf));
  2724.         DataOut |= *(pTrans + ((Data>>4) & 0xf)) <<4;
  2725.         DataOut |= *(pTrans + ((Data>>8) & 0xf)) <<8;
  2726.         DataOut |= *(pTrans +  (Data>>12))       <<12;
  2727.       } else {
  2728.         DataOut  = (Data & 0xf);
  2729.         DataOut |= ((Data>>4) & 0xf) <<4;
  2730.         DataOut |= ((Data>>8) & 0xf) <<8;
  2731.         DataOut |= (Data>>12)       <<12;
  2732.       }
  2733.       /* output data */
  2734.       WRITE_MEM(Off, DataOut);
  2735.       /* inc counters / ptrs etc. */
  2736.       p+=2;
  2737.       xsize -= 4;
  2738.       Off++;
  2739.     }
  2740.     /* Handle right border */
  2741.     if (xsize >0) {    /* Anything to do at all ? */
  2742.       /* Load data */
  2743.       if (Phase == 0) {
  2744.         Data = (*p <<8);
  2745.         if (xsize > 2) {
  2746.           Data |= (*(p+1));
  2747.         }
  2748.       } else {
  2749.         Data = (*p <<12);
  2750.         if (xsize > 1) {
  2751.           Data |= (*(p+1) <<4);
  2752.         }
  2753.       }
  2754.       /* Convert logical indices to physical indices */
  2755.       if (pTrans) {
  2756.         DataOut  = *(pTrans + (Data>>12)) <<12;
  2757.         if (xsize > 1) {
  2758.           DataOut |= *(pTrans + ((Data>>8) & 0xf)) <<8;
  2759.           if (xsize > 2) {
  2760.             DataOut |= *(pTrans + ((Data>>4) & 0xf)) <<4;
  2761.           }
  2762.         }
  2763.       } else {
  2764.         DataOut  = (Data>>12) <<12;
  2765.         if (xsize > 1) {
  2766.           DataOut |= ((Data>>8) & 0xf) <<8;
  2767.           if (xsize > 2) {
  2768.             DataOut |= ((Data>>4) & 0xf) <<4;
  2769.           }
  2770.         }
  2771.       }
  2772.       /* Mask output data */
  2773.       Mask = 0xffff << ((4-xsize)<<2);
  2774.       DataOut &= Mask;
  2775.       /* Or unchanged pixels */
  2776.       READ_MEM(Off, Data);
  2777.       DataOut |= Data &~Mask;
  2778.       /* output data */
  2779.       WRITE_MEM(Off, DataOut);
  2780.     }
  2781.   }
  2782. }
  2783. /********************************************************
  2784. *
  2785. *          Draw Bitmap 4 BPP Optimzed
  2786. *
  2787. *          16 bit bus, 4 bpp mode, SWAP_XY
  2788. *
  2789. *********************************************************
  2790. */
  2791. #elif (LCD_OPTIMIZE)               
  2792.     && (LCD_SWAP_XY)             
  2793.     && (!defined (LCD_LUT_COM))  
  2794.     && (!defined (LCD_LUT_SEG))  
  2795.     && (LCD_BITSPERPIXEL == 4)   
  2796.     && (LCD_BUSWIDTH==16)
  2797. static void DrawBitLine4BPP_Swap(/**/
  2798.   int x,
  2799.   int y,
  2800.   U8 const * pData,
  2801.   int ysize,
  2802.   const U8 * pTrans,
  2803.   int BytesPerLine,
  2804.   U8 Pos)
  2805. {
  2806.   int y0 = x;
  2807.   #if LCD_MIRROR_Y || LCD_MIRROR_X
  2808.     int x0 = LCD_YSIZE - y - 1;
  2809.   #else
  2810.     int x0 = y;
  2811.   #endif
  2812.   tOff Off = XY2OFF(x0,y0);
  2813.   U16 Buffer, Data;
  2814.   U8 Index, Pixel;
  2815.   U8 BufferValid = 0;
  2816.   U8 ShiftPos = (1 - (Pos & 1)) << 2;
  2817.   U16 DataMask = 0xf0 >> (4 - ShiftPos);
  2818.   #if LCD_MIRROR_Y || LCD_MIRROR_X
  2819.     for (; ysize; ysize--, pData += BytesPerLine, x0--) {
  2820.   #else
  2821.     for (; ysize; ysize--, pData += BytesPerLine, x0++) {
  2822.   #endif
  2823.     U8 Shift = ShiftNibble[x0 & 3];
  2824.     Pixel = (*pData & DataMask) >> ShiftPos;
  2825.     if (!BufferValid) {
  2826.       READ_MEM(Off,Buffer);
  2827.       BufferValid = 1;
  2828.     }
  2829.     switch (GUI_Context.DrawMode) {
  2830.     case LCD_DRAWMODE_NORMAL:
  2831.     case LCD_DRAWMODE_REV:
  2832.       Buffer &= ~(0xF << Shift);
  2833.       if (pTrans) {
  2834.         Index = *(pTrans + Pixel);
  2835.       } else {
  2836.         Index = Pixel;
  2837.       }
  2838.       Data = Index << Shift;
  2839.       Buffer |= Data;
  2840.       break;
  2841.     case LCD_DRAWMODE_XOR:
  2842.       if (Pixel)
  2843.         Buffer ^= (0xF << Shift);
  2844.       break;
  2845.     case LCD_DRAWMODE_TRANS:
  2846.       if (Pixel) {
  2847.         Buffer &= ~(0xF << Shift);
  2848.         if (pTrans) {
  2849.           Index = *(pTrans + Pixel);
  2850.         } else {
  2851.           Index = Pixel;
  2852.         }
  2853.         Data = Index << Shift;
  2854.         Buffer |= Data;
  2855.       }
  2856.       break;
  2857.     }
  2858.     #if LCD_MIRROR_Y || LCD_MIRROR_X
  2859.       if (!(x0 & 3)) {
  2860.         BufferValid = 0;
  2861.         WRITE_MEM(Off--, Buffer);
  2862.       }
  2863.     #else
  2864.       if ((x0 & 3) == 3) {
  2865.         BufferValid = 0;
  2866.         WRITE_MEM(Off++, Buffer);
  2867.       }
  2868.     #endif
  2869.   }
  2870.   if (BufferValid)
  2871.     WRITE_MEM(Off, Buffer);
  2872. }
  2873. /**********************************************************
  2874. *
  2875. *          Draw Bitmap 4 BPP, optimized
  2876. *
  2877. *          16 bit bus, 8 bpp mode
  2878. *
  2879. *********************************************************
  2880. */
  2881. #elif (LCD_OPTIMIZE)               
  2882.     && (LCD_MAX_LOG_COLORS > 4) 
  2883.     && (LCD_BITSPERPIXEL == 8)   
  2884.     && (LCD_MIRROR_X==0)         
  2885.     && (LCD_BUSWIDTH==16)        
  2886.     && (!LCD_SWAP_XY)            
  2887.     && (!defined (LCD_LUT_COM))
  2888. static void  DrawBitLine4BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  2889.   LCD_PIXELINDEX Pixels = *p;
  2890.   U8 RemPixels;
  2891.   if (Diff&1) {
  2892.     x++;
  2893.     RemPixels = 1;
  2894.     Pixels <<= 4;
  2895.   } else {
  2896.     RemPixels = 2;
  2897.   }
  2898.   /* Handle transparent bitmaps */
  2899.   if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) {
  2900.     if (pTrans) {
  2901.       do {
  2902.         if (RemPixels==0) {
  2903.           Pixels = *(++p);
  2904.           RemPixels =2;
  2905.         }
  2906.         if (Pixels & 0xf0) {
  2907.           SETPIXEL(x, y, *(pTrans+(Pixels>>4)));
  2908.         }
  2909.         RemPixels--;
  2910.         Pixels <<=4;
  2911.         x++;
  2912.       } while (--xsize);
  2913.     } else {
  2914.       do {
  2915.         if (RemPixels==0) {
  2916.           Pixels = *(++p);
  2917.           RemPixels =2;
  2918.         }
  2919.         if (Pixels & 0xf0) {
  2920.           SETPIXEL(x, y, (Pixels>>4));
  2921.         }
  2922.         RemPixels--;
  2923.         Pixels <<=4;
  2924.         x++;
  2925.       } while (--xsize);
  2926.     }
  2927.   } else {
  2928.     tOff Off;
  2929.     #if LCD_MIRROR_Y
  2930.       y = (LCD_YSIZE-1-(y));
  2931.     #endif
  2932.     /* Handle solid bitmaps */
  2933.     Off = XY2OFF(x,y);
  2934.     /* Handle left border (incomplete words) */
  2935.     if (x&1) {
  2936.       U16 Data, Pixel;
  2937.       READ_MEM(Off,Data);
  2938.       if (pTrans) {
  2939.         Pixel = *(pTrans+(Pixels>>4));
  2940.       } else {
  2941.         Pixel = (Pixels>>4);
  2942.       }
  2943.       Data = (Data &  ((unsigned)0xff<<8)) | (Pixel);
  2944.       WRITE_MEM(Off, Data);
  2945.       xsize--;
  2946.       RemPixels--;
  2947.       Pixels <<=4;
  2948.       Off++;
  2949.     }
  2950.     /* Handle solid middle area */
  2951.     while (xsize >=2) {
  2952.       U16 Data;
  2953.       U8 Data0,Data1;
  2954.       if ((RemPixels&1) ==0) {
  2955.         if (RemPixels ==0) {
  2956.           Pixels = *++p;
  2957.         } else {
  2958.           RemPixels =0;
  2959.         }
  2960.         Data0 = Pixels>>4;
  2961.         Data1 = Pixels&15;
  2962.       } else {
  2963.         Data0 = Pixels>>4;
  2964.         Pixels = *++p;
  2965.         Data1 = Pixels>>4;
  2966.         Pixels<<=4;
  2967.       }
  2968.       Data = ((*(pTrans+Data0)) <<8) | ((*(pTrans+Data1)));
  2969.       WRITE_MEM(Off, Data);
  2970.       xsize-=2;
  2971.       Off++;
  2972.     }
  2973.     /* Handle right border (single pixel) if necessary */
  2974.     if (xsize >0) {
  2975.       U16 Data;
  2976.       U16 Pixel;
  2977.       READ_MEM(Off,Data);
  2978.       if (RemPixels==0) {
  2979.         Pixels =*(p+1);
  2980.       }
  2981.       if (pTrans) {
  2982.         Pixel = *(pTrans+(Pixels>>4));
  2983.       } else {
  2984.         Pixel = (Pixels>>4);
  2985.       }
  2986.       Data = (Data & (U16)(0xff)) | (Pixel<<8);
  2987.       WRITE_MEM(Off, Data);
  2988.     }
  2989.   }
  2990. }
  2991. /*
  2992.         *********************************************************
  2993.         *                                                       *
  2994.         *  Draw Bitmap 4 BPP, unoptimized (default)             *
  2995.         *                                                       *
  2996.         *********************************************************
  2997. */
  2998. #else
  2999. static void  DrawBitLine4BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  3000.   LCD_PIXELINDEX pixels;
  3001. /*
  3002. // Jump to right entry point
  3003. */
  3004.   pixels = *p;
  3005.   if (pTrans) {
  3006.     /*
  3007.       with palette
  3008.     */
  3009.     if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) {
  3010.       if ((Diff&1) ==0)
  3011.         goto WriteTBit0;
  3012.       goto WriteTBit1;
  3013.     } else {
  3014.       if ((Diff&1) ==0)
  3015.         goto WriteBit0;
  3016.       goto WriteBit1;
  3017.     }
  3018.   /*
  3019.           Write without transparency
  3020.   */
  3021.   WriteBit0:
  3022.     SETPIXEL(x+0, y, *(pTrans+(pixels>>4)));
  3023.     if (!--xsize)
  3024.       return;
  3025.   WriteBit1:
  3026.     SETPIXEL(x+1, y, *(pTrans+(pixels&0xf)));
  3027.     if (!--xsize)
  3028.       return;
  3029.     x+=2;
  3030.     pixels = *(++p);
  3031.     goto WriteBit0;
  3032.   /*
  3033.           Write with transparency
  3034.   */
  3035.   WriteTBit0:
  3036.     if (pixels>>4)
  3037.       SETPIXEL(x+0, y, *(pTrans+(pixels>>4)));
  3038.     if (!--xsize)
  3039.       return;
  3040.   WriteTBit1:
  3041.     if (pixels&0xf)
  3042.       SETPIXEL(x+1, y, *(pTrans+(pixels&0xf)));
  3043.     if (!--xsize)
  3044.       return;
  3045.     x+=2;
  3046.     pixels = *(++p);
  3047.     goto WriteTBit0;
  3048.   } else {
  3049.     /*
  3050.       without palette
  3051.     */
  3052.     if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) {
  3053.       if ((Diff&1) ==0)
  3054.         goto WriteDDPTBit0;
  3055.       goto WriteDDPTBit1;
  3056.     } else {
  3057.       if ((Diff&1) ==0)
  3058.         goto WriteDDPBit0;
  3059.       goto WriteDDPBit1;
  3060.     }
  3061.   /*
  3062.           Write without transparency
  3063.   */
  3064.   WriteDDPBit0:
  3065.     SETPIXEL(x+0, y, (pixels>>4));
  3066.     if (!--xsize)
  3067.       return;
  3068.   WriteDDPBit1:
  3069.     SETPIXEL(x+1, y, (pixels&0xf));
  3070.     if (!--xsize)
  3071.       return;
  3072.     x+=2;
  3073.     pixels = *(++p);
  3074.     goto WriteDDPBit0;
  3075.   /*
  3076.           Write with transparency
  3077.   */
  3078.   WriteDDPTBit0:
  3079.     if (pixels>>4)
  3080.       SETPIXEL(x+0, y, (pixels>>4));
  3081.     if (!--xsize)
  3082.       return;
  3083.   WriteDDPTBit1:
  3084.     if (pixels&0xf)
  3085.       SETPIXEL(x+1, y, (pixels&0xf));
  3086.     if (!--xsize)
  3087.       return;
  3088.     x+=2;
  3089.     pixels = *(++p);
  3090.     goto WriteDDPTBit0;
  3091.   }
  3092. }
  3093. #endif
  3094. #endif
  3095. /*
  3096. *********************************************************
  3097. *
  3098. *  Draw Bitmap 8 BPP  (256 colors)
  3099. *
  3100. *      16 bit bus, 4 bpp
  3101. *
  3102. *********************************************************
  3103. */
  3104. #if (LCD_OPTIMIZE)               
  3105.     && (LCD_MAX_LOG_COLORS > 16) 
  3106.     && (LCD_BITSPERPIXEL == 4)   
  3107.     && (LCD_MIRROR_X==0)         
  3108.     && (LCD_BUSWIDTH==16)        
  3109.     && (!LCD_SWAP_XY)            
  3110.     && (!defined (LCD_LUT_SEG))
  3111. static void  DrawBitLine8BPP(int x, int y, U8 const*p, int xsize, const LCD_PIXELINDEX*pTrans) {
  3112.   LCD_PIXELINDEX pixel;
  3113.   #if LCD_MIRROR_Y
  3114.     #define Y (LCD_YSIZE - 1 - y)
  3115.   #endif
  3116.   if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS)==0) {
  3117.     register tOff Off;
  3118.     /* Handle bitmaps with palette */
  3119.     if (pTrans) {
  3120.       for (; xsize > 0; xsize--, x++, p++) {
  3121.         pixel = *p;
  3122.         if (pixel) {
  3123.           SETPIXEL(x+0, y, *(pTrans+pixel));
  3124.         }
  3125.       }
  3126.     /* Handle bitmaps without palette */
  3127.     } else {
  3128.       #if 1 /* Optimized 020104 */
  3129.         U16 Data;
  3130.         U16 DataOut;
  3131.         U16 Mask;
  3132.         /* Offset */
  3133.         #if LCD_MIRROR_Y
  3134.           y = LCD_YSIZE - 1 - y;
  3135.         #endif
  3136.         Off = XY2OFF(x, y);
  3137.         /* Handle left border */
  3138.         if (x & 3) {
  3139.           /* Load data */
  3140.           U8 LeftRem = 4 - (x & 3);
  3141.           DataOut = (*(p + LeftRem - 1));
  3142.           if (LeftRem > 1) {
  3143.             DataOut |= (*(p + LeftRem - 2)) << 4;
  3144.             if (LeftRem > 2) {
  3145.               DataOut |= (*(p + LeftRem - 3)) << 8;
  3146.             }
  3147.           }
  3148.           /* Mask output data */
  3149.           Mask =  0xffff >> (16 - (LeftRem << 2));       /* Mask out pixels to the left */
  3150.           if (xsize < LeftRem) {
  3151.             Mask &= 0xffff << ((LeftRem - xsize) << 2);  /* Mask out pixels to the right */
  3152.           }
  3153.           DataOut &= Mask;
  3154.           /* Or unchanged pixels */
  3155.           READ_MEM(Off, Data);
  3156.           DataOut |= Data & ~Mask;
  3157.           /* output data */
  3158.           WRITE_MEM(Off, DataOut);
  3159.           xsize -= LeftRem;
  3160.           Off++;
  3161.           p += LeftRem;
  3162.         }
  3163.         /* Handle solid middle area (4 pixels at a time)*/
  3164.         while (xsize >= 4) {
  3165.           /* Load data */
  3166.           DataOut = (*p << 12) | (*(p + 1) << 8) | (*(p + 2) << 4) | *(p + 3);
  3167.           p += 4;
  3168.           /* output data */
  3169.           WRITE_MEM(Off, DataOut);
  3170.           /* inc counters / ptrs etc. */
  3171.           xsize -= 4;
  3172.           Off++;
  3173.         }
  3174.         /* Handle right border */
  3175.         if (xsize >0) {    /* Anything to do at all ? */
  3176.           /* Load data */
  3177.           DataOut = (*p++) << 12;
  3178.           if (xsize > 1) {
  3179.             DataOut |= (*p++) << 8;
  3180.             if (xsize > 2) {
  3181.               DataOut |= (*p) << 4;
  3182.             }
  3183.           }
  3184.           /* Mask output data */
  3185.           Mask = 0xffff << ((4 - xsize) << 2);
  3186.           DataOut &= Mask;
  3187.           /* Or unchanged pixels */
  3188.           READ_MEM(Off, Data);
  3189.           DataOut |= Data & ~Mask;
  3190.           /* output data */
  3191.           WRITE_MEM(Off, DataOut);
  3192.         }
  3193.       #else /* Old */
  3194.         for (;(x&3)&& (xsize>0); x++,xsize--) {
  3195.           SETPIXEL(x, y, *p++);
  3196.         }
  3197.         Off = XY2OFF(x,Y);
  3198.         /* Write 4 pixels at a time */
  3199.         if (xsize >=4) { 
  3200.           int LoopRem = xsize>>2;
  3201.           x += xsize &~3;
  3202.           xsize &=3;
  3203.           for (;--LoopRem>=0; p+=4,Off++) {
  3204.             U16 Data = (*p<<(4+8)) | (*(p+1)<<(0+8))| (*(p+2)<<(4))| (*(p+3));
  3205.             LCD_WRITE_MEM(Off, Data);
  3206.           }
  3207.         }
  3208.         for (;xsize>0; x++,xsize--) {
  3209.           SETPIXEL(x, y, *p++);
  3210.         }
  3211.       #endif
  3212.     }
  3213.   } else {
  3214.     /* Handle transparent bitmap with palette */
  3215.     if (pTrans) {
  3216.       while (xsize > 0) {
  3217.         pixel = *p;
  3218.         if (pixel != 0)
  3219.           SETPIXEL(x+0, y, *(pTrans+pixel));
  3220.         xsize--;
  3221.         x++;
  3222.         p++;
  3223.       }
  3224.     /* Handle transparent bitmap without palette */
  3225.     } else {
  3226.       while (xsize > 0) {
  3227.         pixel = *p;
  3228.         if (pixel != 0)
  3229.           SETPIXEL(x+0, y, pixel);
  3230.         xsize--;
  3231.         x++;
  3232.         p++;
  3233.       }
  3234.     }
  3235.   }
  3236. }
  3237. /*
  3238.         *********************************************************
  3239.         *                                                       *
  3240.         *  Draw Bitmap 8 BPP  (256 colors)                      *
  3241.         *                                                       *
  3242.         *      16 bit bus, 8 bpp                                *
  3243.         *                                                       *
  3244.         *********************************************************
  3245. */
  3246. #elif (LCD_OPTIMIZE)               
  3247.     && (LCD_MAX_LOG_COLORS > 16) 
  3248.     && (LCD_BITSPERPIXEL == 8)   
  3249.     && (LCD_MIRROR_X==0)         
  3250.     && (LCD_BUSWIDTH==16)        
  3251.     && (!LCD_SWAP_XY)            
  3252.     && (!defined (LCD_LUT_SEG))
  3253. static void  DrawBitLine8BPP(int x, int y, U8 const*p, int xsize, const LCD_PIXELINDEX*pTrans) {
  3254.   LCD_PIXELINDEX pixel;
  3255.   if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS)==0) {
  3256.     register tOff Off;
  3257.     /* Handle bitmaps with palette */
  3258.     if (pTrans) {
  3259.       /* Handle first pixel seperatly if on odd position */
  3260.       if (x&1) {
  3261.         pixel = *p++;
  3262.         SETPIXEL(x+0, y, *(pTrans+pixel));
  3263.         x++;
  3264.         xsize--;
  3265.       }
  3266.       #if LCD_MIRROR_Y
  3267.         y = (LCD_YSIZE-1-(y));
  3268.       #endif
  3269.       Off = XY2OFF(x,y);
  3270.       x+= xsize&~1;
  3271.       /* Optimization for longer lines ... */
  3272.       for (;xsize>8; xsize-=8, p+=8, Off+=4) {
  3273.         WRITE_MEM(Off,   (*(pTrans+*p)     << 8) | (*(pTrans+*(p+1))));
  3274.         WRITE_MEM(Off+1, (*(pTrans+*(p+2)) << 8) | (*(pTrans+*(p+3))));
  3275.         WRITE_MEM(Off+2, (*(pTrans+*(p+4)) << 8) | (*(pTrans+*(p+5))));
  3276.         WRITE_MEM(Off+3, (*(pTrans+*(p+6)) << 8) | (*(pTrans+*(p+7))));
  3277.       }
  3278.       /* Handle 2 pixels at a time */
  3279.       for (; xsize >= 2; xsize-=2) {
  3280.         U16 Data = (*(pTrans+*p) << 8) | (*(pTrans+*(p+1)));
  3281.         WRITE_MEM(Off,Data);
  3282.         p+=2;
  3283.         Off++;
  3284.       }
  3285.       /* Handle last pixel (if one is left) */
  3286.       if (xsize > 0) {
  3287.         #if LCD_MIRROR_Y
  3288.           y = (LCD_YSIZE-1-(y));
  3289.         #endif
  3290.         pixel = *p;
  3291.         SETPIXEL(x+0, y, *(pTrans+pixel));
  3292.         xsize--;
  3293.         x++;
  3294.         p++;
  3295.       }
  3296.     /* Handle bitmaps without palette */
  3297.     } else {
  3298.       #if defined(LCD_DATAADR) & !defined(WIN32)
  3299.         memcpy((U16*)(LCD_DATAADR+x+((U32)y)*LCD_VXSIZE), p,xsize);
  3300.       #else
  3301.         if (x&1) {
  3302.           pixel = *p++;
  3303.           SETPIXEL(x+0, y, pixel);
  3304.           x++;
  3305.           xsize--;
  3306.         }
  3307.         #if LCD_MIRROR_Y
  3308.           y = (LCD_YSIZE-1-(y));
  3309.         #endif
  3310.         Off = XY2OFF(x,y);
  3311.         x+= xsize&~1;
  3312.         /* Optimization for longer lines ... */
  3313.         for (;xsize>8; xsize-=8, p+=8, Off+=4) {
  3314.           WRITE_MEM(Off,   (*(p)   << 8) | (*(p+1)));
  3315.           WRITE_MEM(Off+1, (*(p+2) << 8) | (*(p+3)));
  3316.           WRITE_MEM(Off+2, (*(p+4) << 8) | (*(p+5)));
  3317.           WRITE_MEM(Off+3, (*(p+6) << 8) | (*(p+7)));
  3318.         }
  3319.         /* Handle 2 pixels at a time */
  3320.         for (; xsize >= 2; xsize-=2) {
  3321.           U16 Data = (*(p) << 8) | (*(p+1));
  3322.           WRITE_MEM(Off,Data);
  3323.           p+=2;
  3324.           Off++;
  3325.         }
  3326.         /* Handle last pixel (if one is left) */
  3327.         if (xsize > 0) {
  3328.           #if LCD_MIRROR_Y
  3329.             y = (LCD_YSIZE-1-(y));
  3330.           #endif
  3331.           pixel = *p;
  3332.           SETPIXEL(x+0, y, pixel);
  3333.           xsize--;
  3334.           x++;
  3335.           p++;
  3336.         }
  3337.       #endif
  3338.       }
  3339.   } else {
  3340.     /* Handle transparent bitmap with palette */
  3341.     if (pTrans) {
  3342.       while (xsize > 0) {
  3343.         pixel = *p;
  3344.         if (pixel != 0)
  3345.           SETPIXEL(x+0, y, *(pTrans+pixel));
  3346.         xsize--;
  3347.         x++;
  3348.         p++;
  3349.       }
  3350.     /* Handle transparent bitmap without palette */
  3351.     } else {
  3352.       while (xsize > 0) {
  3353.         pixel = *p;
  3354.         if (pixel != 0)
  3355.           SETPIXEL(x+0, y, pixel);
  3356.         xsize--;
  3357.         x++;
  3358.         p++;
  3359.       }
  3360.     }
  3361.   }
  3362. }
  3363. #else
  3364. /*
  3365.         *********************************************************
  3366.         *                                                       *
  3367.         *  Draw Bitmap 8 BPP  (256 colors)                      *
  3368.         *                                                       *
  3369.         *      Default (no optimization)                        *
  3370.         *                                                       *
  3371.         *********************************************************
  3372. */
  3373. static void  DrawBitLine8BPP(int x, int y, U8 const*p, int xsize, const LCD_PIXELINDEX*pTrans) {
  3374.   LCD_PIXELINDEX pixel;
  3375.   if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS)==0) {
  3376.     if (pTrans) {
  3377.       for (;xsize > 0; xsize--,x++,p++) {
  3378.         pixel = *p;
  3379.         SETPIXEL(x, y, *(pTrans+pixel));
  3380.       }
  3381.     } else {
  3382.       for (;xsize > 0; xsize--,x++,p++) {
  3383.         SETPIXEL(x, y, *p);
  3384.       }
  3385.     }
  3386.   } else {   /* Handle transparent bitmap */
  3387.     if (pTrans) {
  3388.       for (; xsize > 0; xsize--, x++, p++) {
  3389.         pixel = *p;
  3390.         if (pixel) {
  3391.           SETPIXEL(x+0, y, *(pTrans+pixel));
  3392.         }
  3393.       }
  3394.     } else {
  3395.       for (; xsize > 0; xsize--, x++, p++) {
  3396.         pixel = *p;
  3397.         if (pixel) {
  3398.           SETPIXEL(x+0, y, pixel);
  3399.         }
  3400.       }
  3401.     }
  3402.   }
  3403. }
  3404. #endif
  3405. /*
  3406.         *********************************************************
  3407.         *                                                       *
  3408.         *  Draw Bitmap 8 BPP  (256 colors)                      *
  3409.         *                                                       *
  3410.         *      16 bit bus, 8 bpp                                *
  3411.         *                                                       *
  3412.         *********************************************************
  3413. */
  3414. #if (LCD_BITSPERPIXEL > 8)
  3415. #if (LCD_OPTIMIZE)               
  3416.     && (LCD_MAX_LOG_COLORS > 16) 
  3417.     && (LCD_BITSPERPIXEL == 16)   
  3418.     && (LCD_MIRROR_X==0)         
  3419.     && (LCD_BUSWIDTH==16)        
  3420.     && (!LCD_SWAP_XY)            
  3421.     && (!defined (LCD_LUT_SEG))
  3422. static void  DrawBitLine16BPP(int x, int y, U16 const*p, int xsize) {
  3423.   LCD_PIXELINDEX Index;
  3424.   register tOff Off;
  3425.   #if LCD_MIRROR_Y
  3426.     y = (LCD_YSIZE-1-(y));
  3427.   #endif
  3428.   Off = XY2OFF(x,y);
  3429.   if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS)==0) {
  3430.     /* Always write first pixel */
  3431.     Index = *p;
  3432.     WRITE_MEM(Off, Index);
  3433.     /* Unrolled loop */
  3434.     while ( xsize > 4 ) {
  3435.       WRITE_MEM(Off+1, *(p+1));
  3436.       WRITE_MEM(Off+2, *(p+2));
  3437.       WRITE_MEM(Off+3, *(p+3));
  3438.       WRITE_MEM(Off+4, *(p+4));
  3439.       Off += 4;
  3440.       p += 4;
  3441.       xsize -=4;
  3442.     }
  3443.     /* End loop */
  3444.     for (; --xsize; ) {
  3445.       Off++;
  3446.       Index = *++p;
  3447.       WRITE_MEM(Off, Index);
  3448.     }
  3449.   } else {   /* Handle transparent bitmap */
  3450.     for (; xsize > 0; xsize--, x++, p++) {
  3451.       Index = *p;
  3452.       if (Index) {
  3453.         SETPIXEL(x+0, y, Index);
  3454.       }
  3455.     }
  3456.   }
  3457. }
  3458. /*
  3459.         *********************************************************
  3460.         *                                                       *
  3461.         *  Draw Bitmap 16 BPP
  3462.         *                                                       *
  3463.         *      Default (no optimization)                        *
  3464.         *                                                       *
  3465.         *********************************************************
  3466. */
  3467. #else
  3468. static void  DrawBitLine16BPP(int x, int y, U16 const*p, int xsize) {
  3469.   LCD_PIXELINDEX Index;
  3470.   if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS)==0) {
  3471.     for (;xsize > 0; xsize--,x++,p++) {
  3472.       SETPIXEL(x, y, *p);
  3473.     }
  3474.   } else {   /* Handle transparent bitmap */
  3475.     for (; xsize > 0; xsize--, x++, p++) {
  3476.       Index = *p;
  3477.       if (Index) {
  3478.         SETPIXEL(x+0, y, Index);
  3479.       }
  3480.     }
  3481.   }
  3482. }
  3483. #endif
  3484. #endif
  3485. /*
  3486.         *********************************************************
  3487.         *                                                       *
  3488.         *         Universal draw Bitmap routine                 *
  3489.         *                                                       *
  3490.         *********************************************************
  3491. */
  3492. void LCD_L0_DrawBitmap   (int x0, int y0,
  3493.                        int xsize, int ysize,
  3494.                        int BitsPerPixel, 
  3495.                        int BytesPerLine,
  3496.                        const U8* pData, int Diff,
  3497.                        const LCD_PIXELINDEX* pTrans)
  3498. {
  3499.   int i;
  3500.   /*
  3501.      Use BitBlt engine (if available)
  3502.   */
  3503.   #if LCD_USE_BITBLT              
  3504.       && (LCD_BUSWIDTH==16)       
  3505.       && ((LCD_CONTROLLER == 1356)||(LCD_CONTROLLER == 13806)) 
  3506.       && (LCD_MIRROR_X==0)         
  3507.       && (!defined (LCD_LUT_COM))  
  3508.       && (!defined (LCD_LUT_SEG))
  3509.     /*
  3510.     int y1 = y0+ysize-1;
  3511.     int x1 = x0+xsize-1;
  3512.     */
  3513.     if ((BitsPerPixel==1) && !(GUI_Context.DrawMode & LCD_DRAWMODE_XOR)) {
  3514.       LCD_DrawBitmap1BPPBB(x0, y0, pData, Diff, xsize, ysize, BytesPerLine, pTrans);
  3515.       return;
  3516.     }
  3517.   #endif
  3518.   /*
  3519.      Use DrawBitLineXBPP
  3520.   */
  3521.   switch (BitsPerPixel) {
  3522.   case 1:
  3523.     #if (LCD_OPTIMIZE)               
  3524.         && (LCD_SWAP_XY)             
  3525.         && (!defined (LCD_LUT_COM))  
  3526.         && (!defined (LCD_LUT_SEG))  
  3527.         && (LCD_BITSPERPIXEL == 4)   
  3528.         && (LCD_BUSWIDTH==16)
  3529.       xsize += Diff & 7;
  3530.       for (i = Diff; i < xsize; i++) {
  3531.         DrawBitLine1BPP_Swap(x0+i, y0, pData + (i>>3), ysize, pTrans, BytesPerLine, i);
  3532.       }
  3533.     #else
  3534.       for (i=0; i<ysize; i++) {
  3535.         DrawBitLine1BPP(x0, i+y0, pData, Diff, xsize, pTrans);
  3536.         pData += BytesPerLine;
  3537.       }
  3538.     #endif
  3539.     break;
  3540.   #if (LCD_MAX_LOG_COLORS > 2)
  3541.     case 2:
  3542.       for (i=0; i<ysize; i++) {
  3543.         DrawBitLine2BPP(x0, i+y0, pData, Diff, xsize, pTrans);
  3544.         pData += BytesPerLine;
  3545.       }
  3546.       break;
  3547.   #endif
  3548.   #if (LCD_MAX_LOG_COLORS > 4)
  3549.     case 4:
  3550.       #if (LCD_OPTIMIZE)               
  3551.           && (LCD_SWAP_XY)             
  3552.           && (!defined (LCD_LUT_COM))  
  3553.           && (!defined (LCD_LUT_SEG))  
  3554.           && (LCD_BITSPERPIXEL == 4)   
  3555.           && (LCD_BUSWIDTH==16)
  3556.         xsize += Diff & 1;
  3557.         for (i = Diff; i < xsize; i++) {
  3558.           DrawBitLine4BPP_Swap(x0+i, y0, pData + (i>>1), ysize, pTrans, BytesPerLine, i);
  3559.         }
  3560.       #else
  3561.         for (i=0; i<ysize; i++) {
  3562.           DrawBitLine4BPP(x0, i+y0, pData, Diff, xsize, pTrans);
  3563.           pData += BytesPerLine;
  3564.         }
  3565.       #endif
  3566.       break;
  3567.   #endif
  3568.   #if (LCD_MAX_LOG_COLORS > 16)
  3569.     case 8:
  3570.       for (i=0; i<ysize; i++) {
  3571.         DrawBitLine8BPP(x0, i+y0, pData, xsize, pTrans);
  3572.         pData += BytesPerLine;
  3573.       }
  3574.       break;
  3575.   #endif
  3576.   #if (LCD_BITSPERPIXEL > 8)
  3577.     case 16:
  3578.       for (i=0; i<ysize; i++) {
  3579.         DrawBitLine16BPP(x0, i+y0, (U16*)pData, xsize);
  3580.         pData += BytesPerLine;
  3581.       }
  3582.       break;
  3583.   #endif
  3584.   }
  3585. }
  3586. /********************************************************
  3587. *
  3588. *       LCD_L0_SetOrg
  3589. *
  3590. *********************************************************
  3591. Purpose:        Sets the original position of the virtual display.
  3592.                 Has no function at this point with the PC-driver.
  3593. */
  3594. int OrgX, OrgY;
  3595. void LCD_L0_SetOrg(int x, int y) {
  3596.   OrgX = x;
  3597.   OrgY = y;
  3598. }
  3599. /*
  3600.         *********************************************************
  3601.         *                                                       *
  3602.         *       LCD_On                                          *
  3603.         *       LCD_Off                                         *
  3604.         *                                                       *
  3605.         *********************************************************
  3606. */
  3607. void LCD_Off          (void) {
  3608. #ifdef LCD_OFF
  3609.   LCD_ENABLE_REG_ACCESS();
  3610.   LCD_OFF();
  3611.   LCD_ENABLE_MEM_ACCESS();
  3612. #endif
  3613. }
  3614. void LCD_On           (void) {
  3615. #ifdef LCD_ON
  3616.   LCD_ENABLE_REG_ACCESS();
  3617.   LCD_ON();
  3618.   LCD_ENABLE_MEM_ACCESS();
  3619. #endif
  3620. }
  3621. unsigned int LCD_L0_GetPixelIndex(int x, int y) {
  3622.   return GETPIXEL(x,y);
  3623. }
  3624. /*
  3625.         *********************************************************
  3626.         *                                                       *
  3627.         *                   LCD_L0_SetLUTEntry                     *
  3628.         *                                                       *
  3629.         *********************************************************
  3630. */
  3631. void LCD_L0_SetLUTEntry(U8 Pos, LCD_COLOR color) {
  3632.   int i;
  3633.   #if LCD_BITSPERPIXEL
  3634.     U16 aColorSep[3];
  3635.     for (i=0; i<3; i++) {
  3636.       aColorSep[i] = color &0xff;
  3637.       color>>=8;
  3638.     }
  3639.   #endif
  3640. /* Convert 8 bit color seperation into index */
  3641.   #if (LCD_CONTROLLER == 1374)   /* Calculation for controllers with 4 bit LUT */   
  3642.     ||(LCD_CONTROLLER == 1375) ||(LCD_CONTROLLER == 13705)  
  3643.     ||(LCD_CONTROLLER == 1356) ||(LCD_CONTROLLER == 13506)  
  3644.     ||(LCD_CONTROLLER == 13806)
  3645.     for (i=0; i<3; i++)
  3646.       aColorSep[i] = (U16)(aColorSep[i]+8)/17;
  3647.   #endif
  3648.   #if (LCD_CONTROLLER == 1376)   /* Calculation for controllers with 6 bit LUT */
  3649.     for (i=0; i<3; i++)
  3650.       aColorSep[i] = (aColorSep[i])/4;
  3651.   #endif
  3652. /* Write into palette register */
  3653.   LCD_ENABLE_REG_ACCESS();
  3654.   #if (LCD_CONTROLLER == 1375) || (LCD_CONTROLLER == 1374)  /* 4 bit palette */
  3655.     #if (LCD_BUSWIDTH == 16)
  3656.       WRITE_REG((0x14>>1), Pos * 0x101);   /* Select position */
  3657.       for (i=0; i<3; i++) {
  3658.         WRITE_REG((0x16>>1), ((U16)aColorSep[i]*17) <<8);  /* 1375 expects high nibble, 1374 low nibble (so this works on both) */
  3659.       }
  3660.     #else
  3661.       WRITE_REG((0x15), Pos);   /* Select position */
  3662.       for (i=0; i<3; i++) {
  3663.         WRITE_REG((0x17), aColorSep[i]<<4);
  3664.       }
  3665.     #endif
  3666.   #elif ((LCD_CONTROLLER == 1356)||(LCD_CONTROLLER == 13806))
  3667.     #if (LCD_BUSWIDTH == 16)
  3668.       WRITE_REG(0x01e2/2, Pos);   /* Select position */
  3669.       for (i=0; i<3; i++) {
  3670.         WRITE_REG(0x01e4/2, aColorSep[i]<<4);
  3671.       }
  3672.     #else
  3673.       #error Not yet defined
  3674.     #endif
  3675.   #elif (LCD_CONTROLLER == 1376)
  3676.     #if 0
  3677.     #if LCD_SWAP_BYTE_ORDER
  3678.       /* Write Green and Blue into regs 8/9 */
  3679.       LCD_WRITE_REG((0x8>>1), ((aColorSep[2]<<2)| (aColorSep[1]<<(8+2))));
  3680.       /* Write Red into regs 0xa, index into 0xb */
  3681.       LCD_WRITE_REG(0xa>>1, (Pos<<8)  | (aColorSep[0]<<2));   /* Select position */
  3682.    #else
  3683.       /* Write Green and Blue into regs 8/9 */
  3684.       LCD_WRITE_REG((0x8>>1), (aColorSep[2]<<(8+2))| (aColorSep[1]<<2));
  3685.       /* Write Red into regs 0xa, index into 0xb */
  3686.       LCD_WRITE_REG(0xa>>1, Pos  | (aColorSep[0]<<(8+2)));   /* Select position */
  3687.    #endif
  3688.    #endif /* 0 */
  3689.     /* Write Green and Blue into regs 8/9 */
  3690.     WRITE_REG((0x8>>1), (aColorSep[2]<<(8+2))| (aColorSep[1]<<2));
  3691.     /* Write Red into regs 0xa, index into 0xb */
  3692.     WRITE_REG(0xa>>1, Pos  | (aColorSep[0]<<(8+2)));   /* Select position */
  3693.   #else
  3694.     Pos=Pos;
  3695.     color = color;
  3696.   #endif
  3697.   LCD_ENABLE_MEM_ACCESS();
  3698. }
  3699. /*
  3700.         *********************************************************
  3701.         *                                                       *
  3702.         *       LCD_L0_ReInit : Re-Init the display                *
  3703.         *                                                       *
  3704.         *********************************************************
  3705. ReInit contains all of the code that can be re-executed at any point without
  3706. changing or even disturbing what can be seen on the LCD.
  3707. Note that it is also used as a subroutine by LCD_Init().
  3708. */
  3709. void  LCD_L0_ReInit(void) {
  3710.   LCD_ENABLE_REG_ACCESS();
  3711.   LCD_INIT_CONTROLLER();                     /* macro defined in config */
  3712. #if LCD_USE_BITBLT
  3713.   WRITE_REG(0x10c/2,WORDSPERLINE);       /* Write Bit blit engine line offset */
  3714.   WRITE_REG(0x100/2,0x0);                /* Stop engine (to be on the safe side ...) */
  3715. #endif
  3716.   LCD_ENABLE_MEM_ACCESS();
  3717. }
  3718. /*
  3719.         *********************************************************
  3720.         *                                                       *
  3721.         *       LCD_Init : Init the display                     *
  3722.         *                                                       *
  3723.         *********************************************************
  3724. */
  3725. int  LCD_L0_Init(void) {
  3726.   GUI_DEBUG_LOG("nLCD_Init()");
  3727. /* check production code */
  3728. /*
  3729. #if LCD_CONTROLLER == 1374
  3730.   if ((READ_REG_BYTE(0) &0xfc) != (6<<2)) {
  3731.     GUI_DEBUG_ERROROUT("nLCD13XX: 1374 controller not found");
  3732.     return LCD_ERR_CONTROLLER_NOT_FOUND;
  3733. }
  3734. #elif LCD_CONTROLLER == 1375
  3735.   if ((READ_REG_BYTE(0) >>2) != 0x9) {
  3736.     GUI_DEBUG_ERROROUT("nLCD13XX: 1375 controller not found");
  3737.     return LCD_ERR_CONTROLLER_NOT_FOUND;
  3738. }
  3739. #endif
  3740. */
  3741. #if LCD_CONTROLLER == 1374
  3742.   { int ProdCode;
  3743.     LCD_ENABLE_REG_ACCESS();
  3744.     ProdCode = READ_REG_BYTE(0) >>2;
  3745.     LCD_ENABLE_MEM_ACCESS();
  3746.     if ((ProdCode != 6)    /* 1374 */
  3747.       &&(ProdCode != 9))   /* 1375 */
  3748.     return LCD_ERR_CONTROLLER_NOT_FOUND;
  3749.   }
  3750. #endif
  3751. /* Init controllers (except lookup table) */
  3752.   LCD_L0_ReInit();
  3753.   LCD_Off();
  3754. /* Quick check video memory */
  3755. #if (LCD_BUSWIDTH == 16)
  3756.   LCD_WRITE_MEM(0,0);
  3757.   LCD_WRITE_MEM(1,0x5253);
  3758.   if ((LCD_READ_MEM(0) != 0) || (LCD_READ_MEM(1) != 0x5253)) {
  3759.     GUI_DEBUG_ERROROUT("nLCD13XX: video memory problem");
  3760.     return LCD_ERR_MEMORY;
  3761.   }
  3762.   LCD_WRITE_MEM(1,0);
  3763. #else
  3764.   LCD_WRITE_MEM(0,0);
  3765.   LCD_WRITE_MEM(1,0x52);
  3766.   if ((LCD_READ_MEM(0) != 0) || (LCD_READ_MEM(1) != 0x52)) {
  3767.     GUI_DEBUG_ERROROUT("nLCD13XX: video memory problem");
  3768.     return LCD_ERR_MEMORY;
  3769.   }
  3770. #endif
  3771.   return 0;    /* Init successfull ! */
  3772. }
  3773. /*
  3774.         *********************************************************
  3775.         *                                                       *
  3776.         *       LCD_L0_CheckInit                                   *
  3777.         *                                                       *
  3778.         *  Check if display controller(s) is/are still          *
  3779.         *  properly initialized                                 *
  3780.         *                                                       *
  3781.         *********************************************************
  3782. Return value: 0 => No error, init is O.K.
  3783. */
  3784. int LCD_L0_CheckInit(void) {
  3785.   return 0;
  3786. }
  3787. #else
  3788. void LCD13XX(void) { } /* avoid empty object files */
  3789. #endif  /* (LCD_CONTROLLER/100 == 13) */