PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Dependents:   Sensitive

Fork of PokittoLib by Jonne Valola

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HWLCD.cpp Source File

HWLCD.cpp

Go to the documentation of this file.
00001 /**************************************************************************/
00002 /*!
00003     @file     HWLCD.cpp
00004     @author   Jonne Valola
00005 
00006     @section LICENSE
00007 
00008     Software License Agreement (BSD License)
00009 
00010     Copyright (c) 2016, Jonne Valola
00011     All rights reserved.
00012 
00013     Redistribution and use in source and binary forms, with or without
00014     modification, are permitted provided that the following conditions are met:
00015     1. Redistributions of source code must retain the above copyright
00016     notice, this list of conditions and the following disclaimer.
00017     2. Redistributions in binary form must reproduce the above copyright
00018     notice, this list of conditions and the following disclaimer in the
00019     documentation and/or other materials provided with the distribution.
00020     3. Neither the name of the copyright holders nor the
00021     names of its contributors may be used to endorse or promote products
00022     derived from this software without specific prior written permission.
00023 
00024     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
00025     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00028     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 */
00035 /**************************************************************************/
00036 
00037 #include "HWLCD.h " //HWLCD.h" #include "HWLCD.h"
00038 #include "Pokitto_settings.h "
00039 
00040 #define AB_JUMP 1024 // jump one 1-bit Arduboy screen forward to get next color bit
00041 #define GB_JUMP 504 // jump one 1-bit Gamebuino screen forward to get next color bit
00042 
00043 using namespace Pokitto;
00044 
00045 uint16_t prevdata=0; // if data does not change, do not adjust LCD bus lines
00046 
00047 #if POK_BOARDREV == 2
00048     pwmout_t backlightpwm;
00049 #endif
00050 
00051 
00052 /**************************************************************************/
00053 /*!
00054     @brief  set up the 16-bit bus
00055 */
00056 /**************************************************************************/
00057 
00058 static inline void setup_data_16(uint16_t data)
00059 {
00060     uint32_t p2=0;
00061 
00062     if (data != prevdata) {
00063 
00064     prevdata=data;
00065 
00066     /** D0...D16 = P2_3 ... P2_18 **/
00067     p2 = data << 3;
00068 
00069     //__disable_irq();    // Disable Interrupts
00070     SET_MASK_P2;
00071     LPC_GPIO_PORT->MPIN[2] = p2; // write bits to port
00072     CLR_MASK_P2;
00073     //__enable_irq();     // Enable Interrupts
00074     }
00075 }
00076 
00077 
00078 /**************************************************************************/
00079 /*!
00080     @brief  Write a command to the lcd, 16-bit bus
00081 */
00082 /**************************************************************************/
00083 inline void write_command_16(uint16_t data)
00084 {
00085    CLR_CS; // select lcd
00086    CLR_CD; // clear CD = command
00087    SET_RD; // RD high, do not read
00088    setup_data_16(data); // function that inputs the data into the relevant bus lines
00089    CLR_WR;  // WR low
00090    SET_WR;  // WR low, then high = write strobe
00091    SET_CS; // de-select lcd
00092 }
00093 
00094 /**************************************************************************/
00095 /*!
00096     @brief  Write data to the lcd, 16-bit bus
00097 */
00098 /**************************************************************************/
00099 inline void write_data_16(uint16_t data)
00100 {
00101    CLR_CS;
00102    SET_CD;
00103    SET_RD;
00104    setup_data_16(data);
00105    CLR_WR;
00106    SET_WR;
00107    SET_CS;
00108 }
00109 
00110 /**************************************************************************/
00111 /*!
00112     @brief  Point to a (x,y) location in the LCD DRAM
00113 */
00114 /**************************************************************************/
00115 static inline void setDRAMptr(uint8_t xptr, uint8_t yoffset)
00116 {
00117     write_command(0x20);  // Vertical DRAM Address
00118     write_data(yoffset);
00119     write_command(0x21);  // Horizontal DRAM Address
00120     write_data(xptr);  //
00121     write_command(0x22); // write data to DRAM
00122     CLR_CS_SET_CD_RD_WR;
00123 }
00124 
00125 void Pokitto::initBacklight() {
00126     #if POK_BOARDREV == 2
00127     pwmout_init(&backlightpwm,POK_BACKLIGHT_PIN);
00128     pwmout_period_us(&backlightpwm,5);
00129     pwmout_write(&backlightpwm,POK_BACKLIGHT_INITIALVALUE);
00130     #endif
00131 }
00132 
00133 void Pokitto::setBacklight(float value) {
00134     if (value>0.999f) value = 0.999f;
00135     pwmout_write(&backlightpwm,value);
00136 }
00137 
00138 void Pokitto::lcdInit() {
00139    initBacklight();
00140 
00141    SET_RESET;
00142    wait_ms(10);
00143    CLR_RESET;
00144    wait_ms(10);
00145    SET_RESET;
00146    wait_ms(10);
00147   //************* Start Initial Sequence **********//
00148     write_command(0x01); // driver output control, this also affects direction
00149     write_data(0x11C); // originally: 0x11C 100011100 SS,NL4,NL3,NL2
00150                         // NL4...0 is the number of scan lines to drive the screen !!!
00151                         // so 11100 is 1c = 220 lines, correct
00152                         // test 1: 0x1C 11100 SS=0,NL4,NL3,NL2 -> no effect
00153                         // test 2: 0x31C 1100011100 GS=1,SS=1,NL4,NL3,NL2 -> no effect
00154                         // test 3: 0x51C 10100011100 SM=1,GS=0,SS=1,NL4,NL3,NL2 -> no effect
00155                         // test 4: 0x71C SM=1,GS=1,SS=1,NL4,NL3,NL2
00156                         // test 5: 0x
00157                         // seems to have no effect... is this perhaps only for RGB mode ?
00158 
00159     write_command(0x02); // LCD driving control
00160     write_data(0x0100); // INV = 1
00161 
00162     write_command(0x03); // Entry mode... lets try if this affects the direction
00163     write_data(0x1030); // originally 0x1030 1000000110000 BGR,ID1,ID0
00164                         // test 1: 0x1038 1000000111000 BGR,ID1,ID0,AM=1 ->drawing DRAM horizontally
00165                         // test 4: am=1, id0=0, id1=0, 1000000001000,0x1008 -> same as above, but flipped on long
00166                         // test 2: am=0, id0=0, 1000000100000, 0x1020 -> flipped on long axis
00167                         // test 3: am=0, id1=0, 1000000010000, 0x1010 -> picture flowed over back to screen
00168 
00169 
00170     write_command(0x08); // Display control 2
00171     write_data(0x0808); // 100000001000 FP2,BP2
00172 
00173     write_command(0x0C); // RGB display interface
00174     write_data(0x0000); // all off
00175 
00176     write_command(0x0F); // Frame marker position
00177     write_data(0x0001); // OSC_EN
00178 
00179     write_command(0x20);  // Horizontal DRAM Address
00180     write_data(0x0000);  // 0
00181 
00182     write_command(0x21);  // Vertical DRAM Address
00183     write_data(0x0000); // 0
00184 
00185  //*************Power On sequence ****************//
00186     write_command(0x10);
00187     write_data(0x0000);
00188 
00189     write_command(0x11);
00190     write_data(0x1000);
00191     wait_ms(10);
00192 //------------------------ Set GRAM area --------------------------------//
00193     write_command(0x30); // Gate scan position
00194     write_data(0x0000); // if GS=0, 00h=G1, else 00h=G220
00195 
00196     write_command(0x31); // Vertical scroll control
00197     write_data(0x00DB); // scroll start line 11011011 = 219
00198 
00199     write_command(0x32); // Vertical scroll control
00200     write_data(0x0000); // scroll end line 0
00201 
00202     write_command(0x33); // Vertical scroll control
00203     write_data(0x0000); // 0=vertical scroll disabled
00204 
00205     write_command(0x34); // Partial screen driving control
00206     write_data(0x00DB); // db = full screen (end)
00207 
00208     write_command(0x35); // partial screen
00209     write_data(0x0000); // 0 = start
00210 
00211     write_command(0x36); // Horizontal and vertical RAM position
00212     write_data(0x00AF); //end address 175
00213 
00214     write_command(0x37);
00215     write_data(0x0000); // start address 0
00216 
00217     write_command(0x38);
00218     write_data(0x00DB); //end address 219
00219 
00220     write_command(0x39); // start address 0
00221     write_data(0x0000);
00222     wait_ms(10);
00223     write_command(0xff); // start gamma register control
00224     write_data(0x0003);
00225 
00226 // ----------- Adjust the Gamma  Curve ----------//
00227     write_command(0x50);
00228     write_data(0x0203);
00229 
00230     write_command(0x051);
00231     write_data(0x0A09);
00232 
00233     write_command(0x52);
00234     write_data(0x0005);
00235 
00236     write_command(0x53);
00237     write_data(0x1021);
00238 
00239     write_command(0x54);
00240     write_data(0x0602);
00241 
00242     write_command(0x55);
00243     write_data(0x0003);
00244 
00245     write_command(0x56);
00246     write_data(0x0703);
00247 
00248     write_command(0x57);
00249     write_data(0x0507);
00250 
00251     write_command(0x58);
00252     write_data(0x1021);
00253 
00254     write_command(0x59);
00255     write_data(0x0703);
00256 
00257     write_command(0xB0);
00258     write_data(0x2501);
00259 
00260     write_command(0xFF);
00261     write_data(0x0000);
00262 
00263     write_command(0x07);
00264     write_data(0x1017);
00265     wait_ms(200);
00266     write_command(0x22);
00267 
00268     lcdClear();
00269 }
00270 
00271 void Pokitto::lcdSleep(void){
00272    write_command(0xFF);
00273    write_data(0x0000);
00274 
00275    write_command(0x07);
00276    write_data(0x0000);
00277    wait_ms(50);
00278    write_command(0x10);// Enter Standby mode
00279    write_data(0x0003);
00280    wait_ms(200);
00281 
00282 }
00283 
00284 void Pokitto::lcdWakeUp (void){
00285 
00286    wait_ms(200);
00287    write_command(0xFF);
00288    write_data(0x0000);
00289 
00290    write_command(0x10);// Exit Sleep/ Standby mode
00291    write_data(0x0000);
00292    wait_ms(50);
00293    write_command(0x07);
00294    write_data(0x0117);
00295    wait_ms(200);
00296   }
00297 
00298 void Pokitto::lcdFillSurface(uint16_t c) {
00299     uint32_t i;
00300     write_command(0x20);  // Horizontal DRAM Address
00301     write_data(0x0000);  // 0
00302     write_command(0x21);  // Vertical DRAM Address
00303     write_data(0);
00304     write_command(0x22); // write data to DRAM
00305     setup_data_16(c);
00306     CLR_CS_SET_CD_RD_WR;
00307     for(i=0;i<220*176;i++)
00308     {
00309     CLR_WR;
00310     SET_WR;
00311     }
00312 }
00313 
00314 void Pokitto::lcdClear() {
00315     uint32_t i;
00316     write_command(0x20);  // Horizontal DRAM Address
00317     write_data(0x0000);  // 0
00318     write_command(0x21);  // Vertical DRAM Address
00319     write_data(0);
00320     write_command(0x22); // write data to DRAM
00321     setup_data_16(0x0000);
00322     CLR_CS_SET_CD_RD_WR;
00323     for(i=0;i<220*176;i++)
00324     {
00325         CLR_WR;
00326         SET_WR;
00327     }
00328 }
00329 
00330 void Pokitto::setWindow(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
00331     write_command(0x37); write_data(x1);
00332     write_command(0x36); write_data(x2);
00333     write_command(0x39); write_data(y1);
00334     write_command(0x38); write_data(y2);
00335     write_command(0x20); write_data(x1);
00336     write_command(0x21); write_data(y1);
00337 }
00338 
00339 void Pokitto::lcdTile(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t* gfx){
00340     int width=x1-x0;
00341     int height=y1-y0;
00342     if (x0 > POK_LCD_W) return;
00343     if (y0 > POK_LCD_H) return;
00344     if (x0 < 0) x0=0;
00345     if (y0 < 0) y0=0;
00346 
00347     setWindow(y0, x0, y1-1, x1-1);
00348     write_command(0x22);
00349 
00350     for (int x=0; x<=width*height-1;x++) {
00351         write_data(gfx[x]);
00352     }
00353     setWindow(0, 0, 175, 219);
00354 }
00355 
00356 void Pokitto::lcdPixel(int16_t x, int16_t y, uint16_t color) {
00357     if ((x < 0) || (x >= POK_LCD_W) || (y < 0) || (y >= POK_LCD_H))
00358     return;
00359     write_command(0x20); write_data(y);
00360     write_command(0x21); write_data(x);
00361     write_command(0x22); write_data(color);
00362 
00363 }
00364 
00365 void Pokitto::lcdRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
00366     if(x1<=x0)x1=x0+1;
00367     if(y1<=y0)y1=y0+1;
00368     setWindow(y0, x0, y1-1, x1-1);
00369     write_command(0x22);
00370     int width=x1-x0;
00371     int height=y1-y0;
00372     int i=width*height;
00373     while (i--) {
00374         write_data(color);
00375     }
00376 }
00377 
00378 void Pokitto::lcdRefreshRegionMode1(int16_t x0, int16_t y0, int16_t x1, int16_t y1,  uint8_t * scrbuf, uint16_t * paletteptr){
00379     if(x1<=x0)x1=x0+1;
00380     if(y1<=y0)y1=y0+1;
00381     setWindow(y0, x0, y1-1, x1-1);
00382     write_command(0x22);
00383     uint8_t pix;
00384     uint8_t quartWide=(x1-x0)/4;
00385     uint8_t pic;
00386 
00387     x0/=4;
00388 
00389     for(int y=y0; y<y1; y++){
00390         for(int x=x0; x<x0+quartWide; x++){
00391             pic = scrbuf[x+55*y];
00392             pix = (pic >> 6)&3; write_data(paletteptr[pix]);
00393             pix = (pic >> 4)&3; write_data(paletteptr[pix]);
00394             pix = (pic >> 2)&3; write_data(paletteptr[pix]);
00395             pix = pic &3;       write_data(paletteptr[pix]);
00396         }
00397     }
00398 }
00399 
00400 void Pokitto::lcdRefreshMode1(uint8_t * scrbuf, uint16_t* paletteptr) {
00401 uint16_t x,y,xptr;
00402 uint16_t scanline[4][176]; // read 4 half-nibbles = 4 pixels at a time
00403 uint8_t *d, yoffset=0;
00404 
00405 xptr = 0;
00406 setDRAMptr(xptr,yoffset);
00407 
00408 
00409 for(x=0;x<220;x+=4)
00410   {
00411     d = scrbuf+(x>>2);// point to beginning of line in data
00412     /** find colours in one scanline **/
00413     uint8_t s=0;
00414     for(y=0;y<176;y++)
00415     {
00416     uint8_t tdata = *d;
00417     uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
00418     uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
00419     uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
00420     uint8_t t = tdata & 0x03;// highest half-nibble
00421 
00422     /** put nibble values in the scanlines **/
00423     scanline[0][s] = paletteptr[t];
00424     scanline[1][s] = paletteptr[t2];
00425     scanline[2][s] = paletteptr[t3];
00426     scanline[3][s++] = paletteptr[t4];
00427 
00428     d+=220/4; // jump to read byte directly below in screenbuffer
00429     }
00430     s=0;
00431     /** draw scanlines **/
00432     for (s=0;s<176;) {
00433         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00434         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00435         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00436         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00437         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00438         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00439         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00440         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00441     }
00442     for (s=0;s<176;) {
00443         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00444         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00445         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00446         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00447         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00448         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00449         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00450         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00451     }
00452     for (s=0;s<176;) {
00453         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
00454         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
00455         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
00456         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
00457         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
00458         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
00459         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
00460         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
00461     }
00462     for (s=0;s<176;) {
00463         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
00464         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
00465         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
00466         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
00467         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
00468         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
00469         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
00470         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
00471     }
00472   }
00473 }
00474 
00475 void Pokitto::lcdRefreshMode2(uint8_t * scrbuf, uint16_t* paletteptr) {
00476 uint16_t x,y;
00477 uint16_t scanline[2][88]; // read two nibbles = pixels at a time
00478 uint8_t *d;
00479 
00480 write_command(0x20);  // Horizontal DRAM Address
00481 write_data(0);  // 0
00482 write_command(0x21);  // Vertical DRAM Address
00483 write_data(0);
00484 write_command(0x22); // write data to DRAM
00485 CLR_CS_SET_CD_RD_WR;
00486 
00487 for(x=0;x<110;x+=2)
00488   {
00489     d = scrbuf+(x>>1);// point to beginning of line in data
00490     /** find colours in one scanline **/
00491     uint8_t s=0;
00492     for(y=0;y<88;y++)
00493     {
00494     uint8_t t = *d >> 4; // higher nibble
00495     uint8_t t2 = *d & 0xF; // lower nibble
00496     /** higher nibble = left pixel in pixel pair **/
00497     scanline[0][s] = paletteptr[t];
00498     scanline[1][s++] = paletteptr[t2];
00499     /** testing only **/
00500     //scanline[0][s] = 0xFFFF*(s&1);
00501     //scanline[1][s] = 0xFFFF*(!(s&1));
00502     //s++;
00503     /** until here **/
00504     d+=110/2; // jump to read byte directly below in screenbuffer
00505     }
00506     s=0;
00507     /** draw scanlines **/
00508     /** leftmost scanline twice**/
00509 
00510     for (s=0;s<88;) {
00511         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00512         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00513         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00514         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00515         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00516         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00517         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00518         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00519     }
00520 
00521     for (s=0;s<88;) {
00522         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00523         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00524         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00525         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00526         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00527         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00528         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00529         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00530     }
00531     /** rightmost scanline twice**/
00532     //setDRAMptr(xptr++,yoffset);
00533     for (s=0;s<88;) {
00534         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00535         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00536         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00537         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00538         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00539         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00540         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00541         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00542     }
00543 
00544     for (s=0;s<88;) {
00545         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00546         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00547         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00548         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00549         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00550         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00551         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00552         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00553     }
00554   }
00555 }
00556 
00557 void Pokitto::lcdRefreshMode3(uint8_t * scrbuf, uint16_t* paletteptr) {
00558 uint16_t x,y;
00559 uint16_t scanline[2][176]; // read two nibbles = pixels at a time
00560 uint8_t *d;
00561 
00562 write_command(0x20);  // Horizontal DRAM Address
00563 write_data(0);  // 0
00564 write_command(0x21);  // Vertical DRAM Address
00565 write_data(0);
00566 write_command(0x22); // write data to DRAM
00567 CLR_CS_SET_CD_RD_WR;
00568 
00569 for(x=0;x<220;x+=2)
00570   {
00571     d = scrbuf+(x>>1);// point to beginning of line in data
00572     /** find colours in one scanline **/
00573     uint8_t s=0;
00574     for(y=0;y<176;y++)
00575     {
00576     uint8_t t = *d >> 4; // higher nibble
00577     uint8_t t2 = *d & 0xF; // lower nibble
00578     /** higher nibble = left pixel in pixel pair **/
00579     scanline[0][s] = paletteptr[t];
00580     scanline[1][s++] = paletteptr[t2];
00581     /** testing only **/
00582     //scanline[0][s] = 0xFFFF*(s&1);
00583     //scanline[1][s] = 0xFFFF*(!(s&1));
00584     //s++;
00585     /** until here **/
00586     d+=220/2; // jump to read byte directly below in screenbuffer
00587     }
00588     s=0;
00589     /** draw scanlines **/
00590     /** leftmost scanline**/
00591 
00592     for (s=0;s<176;) {
00593         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00594         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00595         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00596         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00597         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00598         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00599         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00600         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
00601     }
00602 
00603     /** rightmost scanline**/
00604     //setDRAMptr(xptr++,yoffset);
00605     for (s=0;s<176;) {
00606         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00607         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00608         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00609         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00610         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00611         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00612         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00613         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
00614     }
00615   }
00616 }
00617 
00618 void Pokitto::lcdRefreshGB(uint8_t * scrbuf, uint16_t* paletteptr) {
00619 uint16_t x,y;
00620 uint16_t scanline[48];
00621 uint8_t * d;
00622 
00623 #if POK_STRETCH
00624 //uint16_t xptr = 8;
00625 #else
00626 //xptr = 26;
00627 #endif
00628 
00629 write_command(0x20);  // Horizontal DRAM Address
00630 write_data(0);  // 0
00631 write_command(0x21);  // Vertical DRAM Address
00632 write_data(0);
00633 write_command(0x22); // write data to DRAM
00634 CLR_CS_SET_CD_RD_WR;
00635 
00636 /** draw border **/
00637     for (int s=0;s<5*176;) {
00638             setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;s++;
00639     }
00640 
00641 for(x=0;x<84;x++)
00642   {
00643 
00644         d = scrbuf + x;// point to beginning of line in data
00645 
00646         /** find colours in one scanline **/
00647         uint8_t s=0;
00648         for(y=0;y<6;y++)
00649             {
00650             uint8_t t = *d;
00651             #if POK_COLORDEPTH > 1
00652             uint8_t t2 = *(d+504);
00653             #endif
00654             #if POK_COLORDEPTH > 2
00655             uint8_t t3 = *(d+504+504);
00656             #endif
00657             #if POK_COLORDEPTH > 3
00658             uint8_t t4 = *(d+504+504+504);
00659             #endif
00660             uint8_t paletteindex = 0;
00661 
00662             /** bit 1 **/
00663             #if POK_COLORDEPTH == 1
00664             paletteindex = (t & 0x1);
00665             #elif POK_COLORDEPTH == 2
00666             paletteindex = ((t & 0x1)) | ((t2 & 0x01)<<1);
00667             #elif POK_COLORDEPTH == 3
00668             paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2);
00669             #elif POK_COLORDEPTH == 4
00670             paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2) | ((t4 & 0x1)<<3);
00671             #endif
00672             scanline[s++] = paletteptr[paletteindex];
00673 
00674             /** bit 2 **/
00675             #if POK_COLORDEPTH == 1
00676             paletteindex = (t & 0x2)>>1;
00677             #elif POK_COLORDEPTH == 2
00678             paletteindex = ((t & 0x2)>>1) | ((t2 & 0x02));
00679             #elif POK_COLORDEPTH == 3
00680             paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1);
00681             #elif POK_COLORDEPTH == 4
00682             paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1) | ((t4 & 0x2)<<2);
00683             #endif
00684             scanline[s++] = paletteptr[paletteindex];
00685 
00686             /** bit 3 **/
00687             #if POK_COLORDEPTH == 1
00688             paletteindex = (t & 0x4)>>2;
00689             #elif POK_COLORDEPTH == 2
00690             paletteindex = ((t & 4)>>2) | ((t2 & 0x04)>>1);
00691             #elif POK_COLORDEPTH == 3
00692             paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4);
00693             #elif POK_COLORDEPTH == 4
00694             paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4) | ((t4 & 0x4)<<1);
00695             #endif
00696             scanline[s++] = paletteptr[paletteindex];
00697 
00698             /** bit 4 **/
00699             #if POK_COLORDEPTH == 1
00700             paletteindex = (t & 0x8)>>3;
00701             #elif POK_COLORDEPTH == 2
00702             paletteindex = ((t & 0x8)>>3) | ((t2 & 0x08)>>2);
00703             #elif POK_COLORDEPTH == 3
00704             paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1);
00705             #elif POK_COLORDEPTH == 4
00706             paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1) | (t4 & 0x8);
00707             #endif
00708             scanline[s++] = paletteptr[paletteindex];
00709 
00710             /** bit 5 **/
00711             #if POK_COLORDEPTH == 1
00712             paletteindex = (t & 0x10)>>4;
00713             #elif POK_COLORDEPTH == 2
00714             paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3);
00715             #elif POK_COLORDEPTH == 3
00716             paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2);
00717             #elif POK_COLORDEPTH == 4
00718             paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2) | ((t4 & 0x10)>>1);
00719             #endif
00720             scanline[s++] = paletteptr[paletteindex];
00721 
00722             /** bit 6 **/
00723             #if POK_COLORDEPTH == 1
00724             paletteindex = (t & 0x20)>>5;
00725             #elif POK_COLORDEPTH == 2
00726             paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4);
00727             #elif POK_COLORDEPTH == 3
00728             paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3);
00729             #elif POK_COLORDEPTH == 4
00730             paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3) | ((t4 & 0x20)>>2);
00731             #endif
00732             scanline[s++] = paletteptr[paletteindex];
00733 
00734             /** bit 7 **/
00735             #if POK_COLORDEPTH == 1
00736             paletteindex = (t & 0x40)>>6;
00737             #elif POK_COLORDEPTH == 2
00738             paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5);
00739             #elif POK_COLORDEPTH == 3
00740             paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) ;
00741             #elif POK_COLORDEPTH == 4
00742             paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) | ((t4 & 0x40)>>3);
00743             #endif
00744             scanline[s++] = paletteptr[paletteindex];
00745 
00746             /** bit 8 **/
00747             #if POK_COLORDEPTH == 1
00748             paletteindex = (t & 0x80)>>7;
00749             #elif POK_COLORDEPTH == 2
00750             paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6);
00751             #elif POK_COLORDEPTH == 3
00752             paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5);
00753             #elif POK_COLORDEPTH == 4
00754             paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5) | ((t4 & 0x80)>>4);
00755             #endif
00756             scanline[s++] = paletteptr[paletteindex];
00757 
00758             d+=84; // jump to byte directly below
00759             }
00760 
00761 
00762         /*write_command(0x20);  // Horizontal DRAM Address
00763         write_data(0x10);  // 0
00764         write_command(0x21);  // Vertical DRAM Address
00765         write_data(xptr++);
00766         write_command(0x22); // write data to DRAM
00767         CLR_CS_SET_CD_RD_WR;*/
00768         /** draw border **/
00769         setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;        CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00770 
00771         s=0;
00772 
00773         /** draw scanlines **/
00774         for (s=0;s<48;) {
00775             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00776             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00777             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00778             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00779             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00780             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00781             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00782             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00783         }
00784         /** draw border **/
00785         setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;        CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00786 
00787 
00788         /*write_command(0x20);  // Horizontal DRAM Address
00789         write_data(0x10);  // 0
00790         write_command(0x21);  // Vertical DRAM Address
00791         write_data(xptr++);
00792         write_command(0x22); // write data to DRAM
00793         CLR_CS_SET_CD_RD_WR;*/
00794         /** draw border **/
00795         setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;        CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00796 
00797         for (s=0;s<48;) {
00798             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00799             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00800             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00801             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00802             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00803             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00804             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00805             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00806         }
00807 
00808         /** draw border **/
00809         setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;        CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00810 
00811 
00812         #if POK_STRETCH
00813         //if (x>16 && x<68)
00814         if (x&2)// && x&2)
00815         {
00816             /*write_command(0x20);  // Horizontal DRAM Address
00817             write_data(0x10);  // 0
00818             write_command(0x21);  // Vertical DRAM Address
00819             write_data(xptr++);
00820             write_command(0x22); // write data to DRAM
00821             CLR_CS_SET_CD_RD_WR;*/
00822             /** draw border **/
00823         setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;        CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00824 
00825 
00826             for (s=0;s<48;) {
00827             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00828             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00829             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00830             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00831             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00832             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00833             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00834             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00835             }
00836 
00837             /** draw border **/
00838         setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;        CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
00839 
00840         }
00841         #endif
00842     }
00843     /** draw border **/
00844     for (int s=0;s<5*176;) {
00845             setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;s++;
00846     }
00847 }
00848 
00849 
00850 void Pokitto::lcdRefreshAB(uint8_t * scrbuf, uint16_t* paletteptr) {
00851 uint16_t x,y;
00852 uint16_t scanline[64];
00853 uint8_t *d;
00854 //lcdClear();
00855 #if POK_STRETCH
00856 uint16_t xptr = 14;
00857 uint8_t yoffset = 24;
00858 #else
00859 xptr = 0; //was 26
00860 #endif
00861 
00862 for(x=0;x<128;x++)
00863   {
00864     write_command(0x20);  // Horizontal DRAM Address
00865     write_data(yoffset);  // 0
00866     write_command(0x21);  // Vertical DRAM Address
00867     write_data(xptr++);
00868     write_command(0x22); // write data to DRAM
00869     CLR_CS_SET_CD_RD_WR;
00870     //setDRAMptr(xptr++,yoffset);
00871 
00872         d = scrbuf + x;// point to beginning of line in data
00873 
00874         /** find colours in one scanline **/
00875         uint8_t s=0;
00876         for(y=0;y<8;y++)
00877             {
00878             uint8_t t = *d;
00879             #if POK_COLORDEPTH > 1
00880             uint8_t t2 = *(d+AB_JUMP);
00881             #endif // POK_COLORDEPTH
00882             #if POK_COLORDEPTH > 2
00883             uint8_t t3 = *(d+AB_JUMP+AB_JUMP);
00884             #endif // POK_COLORDEPTH
00885             #if POK_COLORDEPTH > 3
00886             uint8_t t4 = *(d+AB_JUMP+AB_JUMP+AB_JUMP);
00887             #endif // POK_COLORDEPTH
00888             uint8_t paletteindex = 0;
00889 
00890             /** bit 1 **/
00891             #if POK_COLORDEPTH == 1
00892             paletteindex = (t & 0x1);
00893             #elif POK_COLORDEPTH == 2
00894             paletteindex = ((t & 0x1)) | ((t2 & 0x01)<<1);
00895             #elif POK_COLORDEPTH == 3
00896             paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2);
00897             #elif POK_COLORDEPTH == 4
00898             paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2) | ((t4 & 0x1)<<3);
00899             #endif
00900             scanline[s++] = paletteptr[paletteindex];
00901 
00902             /** bit 2 **/
00903             #if POK_COLORDEPTH == 1
00904             paletteindex = (t & 0x2)>>1;
00905             #elif POK_COLORDEPTH == 2
00906             paletteindex = ((t & 0x2)>>1) | ((t2 & 0x02));
00907             #elif POK_COLORDEPTH == 3
00908             paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1);
00909             #elif POK_COLORDEPTH == 4
00910             paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1) | ((t4 & 0x2)<<2);
00911             #endif
00912             scanline[s++] = paletteptr[paletteindex];
00913 
00914             /** bit 3 **/
00915             #if POK_COLORDEPTH == 1
00916             paletteindex = (t & 0x4)>>2;
00917             #elif POK_COLORDEPTH == 2
00918             paletteindex = ((t & 4)>>2) | ((t2 & 0x04)>>1);
00919             #elif POK_COLORDEPTH == 3
00920             paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4);
00921             #elif POK_COLORDEPTH == 4
00922             paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4) | ((t4 & 0x4)<<1);
00923             #endif
00924             scanline[s++] = paletteptr[paletteindex];
00925 
00926             /** bit 4 **/
00927             #if POK_COLORDEPTH == 1
00928             paletteindex = (t & 0x8)>>3;
00929             #elif POK_COLORDEPTH == 2
00930             paletteindex = ((t & 0x8)>>3) | ((t2 & 0x08)>>2);
00931             #elif POK_COLORDEPTH == 3
00932             paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1);
00933             #elif POK_COLORDEPTH == 4
00934             paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1) | (t4 & 0x8);
00935             #endif
00936             scanline[s++] = paletteptr[paletteindex];
00937 
00938             /** bit 5 **/
00939             #if POK_COLORDEPTH == 1
00940             paletteindex = (t & 0x10)>>4;
00941             #elif POK_COLORDEPTH == 2
00942             paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3);
00943             #elif POK_COLORDEPTH == 3
00944             paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2);
00945             #elif POK_COLORDEPTH == 4
00946             paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2) | ((t4 & 0x10)>>1);
00947             #endif
00948             scanline[s++] = paletteptr[paletteindex];
00949 
00950             /** bit 6 **/
00951             #if POK_COLORDEPTH == 1
00952             paletteindex = (t & 0x20)>>5;
00953             #elif POK_COLORDEPTH == 2
00954             paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4);
00955             #elif POK_COLORDEPTH == 3
00956             paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3);
00957             #elif POK_COLORDEPTH == 4
00958             paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3) | ((t4 & 0x20)>>2);
00959             #endif
00960             scanline[s++] = paletteptr[paletteindex];
00961 
00962             /** bit 7 **/
00963             #if POK_COLORDEPTH == 1
00964             paletteindex = (t & 0x40)>>6;
00965             #elif POK_COLORDEPTH == 2
00966             paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5);
00967             #elif POK_COLORDEPTH == 3
00968             paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) ;
00969             #elif POK_COLORDEPTH == 4
00970             paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) | ((t4 & 0x40)>>3);
00971             #endif
00972             scanline[s++] = paletteptr[paletteindex];
00973 
00974             /** bit 8 **/
00975             #if POK_COLORDEPTH == 1
00976             paletteindex = (t & 0x80)>>7;
00977             #elif POK_COLORDEPTH == 2
00978             paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6);
00979             #elif POK_COLORDEPTH == 3
00980             paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5);
00981             #elif POK_COLORDEPTH == 4
00982             paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5) | ((t4 & 0x80)>>4);
00983             #endif
00984             scanline[s++] = paletteptr[paletteindex];
00985 
00986             d+=128; // jump to byte directly below
00987             }
00988 
00989         s=0;
00990 
00991         /** draw scanlines **/
00992         for (s=0;s<64;) {
00993             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00994             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00995             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00996             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00997             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00998             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
00999             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01000             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01001         }
01002 
01003         #if POK_STRETCH
01004         if (x&1) {
01005         write_command(0x20);  // Horizontal DRAM Address
01006         write_data(yoffset);  // 0
01007         write_command(0x21);  // Vertical DRAM Address
01008         write_data(xptr++);
01009         write_command(0x22); // write data to DRAM
01010         CLR_CS_SET_CD_RD_WR;
01011         //setDRAMptr(xptr++,yoffset);
01012 
01013         for (s=0;s<64;) {
01014             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01015             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01016             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01017             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01018             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01019             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01020             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01021             setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
01022         }
01023         }
01024         #endif
01025     }
01026 }
01027 
01028 void Pokitto::lcdRefreshModeGBC(uint8_t * scrbuf, uint16_t* paletteptr) {
01029 uint16_t x,y,xptr;
01030 uint16_t scanline[4][144]; // read 4 half-nibbles = 4 pixels at a time
01031 uint8_t *d, yoffset=0;
01032 
01033 xptr = 0;
01034 setDRAMptr(xptr,yoffset);
01035 
01036 
01037 for(x=0;x<160;x+=4)
01038   {
01039     d = scrbuf+(x>>2);// point to beginning of line in data
01040     /** find colours in one scanline **/
01041     uint8_t s=0;
01042     for(y=0;y<144;y++)
01043     {
01044     uint8_t tdata = *d;
01045     uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
01046     uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
01047     uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
01048     uint8_t t = tdata & 0x03;// highest half-nibble
01049 
01050     /** put nibble values in the scanlines **/
01051 
01052     scanline[0][s] = paletteptr[t];
01053     scanline[1][s] = paletteptr[t2];
01054     scanline[2][s] = paletteptr[t3];
01055     scanline[3][s++] = paletteptr[t4];
01056 
01057      d+=160/4; // jump to read byte directly below in screenbuffer
01058     }
01059 
01060     s=0;
01061     /** draw scanlines **/
01062     for (s=0;s<144;) {
01063         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
01064         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
01065         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
01066         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
01067         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
01068         setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
01069     }
01070     setDRAMptr(++xptr,yoffset);
01071     for (s=0;s<144;) {
01072         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
01073         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
01074         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
01075         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
01076         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
01077         setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
01078     }
01079     setDRAMptr(++xptr,yoffset);
01080     for (s=0;s<144;) {
01081         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
01082         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
01083         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
01084         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
01085         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
01086         setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
01087     }
01088     setDRAMptr(++xptr,yoffset);
01089     for (s=0;s<144;) {
01090         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
01091         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
01092         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
01093         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
01094         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
01095         setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
01096     }
01097     setDRAMptr(++xptr,yoffset);
01098   }
01099 }
01100 
01101 
01102 void Pokitto::lcdRefreshT1(uint8_t* tilebuf, uint8_t* tilecolorbuf, uint8_t* tileset, uint16_t* paletteptr) {
01103 #ifdef POK_TILEMODE
01104 uint16_t x,y,data,xptr;
01105 uint16_t scanline[176];
01106 uint8_t yoffset=0, tilebyte, tileindex, tilex=0, tiley=0,xcount;
01107 
01108 
01109 if (!tileset) return;
01110 
01111 #if LCDWIDTH < POK_LCD_W
01112 xptr = (POK_LCD_W-LCDWIDTH)/2;
01113 #else
01114 xptr = 0;
01115 #endif
01116 #if LCDHEIGHT < POK_LCD_H
01117 yoffset = (POK_LCD_H-LCDHEIGHT)/2;
01118 #else
01119 yoffset = 0;
01120 #endif
01121 
01122 for(x=0, xcount=0 ;x<LCDWIDTH;x++,xcount++)  // loop through vertical columns
01123   {
01124     setDRAMptr(xptr++,yoffset); //point to VRAM
01125 
01126         /** find colours in one scanline **/
01127         uint8_t s=0, tiley=0;
01128         //tileindex = tilebuf[tilex*POK_TILES_Y];
01129         if (xcount==POK_TILE_W) {
01130             tilex++;
01131             xcount=0;
01132         }
01133 
01134         for(y=0;y<LCDHEIGHT;)
01135         {
01136             uint8_t tileval = tilebuf[tilex+tiley*POK_TILES_X]; //get tile number
01137             uint16_t index = tileval*POK_TILE_W+xcount;
01138             uint8_t tilebyte = tileset[index]; //get bitmap data
01139             for (uint8_t ycount=0, bitcount=0; ycount<POK_TILE_H; ycount++, y++, bitcount++) {
01140                 if (bitcount==8) {
01141                     bitcount=0;
01142                     index += 176; //jump to byte below in the tileset bitmap
01143                     tilebyte = tileset[index]; //get bitmap data
01144                 }
01145                 //tilebyte = tile[(tileindex>>4)+*POK_TILE_W]; //tilemaps are 16x16
01146                 //uint8_t paletteindex = ((tilebyte>>(bitcount&0x7)) & 0x1);
01147                 if (!tileval) scanline[s++] = COLOR_MAGENTA*((tilebyte>>bitcount)&0x1);//paletteptr[paletteindex];
01148                 else scanline[s++] = paletteptr[((tilebyte>>bitcount)&0x1)*tileval];//paletteptr[paletteindex];
01149             }
01150             tiley++; //move to next tile
01151         }
01152         s=0;
01153 
01154         /** draw scanlines **/
01155         for (s=0;s<LCDHEIGHT;) {
01156             setup_data_16(scanline[s++]);CLR_WR;SET_WR;
01157         }
01158     }
01159     #endif
01160 }
01161 
01162 void Pokitto::blitWord(uint16_t c) {
01163     setup_data_16(c);CLR_WR;SET_WR;
01164 }
01165