Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: YATTT sd_map_test cPong SnowDemo ... more
PokittoLib
Library for programming Pokitto hardware
How to Use
- Import this library to online compiler (see button "import" on the right hand side
- DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
- Change My_settings.h according to your project
- Start coding!
Diff: POKITTO_HW/HWLCD.cpp
- Revision:
- 42:798b5d67b372
- Parent:
- 41:e667167aa9d8
- Child:
- 43:6183b12dd99c
--- a/POKITTO_HW/HWLCD.cpp Wed Apr 25 14:00:49 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1915 +0,0 @@
-/**************************************************************************/
-/*!
- @file HWLCD.cpp
- @author Jonne Valola
-
- @section LICENSE
-
- Software License Agreement (BSD License)
-
- Copyright (c) 2016, Jonne Valola
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holders nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-#include "HWLCD.h" //HWLCD.h" #include "HWLCD.h"
-#include "Pokitto_settings.h"
-
-#ifndef DISABLEAVRMIN
-#define max(a,b) ((a)>(b)?(a):(b))
-#define min(a,b) ((a)<(b)?(a):(b))
-#endif // DISABLEAVRMIN
-
-#define AB_JUMP 1024 // jump one 1-bit Arduboy screen forward to get next color bit
-#define GB_JUMP 504 // jump one 1-bit Gamebuino screen forward to get next color bit
-
-using namespace Pokitto;
-
-uint16_t prevdata=0; // if data does not change, do not adjust LCD bus lines
-
-#if POK_BOARDREV == 2
- pwmout_t backlightpwm;
-#endif
-
-
-/**************************************************************************/
-/*!
- @brief set up the 16-bit bus
-*/
-/**************************************************************************/
-
-static inline void setup_data_16(uint16_t data)
-{
- //uint32_t p2=0;
-
- //if (data != prevdata) {
- //
- //prevdata=data;
-
- /** D0...D16 = P2_3 ... P2_18 **/
- //p2 = data << 3;
-
- //__disable_irq(); // Disable Interrupts
- SET_MASK_P2;
- LPC_GPIO_PORT->MPIN[2] = (data<<3); // write bits to port
- CLR_MASK_P2;
- //__enable_irq(); // Enable Interrupts
- //}
-}
-
-
-/**************************************************************************/
-/*!
- @brief Write a command to the lcd, 16-bit bus
-*/
-/**************************************************************************/
-inline void write_command_16(uint16_t data)
-{
- CLR_CS; // select lcd
- CLR_CD; // clear CD = command
- SET_RD; // RD high, do not read
- setup_data_16(data); // function that inputs the data into the relevant bus lines
- CLR_WR_SLOW; // WR low
- SET_WR; // WR low, then high = write strobe
- SET_CS; // de-select lcd
-}
-
-/**************************************************************************/
-/*!
- @brief Write data to the lcd, 16-bit bus
-*/
-/**************************************************************************/
-inline void write_data_16(uint16_t data)
-{
- CLR_CS;
- SET_CD;
- SET_RD;
- setup_data_16(data);
- CLR_WR;
- SET_WR;
- SET_CS;
-}
-
-/**************************************************************************/
-/*!
- @brief Pump data to the lcd, 16-bit bus, public function
-*/
-/**************************************************************************/
-void Pokitto::pumpDRAMdata(uint16_t* data,uint16_t counter)
-{
- while (counter--) {
- CLR_CS;
- SET_CD;
- SET_RD;
- setup_data_16(*data++);
- CLR_WR;
- SET_WR;
- SET_CS;
- }
-}
-
-
-/**************************************************************************/
-/*!
- @brief Point to a (x,y) location in the LCD DRAM
-*/
-/**************************************************************************/
-static inline void setDRAMptr(uint8_t xptr, uint8_t yoffset)
-{
- write_command(0x20); // Vertical DRAM Address
- write_data(yoffset);
- write_command(0x21); // Horizontal DRAM Address
- write_data(xptr); //
- write_command(0x22); // write data to DRAM
- CLR_CS_SET_CD_RD_WR;
-}
-
-/**************************************************************************/
-/*!
- @brief Point to a (x,y) location in the LCD DRAM, public function
-*/
-/**************************************************************************/
-void Pokitto::setDRAMpoint(uint8_t xptr, uint8_t yoffset)
-{
- write_command(0x20); // Vertical DRAM Address
- write_data(yoffset);
- write_command(0x21); // Horizontal DRAM Address
- write_data(xptr); //
- write_command(0x22); // write data to DRAM
- CLR_CS_SET_CD_RD_WR;
-}
-
-void Pokitto::initBacklight() {
- #if POK_BOARDREV == 2
- pwmout_init(&backlightpwm,POK_BACKLIGHT_PIN);
- pwmout_period_us(&backlightpwm,5);
- pwmout_write(&backlightpwm,POK_BACKLIGHT_INITIALVALUE);
- #endif
-}
-
-void Pokitto::setBacklight(float value) {
- if (value>0.999f) value = 0.999f;
- pwmout_write(&backlightpwm,value);
-}
-
-void Pokitto::lcdInit() {
- initBacklight();
-
- SET_RESET;
- wait_ms(10);
- CLR_RESET;
- wait_ms(10);
- SET_RESET;
- wait_ms(10);
- //************* Start Initial Sequence **********//
- write_command(0x01); // driver output control, this also affects direction
- write_data(0x11C); // originally: 0x11C 100011100 SS,NL4,NL3,NL2
- // NL4...0 is the number of scan lines to drive the screen !!!
- // so 11100 is 1c = 220 lines, correct
- // test 1: 0x1C 11100 SS=0,NL4,NL3,NL2 -> no effect
- // test 2: 0x31C 1100011100 GS=1,SS=1,NL4,NL3,NL2 -> no effect
- // test 3: 0x51C 10100011100 SM=1,GS=0,SS=1,NL4,NL3,NL2 -> no effect
- // test 4: 0x71C SM=1,GS=1,SS=1,NL4,NL3,NL2
- // test 5: 0x
- // seems to have no effect... is this perhaps only for RGB mode ?
-
- write_command(0x02); // LCD driving control
- write_data(0x0100); // INV = 1
-
- write_command(0x03); // Entry mode... lets try if this affects the direction
- write_data(0x1030); // originally 0x1030 1000000110000 BGR,ID1,ID0
- // test 1: 0x1038 1000000111000 BGR,ID1,ID0,AM=1 ->drawing DRAM horizontally
- // test 4: am=1, id0=0, id1=0, 1000000001000,0x1008 -> same as above, but flipped on long
- // test 2: am=0, id0=0, 1000000100000, 0x1020 -> flipped on long axis
- // test 3: am=0, id1=0, 1000000010000, 0x1010 -> picture flowed over back to screen
-
-
- write_command(0x08); // Display control 2
- write_data(0x0808); // 100000001000 FP2,BP2
-
- write_command(0x0C); // RGB display interface
- write_data(0x0000); // all off
-
- write_command(0x0F); // Frame marker position
- write_data(0x0001); // OSC_EN
-
- write_command(0x20); // Horizontal DRAM Address
- write_data(0x0000); // 0
-
- write_command(0x21); // Vertical DRAM Address
- write_data(0x0000); // 0
-
- //*************Power On sequence ****************//
- write_command(0x10);
- write_data(0x0000);
-
- write_command(0x11);
- write_data(0x1000);
- wait_ms(10);
-//------------------------ Set GRAM area --------------------------------//
- write_command(0x30); // Gate scan position
- write_data(0x0000); // if GS=0, 00h=G1, else 00h=G220
-
- write_command(0x31); // Vertical scroll control
- write_data(0x00DB); // scroll start line 11011011 = 219
-
- write_command(0x32); // Vertical scroll control
- write_data(0x0000); // scroll end line 0
-
- write_command(0x33); // Vertical scroll control
- write_data(0x0000); // 0=vertical scroll disabled
-
- write_command(0x34); // Partial screen driving control
- write_data(0x00DB); // db = full screen (end)
-
- write_command(0x35); // partial screen
- write_data(0x0000); // 0 = start
-
- write_command(0x36); // Horizontal and vertical RAM position
- write_data(0x00AF); //end address 175
-
- write_command(0x37);
- write_data(0x0000); // start address 0
-
- write_command(0x38);
- write_data(0x00DB); //end address 219
-
- write_command(0x39); // start address 0
- write_data(0x0000);
- wait_ms(10);
- write_command(0xff); // start gamma register control
- write_data(0x0003);
-
-// ----------- Adjust the Gamma Curve ----------//
- write_command(0x50);
- write_data(0x0203);
-
- write_command(0x051);
- write_data(0x0A09);
-
- write_command(0x52);
- write_data(0x0005);
-
- write_command(0x53);
- write_data(0x1021);
-
- write_command(0x54);
- write_data(0x0602);
-
- write_command(0x55);
- write_data(0x0003);
-
- write_command(0x56);
- write_data(0x0703);
-
- write_command(0x57);
- write_data(0x0507);
-
- write_command(0x58);
- write_data(0x1021);
-
- write_command(0x59);
- write_data(0x0703);
-
- write_command(0xB0);
- write_data(0x2501);
-
- write_command(0xFF);
- write_data(0x0000);
-
- write_command(0x07);
- write_data(0x1017);
- wait_ms(200);
- write_command(0x22);
-
- lcdClear();
-}
-
-void Pokitto::lcdSleep(void){
- write_command(0xFF);
- write_data(0x0000);
-
- write_command(0x07);
- write_data(0x0000);
- wait_ms(50);
- write_command(0x10);// Enter Standby mode
- write_data(0x0003);
- wait_ms(200);
-
-}
-
-void Pokitto::lcdWakeUp (void){
-
- wait_ms(200);
- write_command(0xFF);
- write_data(0x0000);
-
- write_command(0x10);// Exit Sleep/ Standby mode
- write_data(0x0000);
- wait_ms(50);
- write_command(0x07);
- write_data(0x0117);
- wait_ms(200);
- }
-
-void Pokitto::lcdFillSurface(uint16_t c) {
- uint32_t i;
- write_command(0x20); // Horizontal DRAM Address
- write_data(0x0000); // 0
- write_command(0x21); // Vertical DRAM Address
- write_data(0);
- write_command(0x22); // write data to DRAM
- setup_data_16(c);
- CLR_CS_SET_CD_RD_WR;
- for(i=0;i<220*176;i++)
- {
- CLR_WR;
- SET_WR;
- }
-}
-
-void Pokitto::lcdClear() {
- uint32_t i;
- write_command(0x20); // Horizontal DRAM Address
- write_data(0x0000); // 0
- write_command(0x21); // Vertical DRAM Address
- write_data(0);
- write_command(0x22); // write data to DRAM
- setup_data_16(0x0000);
- CLR_CS_SET_CD_RD_WR;
- for(i=0;i<220*176;i++)
- {
- CLR_WR;
- SET_WR;
- }
-}
-
-void Pokitto::lcdPixel(int16_t x, int16_t y, uint16_t color) {
- if ((x < 0) || (x >= POK_LCD_W) || (y < 0) || (y >= POK_LCD_H))
- return;
- write_command(0x20); // Horizontal DRAM Address
- write_data(y); // 0
- write_command(0x21); // Vertical DRAM Address
- write_data(x);
- write_command(0x22); // write data to DRAM
- CLR_CS_SET_CD_RD_WR;
- setup_data_16(color);
- CLR_WR;SET_WR;
-}
-
-void Pokitto::setWindow(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
- write_command(0x37); write_data(x1);
- write_command(0x36); write_data(x2);
- write_command(0x39); write_data(y1);
- write_command(0x38); write_data(y2);
- write_command(0x20); write_data(x1);
- write_command(0x21); write_data(y1);
-}
-
-void Pokitto::lcdTile(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t* gfx){
- int width=x1-x0;
- int height=y1-y0;
- if (x0 > POK_LCD_W) return;
- if (y0 > POK_LCD_H) return;
- if (x0 < 0) x0=0;
- if (y0 < 0) y0=0;
-
- setWindow(y0, x0, y1-1, x1-1);
- write_command(0x22);
-
- for (int x=0; x<=width*height-1;x++) {
- write_data(gfx[x]);
- }
- setWindow(0, 0, 175, 219);
-}
-
-
-void Pokitto::lcdRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
- int16_t temp;
- if (x0>x1) {temp=x0;x0=x1;x1=temp;}
- if (y0>y1) {temp=y0;y0=y1;y1=temp;}
- if (x0 > POK_LCD_W) return;
- if (y0 > POK_LCD_H) return;
- if (x1 > POK_LCD_W) x1=POK_LCD_W;
- if (y1 > POK_LCD_H) y1=POK_LCD_W;
- if (x0 < 0) x0=0;
- if (y0 < 0) y0=0;
-
- int16_t x,y;
- for (x=x0; x<=x1;x++) {
- write_command(0x20); // Horizontal DRAM Address (=y on pokitto screen)
- write_data(y0);
- write_command(0x21); // Vertical DRAM Address (=x on pokitto screen)
- write_data(x);
- write_command(0x22); // write data to DRAM
-
- CLR_CS_SET_CD_RD_WR; // go to vram write mode
-
-
- for (y=y0; y<y1;y++) {
- setup_data_16(color); // setup the data (flat color = no change between pixels)
- CLR_WR;SET_WR; //CLR_WR;SET_WR;//toggle writeline, pokitto screen writes a column up to down
- }
- }
-}
-
-/***
- * Update the screen buffer of 220x176 pixels, 4 colors to LCD.
- *
- * The update rect is used for drawing only part of the screen buffer to LCD. Because of speed optimizations, the
- * x, y, and width of the update rect must be dividable by 4 pixels, and the height must be dividable by 8 pixels.
- * Note: The update rect is currently used for 220x176, 4 colors, screen mode only.
- * @param scrbuf The screen buffer.
- * @param updRectX The update rect.
- * @param updRectY The update rect.
- * @param updRectW The update rect.
- * @param updRectH The update rect.
- * @param paletteptr The screen palette.
-*/
-void Pokitto::lcdRefreshMode1(uint8_t * scrbuf, uint8_t updRectX, uint8_t updRectY, uint8_t updRectW, uint8_t updRectH, uint16_t* paletteptr) {
-
- uint16_t x,y,xptr;
- uint16_t scanline[4][176]; // read 4 half-nibbles = 4 pixels at a time
- uint8_t *d, yoffset=0;
-
- // If not the full screen is updated, check the validity of the update rect.
- if ( updRectX != 0 || updRectY != 0 ||updRectW != LCDWIDTH ||updRectH != LCDHEIGHT ) {
- uint8_t org_screenx = updRectX;
- updRectX &= 0xfc; // Make the value dividable by 4.
- updRectW += org_screenx - updRectX;
- updRectW = (updRectW + 3) & 0xfc; // Make the value dividable by 4, round up.
-
- uint8_t org_screeny = updRectY;
- updRectY &= 0xfc; // Make the value dividable by 4.
- updRectH += org_screeny - updRectY;
- updRectH = (updRectH + 7) & 0xf8; // Make the value dividable by 8 (because of loop unroll optimization), round up.
- }
-
-
- #ifdef PROJ_SHOW_FPS_COUNTER
- xptr = 8;
- setDRAMptr(8, 0);
- #else
- xptr = 0;
- setDRAMptr(0, 0);
- #endif
-
- for (x=updRectX; x<updRectX+updRectW; x+=4) {
- d = scrbuf+(x>>2);// point to beginning of line in data
-
- /** find colours in one scanline **/
- uint8_t s=0;
- d += (updRectY * 220/4);
- for (y=updRectY; y<updRectY+updRectH; y++) {
- uint8_t tdata = *d;
- uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
- uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
- uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
- uint8_t t = tdata & 0x03;// highest half-nibble
-
- /** put nibble values in the scanlines **/
- scanline[0][y] = paletteptr[t];
- scanline[1][y] = paletteptr[t2];
- scanline[2][y] = paletteptr[t3];
- scanline[3][y] = paletteptr[t4];
-
- d += 220/4; // jump to read byte directly below in screenbuffer
- }
-
- #ifdef PROJ_SHOW_FPS_COUNTER
- if (x>=8 ) {
- #else
- {
-
- #endif
-
- // Draw 8 vertical pixels at a time for performance reasons
- setDRAMptr(x, updRectY);
- for (uint8_t s=updRectY; s<updRectY+updRectH;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- }
- setDRAMptr(x+1, updRectY);
- for (uint8_t s=updRectY; s<updRectY+updRectH;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- }
- setDRAMptr(x+2, updRectY);
- for (uint8_t s=updRectY; s<updRectY+updRectH;) {
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- }
- setDRAMptr(x+3, updRectY);
- for (uint8_t s=updRectY; s<updRectY+updRectH;) {
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- }
- }
- }
-
- #ifdef POK_SIM
- simulator.refreshDisplay();
- #endif
-}
-
-// Copy sprite pixels to the scanline
-#define SPRITE_2BPP_INNER_LOOP(n)\
-\
- /* If the sprite is enabled and contained in this vertical scanline, copy 4 pixels. */\
- if (sprScanlineAddr[(n)] &&\
- y >= sprites[(n)].y && y < sprites[(n)].y + sprites[(n)].h ) {\
-\
- int16_t sprx = sprites[(n)].x;\
- uint16_t s_data16b = 0; /* sprite data, 2 bytes */\
-\
- /* Get pixel block, 4 or 8 pixels horizontally. Use the predefined bitshift mode. */\
- /* Note:it is cheapest to compare to 0 first. */\
- if (sprScanlineBitshiftMode[(n)] == BITSHIFT_MODE_MIDDLE_BYTE) {\
- s_data16b = *(sprScanlineAddr[(n)]);\
- uint16_t leftByte = *(sprScanlineAddr[(n)]-1);\
- s_data16b = (leftByte << 8) | s_data16b;\
- }\
- else if (sprScanlineBitshiftMode[(n)] == BITSHIFT_MODE_FIRST_BYTE) {\
- s_data16b = *(sprScanlineAddr[(n)]);\
- }\
- else { /* BITSHIFT_MODE_LAST_BYTE */\
- uint16_t leftByte = *(sprScanlineAddr[(n)]-1);\
- s_data16b = (leftByte << 8) | s_data16b;\
- }\
-\
- /* Shift sprite pixels according to sprite x. After shifting we have only 4 pixels. */\
- uint8_t shiftRight = (sprx&0x3) << 1;\
- s_data16b = (s_data16b >> shiftRight);\
-\
- /* Get individual pixels */\
- uint8_t s_t4 = s_data16b & 0x03; s_data16b >>= 2; /* lowest half-nibble */\
- uint8_t s_t3 = s_data16b & 0x03; s_data16b >>= 2; /* second lowest half-nibble */\
- uint8_t s_t2 = s_data16b & 0x03; s_data16b >>= 2; /* second highest half-nibble */\
- uint8_t s_t1 = s_data16b & 0x03; /* highest half-nibble */\
-\
- /* Store pixels as 16-bit colors from the palette */\
- if (s_t4 != transparentColor) p4 = sprites[(n)].palette[s_t4];\
- if (s_t3 != transparentColor) p3 = sprites[(n)].palette[s_t3];\
- if (s_t2 != transparentColor) p2 = sprites[(n)].palette[s_t2];\
- if (s_t1 != transparentColor) p = sprites[(n)].palette[s_t1];\
-\
- /* Advance scanline address */\
- sprScanlineAddr[(n)] += (sprites[(n)].w >> 2);\
- }
-
-// Loop unrolling macros
-#define UNROLLED_LOOP_1() SPRITE_2BPP_INNER_LOOP(0)
-#define UNROLLED_LOOP_2() UNROLLED_LOOP_1() SPRITE_2BPP_INNER_LOOP(1)
-#define UNROLLED_LOOP_3() UNROLLED_LOOP_2() SPRITE_2BPP_INNER_LOOP(2)
-#define UNROLLED_LOOP_4() UNROLLED_LOOP_3() SPRITE_2BPP_INNER_LOOP(3)
-#define UNROLLED_LOOP_5() UNROLLED_LOOP_4() SPRITE_2BPP_INNER_LOOP(4)
-#define UNROLLED_LOOP_6() UNROLLED_LOOP_5() SPRITE_2BPP_INNER_LOOP(5)
-#define UNROLLED_LOOP_7() UNROLLED_LOOP_6() SPRITE_2BPP_INNER_LOOP(6)
-#define UNROLLED_LOOP_8() UNROLLED_LOOP_7() SPRITE_2BPP_INNER_LOOP(7)
-#define UNROLLED_LOOP_9() UNROLLED_LOOP_8() SPRITE_2BPP_INNER_LOOP(8)
-#define UNROLLED_LOOP_10() UNROLLED_LOOP_9() SPRITE_2BPP_INNER_LOOP(9)
-#define UNROLLED_LOOP_11() UNROLLED_LOOP_10() SPRITE_2BPP_INNER_LOOP(10)
-#define UNROLLED_LOOP_12() UNROLLED_LOOP_11() SPRITE_2BPP_INNER_LOOP(11)
-#define UNROLLED_LOOP_13() UNROLLED_LOOP_12() SPRITE_2BPP_INNER_LOOP(12)
-#define UNROLLED_LOOP_14() UNROLLED_LOOP_13() SPRITE_2BPP_INNER_LOOP(13)
-#define UNROLLED_LOOP_15() UNROLLED_LOOP_14() SPRITE_2BPP_INNER_LOOP(14)
-#define UNROLLED_LOOP_16() UNROLLED_LOOP_15() SPRITE_2BPP_INNER_LOOP(15)
-#define UNROLLED_LOOP_N_(n) UNROLLED_LOOP_##n()
-#define UNROLLED_LOOP_N(n) UNROLLED_LOOP_N_(n)
-
-/***
- * Update the screen buffer of 220x176 pixels, 4 colors and free size 4 color sprites to LCD.
- *
- * The update rect is used for drawing only part of the screen buffer to LCD. Because of speed optimizations, the
- * x, y, and width of the update rect must be dividable by 4 pixels, and the height must be dividable by 8 pixels.
- * Note: The update rect is currently used for 220x176, 4 colors, screen mode only.
- * If drawSpritesOnly=true, only sprites are fully updated to LCD. However, the dirty rect of the screen buffer is
- * drawn behind the sprite current and previous location.
- * Note: Sprite is enabled if sprite.bitmapData is not NULL. Also all enabled sprites must be at the beginning of
- * the sprites array. No gaps are allowed in the array.
- * @param scrbuf The screen buffer.
- * @param updRectX The update rect.
- * @param updRectY The update rect.
- * @param updRectW The update rect.
- * @param updRectH The update rect.
- * @param paletteptr The screen palette.
- * @param sprites The sprite array.
- * @param drawSpritesOnly True, if only sprites are drawn. False, if both sprites and the screen buffer are drawn.
-*/
-void Pokitto::lcdRefreshMode1Spr(
- uint8_t * scrbuf, uint8_t updRectX, uint8_t updRectY, uint8_t updRectW, uint8_t updRectH, uint16_t* paletteptr,
- SpriteInfo* sprites, bool drawSpritesOnly) {
-
- // In direct mode draw only sprites and their dirty rects. Return now if there are no sprites
- if (drawSpritesOnly && (sprites == NULL || sprites[0].bitmapData == NULL))
- return;
-
- uint16_t x,y;
- uint16_t scanline[4][176]; // read 4 half-nibbles (= 4 pixels) at a time
- const uint8_t transparentColor = 0; // fixed palette index 0 for transparency
-
- // If not the full screen is updated, check the validity of the update rect.
- if ( updRectX != 0 || updRectY != 0 ||updRectW != LCDWIDTH ||updRectH != LCDHEIGHT ) {
- uint8_t org_screenx = updRectX;
- updRectX &= 0xfc; // Make the value dividable by 4.
- updRectW += org_screenx - updRectX;
- updRectW = (updRectW + 3) & 0xfc; // Make the value dividable by 4, round up.
-
- uint8_t org_screeny = updRectY;
- updRectY &= 0xfc; // Make the value dividable by 4.
- updRectH += org_screeny - updRectY;
- updRectH = (updRectH + 7) & 0xf8; // Make the value dividable by 8 (because of loop unroll optimization), round up.
- }
-
- // Calculate the current amount of sprites
- // Note: Sprites must be taken into use from index 0 upwards, because the first sprite with bitmapData==NULL is considered as the last sprite
- uint8_t spriteCount = 0;
- if (sprites != NULL)
- for (;sprites[spriteCount].bitmapData != NULL && spriteCount < SPRITE_COUNT; spriteCount++);
-
- // If drawing the screen buffer, set the start pos to LCD commands only here.
- #ifdef PROJ_SHOW_FPS_COUNTER
- if (!drawSpritesOnly) setDRAMptr(8, 0);
- #else
- if (!drawSpritesOnly) setDRAMptr(0, 0);
- #endif
-
- //*** GO THROUGH EACH VERTICAL GROUP OF 4 SCANLINES.***
-
- for (x=0; x<LCDWIDTH; x+=4) {
-
- uint8_t *screenBufScanlineAddr = scrbuf + (x>>2);// point to beginning of line in data
-
- /*Prepare scanline start address for sprites that are visible in this vertical scanline. Sprite width cannot exceed the screen width*/
- uint8_t *sprScanlineAddr[SPRITE_COUNT]; // Sprite start address for the scanline
- uint8_t sprScanlineBitshiftMode[SPRITE_COUNT]; // Sprite bitshift mode for the scanline
- const uint8_t BITSHIFT_MODE_MIDDLE_BYTE = 0;
- const uint8_t BITSHIFT_MODE_FIRST_BYTE = 1;
- const uint8_t BITSHIFT_MODE_LAST_BYTE = 2;
- uint8_t scanlineMinY = 255; // Init to uninitialized value. Do not draw by default.
- uint8_t scanlineMaxY = 0; // Init to uninitialized value. Do not draw by default.
-
- //*** CALCULATE DIRTY RECTS AND RESOLVE WHICH SPRITES BELONG TO THIS SCANLINE GROUP ***
-
- if (sprites != NULL) {
-
- // Check all the sprites for this scanline. That is used for handling the given update rect
- // Note that the last round is when (sprindex == spriteCount). That is used to add the screen buffer
- // update rect to the dirty rect.
- for (int sprindex = 0; sprindex <= spriteCount; sprindex++) {
-
- int16_t sprx, spry, sprOldX, sprOldY;
- uint8_t sprw, sprh;
- bool isCurrentSpriteOutOfScreen = false;
- bool isOldSpriteOutOfScreen = false;
-
- if (sprindex < spriteCount) {
-
- sprx = sprites[sprindex].x;
- spry = sprites[sprindex].y;
- sprw = sprites[sprindex].w;
- sprh = sprites[sprindex].h;
- sprOldX = sprites[sprindex].oldx;
- sprOldY = sprites[sprindex].oldy;
- }
-
- // Handle the screen buffer update rect after all sprites
- else if(!drawSpritesOnly){
-
- sprx = updRectX;
- spry = updRectY;
- sprw = updRectW;
- sprh = updRectH;
- sprOldX = updRectX;
- sprOldY = updRectY;
- isCurrentSpriteOutOfScreen = false;
- isOldSpriteOutOfScreen = false;
- }
-
- // Check for out-of-screen
- if (sprx >= LCDWIDTH || spry >= LCDHEIGHT)
- isCurrentSpriteOutOfScreen = true;
- if (sprOldX >= LCDWIDTH || sprOldY >= LCDHEIGHT)
- isOldSpriteOutOfScreen = true;
-
- // Skip if current and old sprites are out-of-screen
- if (isCurrentSpriteOutOfScreen && isOldSpriteOutOfScreen)
- continue;
-
- // Detect the dirty rect x-span by combining the previous and current sprite position.
- int16_t sprDirtyXMin = min(sprx, sprOldX);
- int16_t sprDirtyXMax = max(sprx, sprOldX);
- if (isCurrentSpriteOutOfScreen)
- sprDirtyXMax = sprOldX;
- if (isOldSpriteOutOfScreen)
- sprDirtyXMax = sprx;
-
- // Is current x inside the sprite combined dirty rect ?
- int16_t sprDirtyXMaxEnd = sprDirtyXMax + sprw - 1 + 4; // Add 4 pixels to dirty rect width (needed?)
- if (sprDirtyXMin <= x+3 && x <= sprDirtyXMaxEnd) {
-
- // *** COMBINE DIRTY RECTS FOR THIS SCANLINE GROUP ***
-
- // Dirty rect
- int16_t sprDirtyYMin = min(spry, sprOldY);
- sprDirtyYMin = max(sprDirtyYMin, 0);
- int16_t sprDirtyYMax = max(spry, sprOldY);
- if (isCurrentSpriteOutOfScreen)
- sprDirtyYMax = sprOldY;
- if (isOldSpriteOutOfScreen)
- sprDirtyYMax = spry;
- int16_t sprDirtyYMaxEnd = sprDirtyYMax + sprh - 1;
- sprDirtyYMaxEnd = min(sprDirtyYMaxEnd, LCDHEIGHT - 1); // Should use LCDHEIGHT instead of screenH? Same with other screen* ?
-
- // Get the scanline min and max y values for drawing
- if (sprDirtyYMin < scanlineMinY)
- scanlineMinY = sprDirtyYMin;
- if (sprDirtyYMaxEnd > scanlineMaxY)
- scanlineMaxY = sprDirtyYMaxEnd;
-
- // *** PREPARE SPRITE FOR DRAWING ***
-
- // Check if the sprite should be active for this vertical scanline group.
- if (sprindex < spriteCount && // not for update rect
- !isCurrentSpriteOutOfScreen && //out-of-screen
- sprx <= x+3 && x < sprx + sprw) { // note: cover group of 4 pixels of the scanline (x+3)
-
- // Find the byte number in the sprite data
- int16_t byteNum = ((x+3) - sprx)>>2;
-
- // Get the start addres of the spite data in this scanline.
- sprScanlineAddr[sprindex] = const_cast<uint8_t*>(sprites[sprindex].bitmapData + byteNum);
-
- // If the sprite goes over the top, it must be clipped from the top.
- if(spry < 0)
- sprScanlineAddr[sprindex] += (-spry) * (sprw >> 2);
-
- // Select the bitshift mode for the blit algorithm
- if (byteNum == 0)
- sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_FIRST_BYTE;
- else if (byteNum >= (sprw >> 2))
- sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_LAST_BYTE;
- else
- sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_MIDDLE_BYTE;
- }
- else
- sprScanlineAddr[sprindex] = NULL; // Deactive sprite for this scanline
- }
- else
- sprScanlineAddr[sprindex] = NULL; // Deactive sprite for this scanline
- }
- }
-
- // *** ADJUST THE SCANLINE GROUP HEIGHT ***
-
- // The height must dividable by 8. That is needed because later we copy 8 pixels at a time to the LCD.
- if (scanlineMaxY - scanlineMinY + 1 > 0) {
- uint8_t scanlineH = scanlineMaxY - scanlineMinY + 1;
- uint8_t addW = 8 - (scanlineH & 0x7);
-
- // if height is not dividable by 8, make it be.
- if (addW != 0) {
- if (scanlineMinY > addW )
- scanlineMinY -= addW;
- else if( scanlineMaxY + addW < updRectY+updRectH)
- scanlineMaxY += addW;
- else {
- // Draw full height scanline
- scanlineMinY = updRectY;
- scanlineMaxY = updRectY+updRectH-1;
- }
- }
- }
-
- // *** COMBINE THE SCANLINE GROUP OF THE SCREEN BUFFER AND ALL SPRITES ***
-
- // Find colours in this group of 4 scanlines
- screenBufScanlineAddr += (scanlineMinY * 220/4);
- for (y=scanlineMinY; y<=scanlineMaxY; y++)
- {
- // get the screen buffer data first
- uint8_t tdata = *screenBufScanlineAddr;
- uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
- uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
- uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
- uint8_t t = tdata & 0x03;// highest half-nibble
-
- // Convert to 16-bit colors in palette
- uint16_t p = paletteptr[t];
- uint16_t p2 = paletteptr[t2];
- uint16_t p3 = paletteptr[t3];
- uint16_t p4 = paletteptr[t4];
-
- #if 0
- // Dirty rect visual test
- p = COLOR_BLUE >> (Core::frameCount % 5);
- p2 = COLOR_BLUE >> (Core::frameCount % 5);
- p3 = COLOR_BLUE >> (Core::frameCount % 5);
- p4 = COLOR_BLUE >> (Core::frameCount % 5);
- #endif
-
- // Add active sprite pixels
- if (sprites != NULL) {
-
- // Use loop unrolling for speed optimization
- UNROLLED_LOOP_N(SPRITE_COUNT)
- }
-
- // put the result nibble values in the scanline
- scanline[0][y] = p;
- scanline[1][y] = p2;
- scanline[2][y] = p3;
- scanline[3][y] = p4;
-
- screenBufScanlineAddr += 220>>2; // jump to read byte directly below in screenbuffer
- }
-
- // *** DRAW THE SCANLINE GROUP TO LCD
-
-#ifdef PROJ_SHOW_FPS_COUNTER
- if (x>=8 && scanlineMaxY - scanlineMinY +1 > 0) {
-#else
- if (scanlineMaxY - scanlineMinY +1 > 0) {
-#endif
- // Draw 8 vertical pixels at a time for performance reasons
-
- setDRAMptr(x, scanlineMinY);
- for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- }
-
- setDRAMptr(x+1, scanlineMinY);
- for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- }
-
- setDRAMptr(x+2, scanlineMinY);
- for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- }
-
- setDRAMptr(x+3, scanlineMinY);
- for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- }
- }
- }
-
- // Update old x and y for the sprites
- if (sprites != NULL) {
- for (int sprindex = 0; sprindex < spriteCount; sprindex++) {
- sprites[sprindex].oldx = sprites[sprindex].x;
- sprites[sprindex].oldy = sprites[sprindex].y;
- }
- }
-
- #ifdef POK_SIM
- simulator.refreshDisplay();
- #endif
-}
-
-void Pokitto::lcdRefreshMode2(uint8_t * scrbuf, uint16_t* paletteptr) {
-uint16_t x,y;
-uint16_t scanline[2][88]; // read two nibbles = pixels at a time
-uint8_t *d;
-
-write_command(0x20); // Horizontal DRAM Address
-write_data(0); // 0
-write_command(0x21); // Vertical DRAM Address
-write_data(0);
-write_command(0x22); // write data to DRAM
-CLR_CS_SET_CD_RD_WR;
-
-for(x=0;x<110;x+=2)
- {
- d = scrbuf+(x>>1);// point to beginning of line in data
- /** find colours in one scanline **/
- uint8_t s=0;
- for(y=0;y<88;y++)
- {
- uint8_t t = *d >> 4; // higher nibble
- uint8_t t2 = *d & 0xF; // lower nibble
- /** higher nibble = left pixel in pixel pair **/
- scanline[0][s] = paletteptr[t];
- scanline[1][s++] = paletteptr[t2];
- /** testing only **/
- //scanline[0][s] = 0xFFFF*(s&1);
- //scanline[1][s] = 0xFFFF*(!(s&1));
- //s++;
- /** until here **/
- d+=110/2; // jump to read byte directly below in screenbuffer
- }
- s=0;
- /** draw scanlines **/
- /** leftmost scanline twice**/
-
- #ifdef PROJ_SHOW_FPS_COUNTER
- if (x<4) continue;
- setDRAMptr(x<<1, 0);
- #endif
-
- for (s=0;s<88;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
-
- for (s=0;s<88;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
- /** rightmost scanline twice**/
- //setDRAMptr(xptr++,yoffset);
- for (s=0;s<88;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
-
- for (s=0;s<88;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
- }
-}
-
-void Pokitto::lcdRefreshMode3(uint8_t * scrbuf, uint16_t* paletteptr) {
-uint16_t x,y;
-uint16_t scanline[2][176]; // read two nibbles = pixels at a time
-uint8_t *d;
-
-write_command(0x20); // Horizontal DRAM Address
-write_data(0); // 0
-write_command(0x21); // Vertical DRAM Address
-write_data(0);
-write_command(0x22); // write data to DRAM
-CLR_CS_SET_CD_RD_WR;
-
-for(x=0;x<220;x+=2)
- {
- d = scrbuf+(x>>1);// point to beginning of line in data
- /** find colours in one scanline **/
- uint8_t s=0;
- for(y=0;y<176;y++)
- {
- uint8_t t = *d >> 4; // higher nibble
- uint8_t t2 = *d & 0xF; // lower nibble
- /** higher nibble = left pixel in pixel pair **/
- scanline[0][s] = paletteptr[t];
- scanline[1][s++] = paletteptr[t2];
- /** testing only **/
- //scanline[0][s] = 0xFFFF*(s&1);
- //scanline[1][s] = 0xFFFF*(!(s&1));
- //s++;
- /** until here **/
- d+=220/2; // jump to read byte directly below in screenbuffer
- }
- s=0;
- /** draw scanlines **/
- /** leftmost scanline**/
-
- #ifdef PROJ_SHOW_FPS_COUNTER
- if (x<8) continue;
- setDRAMptr(x, 0);
- #endif
-
- for (s=0;s<176;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- }
-
- /** rightmost scanline**/
- //setDRAMptr(xptr++,yoffset);
- for (s=0;s<176;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- }
- }
-}
-
-void Pokitto::lcdRefreshGB(uint8_t * scrbuf, uint16_t* paletteptr) {
-uint16_t x,y;
-uint16_t scanline[48];
-uint8_t * d;
-
-#if POK_STRETCH
-//uint16_t xptr = 8;
-#else
-//xptr = 26;
-#endif
-
-write_command(0x20); // Horizontal DRAM Address
-write_data(0); // 0
-write_command(0x21); // Vertical DRAM Address
-write_data(0);
-write_command(0x22); // write data to DRAM
-CLR_CS_SET_CD_RD_WR;
-
-/** draw border **/
- for (int s=0;s<5*176;) {
- setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;s++;
- }
-
-for(x=0;x<84;x++)
- {
-
- d = scrbuf + x;// point to beginning of line in data
-
- /** find colours in one scanline **/
- uint8_t s=0;
- for(y=0;y<6;y++)
- {
- uint8_t t = *d;
- #if POK_COLORDEPTH > 1
- uint8_t t2 = *(d+504);
- #endif
- #if POK_COLORDEPTH > 2
- uint8_t t3 = *(d+504+504);
- #endif
- #if POK_COLORDEPTH > 3
- uint8_t t4 = *(d+504+504+504);
- #endif
- uint8_t paletteindex = 0;
-
- /** bit 1 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x1);
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x1)) | ((t2 & 0x01)<<1);
- #elif POK_COLORDEPTH == 3
- paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2);
- #elif POK_COLORDEPTH == 4
- paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2) | ((t4 & 0x1)<<3);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 2 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x2)>>1;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x2)>>1) | ((t2 & 0x02));
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1) | ((t4 & 0x2)<<2);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 3 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x4)>>2;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 4)>>2) | ((t2 & 0x04)>>1);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4) | ((t4 & 0x4)<<1);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 4 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x8)>>3;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x8)>>3) | ((t2 & 0x08)>>2);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1) | (t4 & 0x8);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 5 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x10)>>4;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2) | ((t4 & 0x10)>>1);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 6 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x20)>>5;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3) | ((t4 & 0x20)>>2);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 7 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x40)>>6;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) ;
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) | ((t4 & 0x40)>>3);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 8 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x80)>>7;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5) | ((t4 & 0x80)>>4);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- d+=84; // jump to byte directly below
- }
-
-
- /*write_command(0x20); // Horizontal DRAM Address
- write_data(0x10); // 0
- write_command(0x21); // Vertical DRAM Address
- write_data(xptr++);
- write_command(0x22); // write data to DRAM
- CLR_CS_SET_CD_RD_WR;*/
- /** draw border **/
- 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;
-
- s=0;
-
- /** draw scanlines **/
- for (s=0;s<48;) {
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
- /** draw border **/
- 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;
-
-
- /*write_command(0x20); // Horizontal DRAM Address
- write_data(0x10); // 0
- write_command(0x21); // Vertical DRAM Address
- write_data(xptr++);
- write_command(0x22); // write data to DRAM
- CLR_CS_SET_CD_RD_WR;*/
- /** draw border **/
- 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;
-
- for (s=0;s<48;) {
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
-
- /** draw border **/
- 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;
-
-
- #if POK_STRETCH
- //if (x>16 && x<68)
- if (x&2)// && x&2)
- {
- /*write_command(0x20); // Horizontal DRAM Address
- write_data(0x10); // 0
- write_command(0x21); // Vertical DRAM Address
- write_data(xptr++);
- write_command(0x22); // write data to DRAM
- CLR_CS_SET_CD_RD_WR;*/
- /** draw border **/
- 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;
-
-
- for (s=0;s<48;) {
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
-
- /** draw border **/
- 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;
-
- }
- #endif
- }
- /** draw border **/
- for (int s=0;s<5*176;) {
- setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;s++;
- }
-}
-
-
-void Pokitto::lcdRefreshAB(uint8_t * scrbuf, uint16_t* paletteptr) {
-uint16_t x,y;
-uint16_t scanline[64];
-uint8_t *d;
-//lcdClear();
-#if POK_STRETCH
-uint16_t xptr = 14;
-uint8_t yoffset = 24;
-#else
-uint16_t xptr = 0;
-uint8_t yoffset = 0;
-#endif
-
-for(x=0;x<128;x++)
- {
- write_command(0x20); // Horizontal DRAM Address
- write_data(yoffset); // 0
- write_command(0x21); // Vertical DRAM Address
- write_data(xptr++);
- write_command(0x22); // write data to DRAM
- CLR_CS_SET_CD_RD_WR;
- //setDRAMptr(xptr++,yoffset);
-
- d = scrbuf + x;// point to beginning of line in data
-
- /** find colours in one scanline **/
- uint8_t s=0;
- for(y=0;y<8;y++)
- {
- uint8_t t = *d;
- #if POK_COLORDEPTH > 1
- uint8_t t2 = *(d+AB_JUMP);
- #endif // POK_COLORDEPTH
- #if POK_COLORDEPTH > 2
- uint8_t t3 = *(d+AB_JUMP+AB_JUMP);
- #endif // POK_COLORDEPTH
- #if POK_COLORDEPTH > 3
- uint8_t t4 = *(d+AB_JUMP+AB_JUMP+AB_JUMP);
- #endif // POK_COLORDEPTH
- uint8_t paletteindex = 0;
-
- /** bit 1 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x1);
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x1)) | ((t2 & 0x01)<<1);
- #elif POK_COLORDEPTH == 3
- paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2);
- #elif POK_COLORDEPTH == 4
- paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2) | ((t4 & 0x1)<<3);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 2 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x2)>>1;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x2)>>1) | ((t2 & 0x02));
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1) | ((t4 & 0x2)<<2);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 3 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x4)>>2;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 4)>>2) | ((t2 & 0x04)>>1);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4) | ((t4 & 0x4)<<1);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 4 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x8)>>3;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x8)>>3) | ((t2 & 0x08)>>2);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1) | (t4 & 0x8);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 5 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x10)>>4;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2) | ((t4 & 0x10)>>1);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 6 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x20)>>5;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3) | ((t4 & 0x20)>>2);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 7 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x40)>>6;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) ;
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) | ((t4 & 0x40)>>3);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- /** bit 8 **/
- #if POK_COLORDEPTH == 1
- paletteindex = (t & 0x80)>>7;
- #elif POK_COLORDEPTH == 2
- paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6);
- #elif POK_COLORDEPTH == 3
- paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5);
- #elif POK_COLORDEPTH == 4
- paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5) | ((t4 & 0x80)>>4);
- #endif
- scanline[s++] = paletteptr[paletteindex];
-
- d+=128; // jump to byte directly below
- }
-
- s=0;
-
- /** draw scanlines **/
- for (s=0;s<64;) {
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
-
- #if POK_STRETCH
- if (x&1) {
- write_command(0x20); // Horizontal DRAM Address
- write_data(yoffset); // 0
- write_command(0x21); // Vertical DRAM Address
- write_data(xptr++);
- write_command(0x22); // write data to DRAM
- CLR_CS_SET_CD_RD_WR;
- //setDRAMptr(xptr++,yoffset);
-
- for (s=0;s<64;) {
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
- }
- #endif
- }
-}
-
-void Pokitto::lcdRefreshModeGBC(uint8_t * scrbuf, uint16_t* paletteptr) {
-uint16_t x,y,xptr;
-uint16_t scanline[4][144]; // read 4 half-nibbles = 4 pixels at a time
-uint8_t *d, yoffset=0;
-
-xptr = 0;
-setDRAMptr(xptr,yoffset);
-
-
-for(x=0;x<160;x+=4)
- {
- d = scrbuf+(x>>2);// point to beginning of line in data
- /** find colours in one scanline **/
- uint8_t s=0;
- for(y=0;y<144;y++)
- {
- uint8_t tdata = *d;
- uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
- uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
- uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
- uint8_t t = tdata & 0x03;// highest half-nibble
-
- /** put nibble values in the scanlines **/
-
- scanline[0][s] = paletteptr[t];
- scanline[1][s] = paletteptr[t2];
- scanline[2][s] = paletteptr[t3];
- scanline[3][s++] = paletteptr[t4];
-
- d+=160/4; // jump to read byte directly below in screenbuffer
- }
-
- s=0;
- /** draw scanlines **/
- for (s=0;s<144;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- }
- setDRAMptr(++xptr,yoffset);
- for (s=0;s<144;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- }
- setDRAMptr(++xptr,yoffset);
- for (s=0;s<144;) {
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
- }
- setDRAMptr(++xptr,yoffset);
- for (s=0;s<144;) {
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
- }
- setDRAMptr(++xptr,yoffset);
- }
-}
-
-
-void Pokitto::lcdRefreshT1(uint8_t* tilebuf, uint8_t* tilecolorbuf, uint8_t* tileset, uint16_t* paletteptr) {
-#ifdef POK_TILEMODE
-uint16_t x,y,data,xptr;
-uint16_t scanline[176];
-uint8_t yoffset=0, tilebyte, tileindex, tilex=0, tiley=0,xcount;
-
-
-if (!tileset) return;
-
-#if LCDWIDTH < POK_LCD_W
-xptr = (POK_LCD_W-LCDWIDTH)/2;
-#else
-xptr = 0;
-#endif
-#if LCDHEIGHT < POK_LCD_H
-yoffset = (POK_LCD_H-LCDHEIGHT)/2;
-#else
-yoffset = 0;
-#endif
-
-for(x=0, xcount=0 ;x<LCDWIDTH;x++,xcount++) // loop through vertical columns
- {
- setDRAMptr(xptr++,yoffset); //point to VRAM
-
- /** find colours in one scanline **/
- uint8_t s=0, tiley=0;
- //tileindex = tilebuf[tilex*POK_TILES_Y];
- if (xcount==POK_TILE_W) {
- tilex++;
- xcount=0;
- }
-
- for(y=0;y<LCDHEIGHT;)
- {
- uint8_t tileval = tilebuf[tilex+tiley*POK_TILES_X]; //get tile number
- uint16_t index = tileval*POK_TILE_W+xcount;
- uint8_t tilebyte = tileset[index]; //get bitmap data
- for (uint8_t ycount=0, bitcount=0; ycount<POK_TILE_H; ycount++, y++, bitcount++) {
- if (bitcount==8) {
- bitcount=0;
- index += 176; //jump to byte below in the tileset bitmap
- tilebyte = tileset[index]; //get bitmap data
- }
- //tilebyte = tile[(tileindex>>4)+*POK_TILE_W]; //tilemaps are 16x16
- //uint8_t paletteindex = ((tilebyte>>(bitcount&0x7)) & 0x1);
- if (!tileval) scanline[s++] = COLOR_MAGENTA*((tilebyte>>bitcount)&0x1);//paletteptr[paletteindex];
- else scanline[s++] = paletteptr[((tilebyte>>bitcount)&0x1)*tileval];//paletteptr[paletteindex];
- }
- tiley++; //move to next tile
- }
- s=0;
-
- /** draw scanlines **/
- for (s=0;s<LCDHEIGHT;) {
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
- }
- }
- #endif
-}
-
-
-void Pokitto::lcdRefreshMode13(uint8_t * scrbuf, uint16_t* paletteptr, uint8_t offset){
-uint16_t x,y;
-uint16_t scanline[2][110]; // read two nibbles = pixels at a time
-uint8_t *d;
-
-write_command(0x20); write_data(0);
-write_command(0x21); write_data(0);
-write_command(0x22);
-CLR_CS_SET_CD_RD_WR;
-
-for(x=0;x<110;x+=2)
- {
- d = scrbuf+x;// point to beginning of line in data
- uint8_t s=0;
- for(y=0;y<88;y++)
- {
- uint8_t t = *d;
- uint8_t t1 = *(d+1);
- scanline[0][s] = paletteptr[(t+offset)&255];
- scanline[1][s++] = paletteptr[(t1+offset)&255];
- d+=110; // jump to read byte directly below in screenbuffer
- }
- s=0;
- for (s=0;s<88;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
- for (s=0;s<88;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
- for (s=0;s<88;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
- for (s=0;s<88;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
- }
- }
-
-}
-
-
-
-void Pokitto::lcdRefreshMode14(uint8_t * scrbuf, uint16_t* paletteptr) {
-uint16_t x,y,data,xptr;
-uint16_t scanline[176]; uint16_t* scptr;
-uint8_t *d;
-
-write_command(0x20); write_data(0);
-write_command(0x21); write_data(0);
-write_command(0x22);
-CLR_CS_SET_CD_RD_WR;
-
-for(x=0;x<220;x++)
- {
- d = scrbuf+x;
- scptr = &scanline[0];
-
- /** find colours in one scanline **/
- /*for(y=0;y<22;y++)
- {
-
- uint16_t t = *d;
- uint16_t t2 = *(d+POK_BITFRAME);
- uint16_t t3 = *(d+POK_BITFRAME+POK_BITFRAME);
-
- *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
- *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
- *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
- *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
-
- *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
- *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
- *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
- *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
-
-
- d+=220; // jump to word directly below
- }
- */
- /** alternative way: go through one color at a time **/
- scptr = &scanline[0]; // set to beginning of scanline
- for(y=0;y<22;y++, d +=220)
- {
- uint16_t t = *d & 0xFF;
-
- *scptr++ = R_MASK * (t&0x1); t >>= 1;
- *scptr++ = R_MASK * (t&0x1); t >>= 1;
- *scptr++ = R_MASK * (t&0x1); t >>= 1;
- *scptr++ = R_MASK * (t&0x1); t >>= 1;
- *scptr++ = R_MASK * (t&0x1); t >>= 1;
- *scptr++ = R_MASK * (t&0x1); t >>= 1;
- *scptr++ = R_MASK * (t&0x1); t >>= 1;
- *scptr++ = R_MASK * (t&0x1);
- }
- scptr = &scanline[0]; // set to beginning of scanline
- d = scrbuf+x+POK_BITFRAME;
- for(y=0;y<22;y++, d +=220)
- {
- uint16_t t = *d & 0xFF;
-
- *scptr++ |= G_MASK * (t&0x1); t >>= 1;
- *scptr++ |= G_MASK * (t&0x1); t >>= 1;
- *scptr++ |= G_MASK * (t&0x1); t >>= 1;
- *scptr++ |= G_MASK * (t&0x1); t >>= 1;
- *scptr++ |= G_MASK * (t&0x1); t >>= 1;
- *scptr++ |= G_MASK * (t&0x1); t >>= 1;
- *scptr++ |= G_MASK * (t&0x1); t >>= 1;
- *scptr++ |= G_MASK * (t&0x1);
- }
- scptr = &scanline[0]; // set to beginning of scanline
- d = scrbuf+x+POK_BITFRAME*2;
- for(y=0;y<22;y++, d +=220)
- {
- uint16_t t = *d & 0xFF;
-
- *scptr++ |= B_MASK * (t&0x1); t >>= 1;
- *scptr++ |= B_MASK * (t&0x1); t >>= 1;
- *scptr++ |= B_MASK * (t&0x1); t >>= 1;
- *scptr++ |= B_MASK * (t&0x1); t >>= 1;
- *scptr++ |= B_MASK * (t&0x1); t >>= 1;
- *scptr++ |= B_MASK * (t&0x1); t >>= 1;
- *scptr++ |= B_MASK * (t&0x1); t >>= 1;
- *scptr++ |= B_MASK * (t&0x1);
- }
-
-
- #ifdef PROJ_SHOW_FPS_COUNTER
- if (x<8) continue;
- setDRAMptr(x, 0);
- #endif
-
- /** draw scanlines **/
- for (int s=0;s<176;) {
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[s++]);CLR_WR;SET_WR;
-
- }
-
- }
-}
-
-//#define ADEKTOSMODE15
-
-#ifdef ADEKTOSMODE15
-void Pokitto::lcdRefreshMode15(uint16_t* pal, uint8_t* scrbuf){
- write_command(0x03); write_data(0x1038); //realy only need to call this once
- write_command(0x20); write_data(0);
- write_command(0x21); write_data(0);
-
- write_command(0x22);
-
- #ifdef PROJ_SHOW_FPS_COUNTER
- for (int x=0,xt=0; x<0x4BA0;x++,xt++) {
- if (xt==110) xt=0;
- if (xt<8) {
- write_data(0);
- write_data(0);
- } else {
- write_data(pal[(((scrbuf[x]) & 0xf0) >> 4)]);
- write_data(pal[( (scrbuf[x]) & 0x0f)]);
- }
-
- }
- #else
- for (int x=0; x<0x4BA0;x++) {
- write_data(pal[(((scrbuf[x]) & 0xf0) >> 4)]);
- write_data(pal[( (scrbuf[x]) & 0x0f)]);
- }
- #endif //PROJ_SHOW_FPS_COUNTER
-}
-
-#else
-
-void Pokitto::lcdRefreshMode15(uint16_t* paletteptr, uint8_t* scrbuf){
-uint16_t x,y,xptr;
-uint16_t scanline[2][176]; // read two nibbles = pixels at a time
-uint8_t *d, yoffset=0;
-
-xptr = 0;
-//setDRAMptr(xptr,yoffset);
-
-write_command(0x20); write_data(0);
-write_command(0x21); write_data(0);
-write_command(0x22);
-CLR_CS_SET_CD_RD_WR;
-
-for(x=0;x<220;x+=2)
- {
- d = scrbuf+(x>>1);// point to beginning of line in data
- // find colours in one scanline
- uint8_t s=0;
- for(y=0;y<176;y++)
- {
- uint8_t t = *d >> 4; // higher nibble
- uint8_t t2 = *d & 0xF; // lower nibble
- // higher nibble = left pixel in pixel pair
- scanline[0][s] = paletteptr[t];
- scanline[1][s++] = paletteptr[t2];
-
- d+=220/2; // jump to read byte directly below in screenbuffer
- }
- s=0;
- // draw scanlines
-
- #ifdef PROJ_SHOW_FPS_COUNTER
- if (x<8) continue;
- setDRAMptr(x, 0);
- #endif
-
- for (s=0;s<176;) {
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
- }
-
- for (s=0;s<176;) {
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
- }
- }
-}
-#endif //ADEKTOSMODE15
-
-void Pokitto::blitWord(uint16_t c) {
- setup_data_16(c);CLR_WR;SET_WR;
-}
-
-