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

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Committer:
Pokitto
Date:
Wed Dec 25 23:59:52 2019 +0000
Revision:
71:531419862202
Parent:
65:deed4aa606fb
Changed Mode2 C++ refresh code (graphical errors)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pokitto 46:e7e438368e16 1 /**************************************************************************/
Pokitto 46:e7e438368e16 2 /*!
Pokitto 46:e7e438368e16 3 @file HWLCD.cpp
Pokitto 46:e7e438368e16 4 @author Jonne Valola
Pokitto 46:e7e438368e16 5
Pokitto 46:e7e438368e16 6 @section LICENSE
Pokitto 46:e7e438368e16 7
Pokitto 46:e7e438368e16 8 Software License Agreement (BSD License)
Pokitto 46:e7e438368e16 9
Pokitto 46:e7e438368e16 10 Copyright (c) 2016, Jonne Valola
Pokitto 46:e7e438368e16 11 All rights reserved.
Pokitto 46:e7e438368e16 12
Pokitto 46:e7e438368e16 13 Redistribution and use in source and binary forms, with or without
Pokitto 46:e7e438368e16 14 modification, are permitted provided that the following conditions are met:
Pokitto 46:e7e438368e16 15 1. Redistributions of source code must retain the above copyright
Pokitto 46:e7e438368e16 16 notice, this list of conditions and the following disclaimer.
Pokitto 46:e7e438368e16 17 2. Redistributions in binary form must reproduce the above copyright
Pokitto 46:e7e438368e16 18 notice, this list of conditions and the following disclaimer in the
Pokitto 46:e7e438368e16 19 documentation and/or other materials provided with the distribution.
Pokitto 46:e7e438368e16 20 3. Neither the name of the copyright holders nor the
Pokitto 46:e7e438368e16 21 names of its contributors may be used to endorse or promote products
Pokitto 46:e7e438368e16 22 derived from this software without specific prior written permission.
Pokitto 46:e7e438368e16 23
Pokitto 46:e7e438368e16 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
Pokitto 46:e7e438368e16 25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Pokitto 46:e7e438368e16 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Pokitto 46:e7e438368e16 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
Pokitto 46:e7e438368e16 28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Pokitto 46:e7e438368e16 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Pokitto 46:e7e438368e16 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
Pokitto 46:e7e438368e16 31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Pokitto 46:e7e438368e16 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Pokitto 46:e7e438368e16 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Pokitto 46:e7e438368e16 34 */
Pokitto 46:e7e438368e16 35 /**************************************************************************/
Pokitto 46:e7e438368e16 36
Pokitto 46:e7e438368e16 37 #include "HWLCD.h" //HWLCD.h" #include "HWLCD.h"
Pokitto 46:e7e438368e16 38 #include "Pokitto_settings.h"
Pokitto 46:e7e438368e16 39
Pokitto 51:113b1d84c34f 40 #define avrmax(a,b) ((a)>(b)?(a):(b))
Pokitto 51:113b1d84c34f 41 #define avrmin(a,b) ((a)<(b)?(a):(b))
Pokitto 46:e7e438368e16 42
Pokitto 46:e7e438368e16 43 #ifdef DISABLEAVRMIN
Pokitto 46:e7e438368e16 44 #include <algorithm>
Pokitto 46:e7e438368e16 45 using std::min;
Pokitto 46:e7e438368e16 46 using std::max;
Pokitto 46:e7e438368e16 47 #endif // DISABLEAVRMIN
Pokitto 46:e7e438368e16 48
Pokitto 46:e7e438368e16 49 #define AB_JUMP 1024 // jump one 1-bit Arduboy screen forward to get next color bit
Pokitto 46:e7e438368e16 50 #define GB_JUMP 504 // jump one 1-bit Gamebuino screen forward to get next color bit
Pokitto 46:e7e438368e16 51
Pokitto 71:531419862202 52 //#undef __ARMCC_VERSION
Pokitto 71:531419862202 53
Pokitto 46:e7e438368e16 54 using namespace Pokitto;
Pokitto 46:e7e438368e16 55
Pokitto 46:e7e438368e16 56 uint16_t prevdata=0; // if data does not change, do not adjust LCD bus lines
Pokitto 46:e7e438368e16 57
Pokitto 46:e7e438368e16 58 #if POK_BOARDREV == 2
Pokitto 46:e7e438368e16 59 pwmout_t backlightpwm;
Pokitto 46:e7e438368e16 60 #endif
Pokitto 46:e7e438368e16 61
Pokitto 51:113b1d84c34f 62 volatile uint32_t *LCD = reinterpret_cast< volatile uint32_t * >(0xA0002188);
Pokitto 46:e7e438368e16 63
Pokitto 46:e7e438368e16 64 /**************************************************************************/
Pokitto 46:e7e438368e16 65 /*!
Pokitto 46:e7e438368e16 66 @brief set up the 16-bit bus
Pokitto 46:e7e438368e16 67 */
Pokitto 46:e7e438368e16 68 /**************************************************************************/
Pokitto 46:e7e438368e16 69
Pokitto 46:e7e438368e16 70 static inline void setup_data_16(uint16_t data)
Pokitto 46:e7e438368e16 71 {
Pokitto 46:e7e438368e16 72 //uint32_t p2=0;
Pokitto 46:e7e438368e16 73
Pokitto 46:e7e438368e16 74 //if (data != prevdata) {
Pokitto 46:e7e438368e16 75 //
Pokitto 46:e7e438368e16 76 //prevdata=data;
Pokitto 46:e7e438368e16 77
Pokitto 46:e7e438368e16 78 /** D0...D16 = P2_3 ... P2_18 **/
Pokitto 46:e7e438368e16 79 //p2 = data << 3;
Pokitto 46:e7e438368e16 80
Pokitto 46:e7e438368e16 81 //__disable_irq(); // Disable Interrupts
Pokitto 46:e7e438368e16 82 SET_MASK_P2;
Pokitto 46:e7e438368e16 83 LPC_GPIO_PORT->MPIN[2] = (data<<3); // write bits to port
Pokitto 46:e7e438368e16 84 CLR_MASK_P2;
Pokitto 46:e7e438368e16 85 //__enable_irq(); // Enable Interrupts
Pokitto 46:e7e438368e16 86 //}
Pokitto 46:e7e438368e16 87 }
Pokitto 46:e7e438368e16 88
Pokitto 46:e7e438368e16 89
Pokitto 46:e7e438368e16 90 /**************************************************************************/
Pokitto 46:e7e438368e16 91 /*!
Pokitto 46:e7e438368e16 92 @brief Write a command to the lcd, 16-bit bus
Pokitto 46:e7e438368e16 93 */
Pokitto 46:e7e438368e16 94 /**************************************************************************/
Pokitto 46:e7e438368e16 95 inline void write_command_16(uint16_t data)
Pokitto 46:e7e438368e16 96 {
Pokitto 46:e7e438368e16 97 CLR_CS; // select lcd
Pokitto 46:e7e438368e16 98 CLR_CD; // clear CD = command
Pokitto 46:e7e438368e16 99 SET_RD; // RD high, do not read
Pokitto 46:e7e438368e16 100 setup_data_16(data); // function that inputs the data into the relevant bus lines
Pokitto 46:e7e438368e16 101 CLR_WR_SLOW; // WR low
Pokitto 46:e7e438368e16 102 SET_WR; // WR low, then high = write strobe
Pokitto 46:e7e438368e16 103 SET_CS; // de-select lcd
Pokitto 46:e7e438368e16 104 }
Pokitto 46:e7e438368e16 105
Pokitto 46:e7e438368e16 106 /**************************************************************************/
Pokitto 46:e7e438368e16 107 /*!
Pokitto 46:e7e438368e16 108 @brief Write data to the lcd, 16-bit bus
Pokitto 46:e7e438368e16 109 */
Pokitto 46:e7e438368e16 110 /**************************************************************************/
Pokitto 46:e7e438368e16 111 inline void write_data_16(uint16_t data)
Pokitto 46:e7e438368e16 112 {
Pokitto 46:e7e438368e16 113 CLR_CS;
Pokitto 46:e7e438368e16 114 SET_CD;
Pokitto 46:e7e438368e16 115 SET_RD;
Pokitto 46:e7e438368e16 116 setup_data_16(data);
Pokitto 46:e7e438368e16 117 CLR_WR;
Pokitto 46:e7e438368e16 118 SET_WR;
Pokitto 46:e7e438368e16 119 SET_CS;
Pokitto 46:e7e438368e16 120 }
Pokitto 46:e7e438368e16 121
Pokitto 46:e7e438368e16 122 /**************************************************************************/
Pokitto 46:e7e438368e16 123 /*!
Pokitto 46:e7e438368e16 124 @brief Pump data to the lcd, 16-bit bus, public function
Pokitto 46:e7e438368e16 125 */
Pokitto 46:e7e438368e16 126 /**************************************************************************/
Pokitto 46:e7e438368e16 127 void Pokitto::pumpDRAMdata(uint16_t* data,uint16_t counter)
Pokitto 46:e7e438368e16 128 {
Pokitto 46:e7e438368e16 129 while (counter--) {
Pokitto 46:e7e438368e16 130 CLR_CS;
Pokitto 46:e7e438368e16 131 SET_CD;
Pokitto 46:e7e438368e16 132 SET_RD;
Pokitto 46:e7e438368e16 133 setup_data_16(*data++);
Pokitto 46:e7e438368e16 134 CLR_WR;
Pokitto 46:e7e438368e16 135 SET_WR;
Pokitto 46:e7e438368e16 136 SET_CS;
Pokitto 46:e7e438368e16 137 }
Pokitto 46:e7e438368e16 138 }
Pokitto 46:e7e438368e16 139
Pokitto 46:e7e438368e16 140
Pokitto 46:e7e438368e16 141 /**************************************************************************/
Pokitto 46:e7e438368e16 142 /*!
Pokitto 46:e7e438368e16 143 @brief Point to a (x,y) location in the LCD DRAM
Pokitto 46:e7e438368e16 144 */
Pokitto 46:e7e438368e16 145 /**************************************************************************/
Pokitto 46:e7e438368e16 146 static inline void setDRAMptr(uint8_t xptr, uint8_t yoffset)
Pokitto 46:e7e438368e16 147 {
Pokitto 46:e7e438368e16 148 write_command(0x20); // Vertical DRAM Address
Pokitto 46:e7e438368e16 149 write_data(yoffset);
Pokitto 46:e7e438368e16 150 write_command(0x21); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 151 write_data(xptr); //
Pokitto 46:e7e438368e16 152 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 153 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 154 }
Pokitto 46:e7e438368e16 155
Pokitto 46:e7e438368e16 156 /**************************************************************************/
Pokitto 46:e7e438368e16 157 /*!
Pokitto 46:e7e438368e16 158 @brief Point to a (x,y) location in the LCD DRAM, public function
Pokitto 46:e7e438368e16 159 */
Pokitto 46:e7e438368e16 160 /**************************************************************************/
Pokitto 46:e7e438368e16 161 void Pokitto::setDRAMpoint(uint8_t xptr, uint8_t yoffset)
Pokitto 46:e7e438368e16 162 {
Pokitto 46:e7e438368e16 163 write_command(0x20); // Vertical DRAM Address
Pokitto 46:e7e438368e16 164 write_data(yoffset);
Pokitto 46:e7e438368e16 165 write_command(0x21); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 166 write_data(xptr); //
Pokitto 46:e7e438368e16 167 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 168 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 169 }
Pokitto 46:e7e438368e16 170
Pokitto 46:e7e438368e16 171 void Pokitto::initBacklight() {
Pokitto 46:e7e438368e16 172 #if POK_BOARDREV == 2
Pokitto 46:e7e438368e16 173 pwmout_init(&backlightpwm,POK_BACKLIGHT_PIN);
Pokitto 46:e7e438368e16 174 pwmout_period_us(&backlightpwm,5);
Pokitto 46:e7e438368e16 175 pwmout_write(&backlightpwm,POK_BACKLIGHT_INITIALVALUE);
Pokitto 46:e7e438368e16 176 #endif
Pokitto 46:e7e438368e16 177 }
Pokitto 46:e7e438368e16 178
Pokitto 46:e7e438368e16 179 void Pokitto::setBacklight(float value) {
Pokitto 46:e7e438368e16 180 if (value>0.999f) value = 0.999f;
Pokitto 46:e7e438368e16 181 pwmout_write(&backlightpwm,value);
Pokitto 46:e7e438368e16 182 }
Pokitto 46:e7e438368e16 183
Pokitto 46:e7e438368e16 184 void Pokitto::lcdInit() {
Pokitto 46:e7e438368e16 185 initBacklight();
Pokitto 46:e7e438368e16 186
Pokitto 46:e7e438368e16 187 SET_RESET;
Pokitto 46:e7e438368e16 188 wait_ms(10);
Pokitto 46:e7e438368e16 189 CLR_RESET;
Pokitto 46:e7e438368e16 190 wait_ms(10);
Pokitto 46:e7e438368e16 191 SET_RESET;
Pokitto 46:e7e438368e16 192 wait_ms(10);
Pokitto 46:e7e438368e16 193 //************* Start Initial Sequence **********//
Pokitto 46:e7e438368e16 194 write_command(0x01); // driver output control, this also affects direction
Pokitto 46:e7e438368e16 195 write_data(0x11C); // originally: 0x11C 100011100 SS,NL4,NL3,NL2
Pokitto 46:e7e438368e16 196 // NL4...0 is the number of scan lines to drive the screen !!!
Pokitto 46:e7e438368e16 197 // so 11100 is 1c = 220 lines, correct
Pokitto 46:e7e438368e16 198 // test 1: 0x1C 11100 SS=0,NL4,NL3,NL2 -> no effect
Pokitto 46:e7e438368e16 199 // test 2: 0x31C 1100011100 GS=1,SS=1,NL4,NL3,NL2 -> no effect
Pokitto 46:e7e438368e16 200 // test 3: 0x51C 10100011100 SM=1,GS=0,SS=1,NL4,NL3,NL2 -> no effect
Pokitto 46:e7e438368e16 201 // test 4: 0x71C SM=1,GS=1,SS=1,NL4,NL3,NL2
Pokitto 46:e7e438368e16 202 // test 5: 0x
Pokitto 46:e7e438368e16 203 // seems to have no effect... is this perhaps only for RGB mode ?
Pokitto 46:e7e438368e16 204
Pokitto 46:e7e438368e16 205 write_command(0x02); // LCD driving control
Pokitto 46:e7e438368e16 206 write_data(0x0100); // INV = 1
Pokitto 46:e7e438368e16 207
Pokitto 46:e7e438368e16 208 write_command(0x03); // Entry mode... lets try if this affects the direction
Pokitto 46:e7e438368e16 209 write_data(0x1030); // originally 0x1030 1000000110000 BGR,ID1,ID0
Pokitto 46:e7e438368e16 210 // test 1: 0x1038 1000000111000 BGR,ID1,ID0,AM=1 ->drawing DRAM horizontally
Pokitto 46:e7e438368e16 211 // test 4: am=1, id0=0, id1=0, 1000000001000,0x1008 -> same as above, but flipped on long
Pokitto 46:e7e438368e16 212 // test 2: am=0, id0=0, 1000000100000, 0x1020 -> flipped on long axis
Pokitto 46:e7e438368e16 213 // test 3: am=0, id1=0, 1000000010000, 0x1010 -> picture flowed over back to screen
Pokitto 46:e7e438368e16 214
Pokitto 46:e7e438368e16 215
Pokitto 46:e7e438368e16 216 write_command(0x08); // Display control 2
Pokitto 46:e7e438368e16 217 write_data(0x0808); // 100000001000 FP2,BP2
Pokitto 46:e7e438368e16 218
Pokitto 46:e7e438368e16 219 write_command(0x0C); // RGB display interface
Pokitto 46:e7e438368e16 220 write_data(0x0000); // all off
Pokitto 46:e7e438368e16 221
Pokitto 46:e7e438368e16 222 write_command(0x0F); // Frame marker position
Pokitto 46:e7e438368e16 223 write_data(0x0001); // OSC_EN
Pokitto 46:e7e438368e16 224
Pokitto 46:e7e438368e16 225 write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 226 write_data(0x0000); // 0
Pokitto 46:e7e438368e16 227
Pokitto 46:e7e438368e16 228 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 229 write_data(0x0000); // 0
Pokitto 46:e7e438368e16 230
Pokitto 46:e7e438368e16 231 //*************Power On sequence ****************//
Pokitto 46:e7e438368e16 232 write_command(0x10);
Pokitto 46:e7e438368e16 233 write_data(0x0000);
Pokitto 46:e7e438368e16 234
Pokitto 46:e7e438368e16 235 write_command(0x11);
Pokitto 46:e7e438368e16 236 write_data(0x1000);
Pokitto 46:e7e438368e16 237 wait_ms(10);
Pokitto 46:e7e438368e16 238 //------------------------ Set GRAM area --------------------------------//
Pokitto 46:e7e438368e16 239 write_command(0x30); // Gate scan position
Pokitto 46:e7e438368e16 240 write_data(0x0000); // if GS=0, 00h=G1, else 00h=G220
Pokitto 46:e7e438368e16 241
Pokitto 46:e7e438368e16 242 write_command(0x31); // Vertical scroll control
Pokitto 46:e7e438368e16 243 write_data(0x00DB); // scroll start line 11011011 = 219
Pokitto 46:e7e438368e16 244
Pokitto 46:e7e438368e16 245 write_command(0x32); // Vertical scroll control
Pokitto 46:e7e438368e16 246 write_data(0x0000); // scroll end line 0
Pokitto 46:e7e438368e16 247
Pokitto 46:e7e438368e16 248 write_command(0x33); // Vertical scroll control
Pokitto 46:e7e438368e16 249 write_data(0x0000); // 0=vertical scroll disabled
Pokitto 46:e7e438368e16 250
Pokitto 46:e7e438368e16 251 write_command(0x34); // Partial screen driving control
Pokitto 46:e7e438368e16 252 write_data(0x00DB); // db = full screen (end)
Pokitto 46:e7e438368e16 253
Pokitto 46:e7e438368e16 254 write_command(0x35); // partial screen
Pokitto 46:e7e438368e16 255 write_data(0x0000); // 0 = start
Pokitto 46:e7e438368e16 256
Pokitto 46:e7e438368e16 257 write_command(0x36); // Horizontal and vertical RAM position
Pokitto 46:e7e438368e16 258 write_data(0x00AF); //end address 175
Pokitto 46:e7e438368e16 259
Pokitto 46:e7e438368e16 260 write_command(0x37);
Pokitto 46:e7e438368e16 261 write_data(0x0000); // start address 0
Pokitto 46:e7e438368e16 262
Pokitto 46:e7e438368e16 263 write_command(0x38);
Pokitto 46:e7e438368e16 264 write_data(0x00DB); //end address 219
Pokitto 46:e7e438368e16 265
Pokitto 46:e7e438368e16 266 write_command(0x39); // start address 0
Pokitto 46:e7e438368e16 267 write_data(0x0000);
Pokitto 46:e7e438368e16 268 wait_ms(10);
Pokitto 46:e7e438368e16 269 write_command(0xff); // start gamma register control
Pokitto 46:e7e438368e16 270 write_data(0x0003);
Pokitto 46:e7e438368e16 271
Pokitto 46:e7e438368e16 272 // ----------- Adjust the Gamma Curve ----------//
Pokitto 46:e7e438368e16 273 write_command(0x50);
Pokitto 46:e7e438368e16 274 write_data(0x0203);
Pokitto 46:e7e438368e16 275
Pokitto 46:e7e438368e16 276 write_command(0x051);
Pokitto 46:e7e438368e16 277 write_data(0x0A09);
Pokitto 46:e7e438368e16 278
Pokitto 46:e7e438368e16 279 write_command(0x52);
Pokitto 46:e7e438368e16 280 write_data(0x0005);
Pokitto 46:e7e438368e16 281
Pokitto 46:e7e438368e16 282 write_command(0x53);
Pokitto 46:e7e438368e16 283 write_data(0x1021);
Pokitto 46:e7e438368e16 284
Pokitto 46:e7e438368e16 285 write_command(0x54);
Pokitto 46:e7e438368e16 286 write_data(0x0602);
Pokitto 46:e7e438368e16 287
Pokitto 46:e7e438368e16 288 write_command(0x55);
Pokitto 46:e7e438368e16 289 write_data(0x0003);
Pokitto 46:e7e438368e16 290
Pokitto 46:e7e438368e16 291 write_command(0x56);
Pokitto 46:e7e438368e16 292 write_data(0x0703);
Pokitto 46:e7e438368e16 293
Pokitto 46:e7e438368e16 294 write_command(0x57);
Pokitto 46:e7e438368e16 295 write_data(0x0507);
Pokitto 46:e7e438368e16 296
Pokitto 46:e7e438368e16 297 write_command(0x58);
Pokitto 46:e7e438368e16 298 write_data(0x1021);
Pokitto 46:e7e438368e16 299
Pokitto 46:e7e438368e16 300 write_command(0x59);
Pokitto 46:e7e438368e16 301 write_data(0x0703);
Pokitto 46:e7e438368e16 302
Pokitto 46:e7e438368e16 303 write_command(0xB0);
Pokitto 46:e7e438368e16 304 write_data(0x2501);
Pokitto 46:e7e438368e16 305
Pokitto 46:e7e438368e16 306 write_command(0xFF);
Pokitto 46:e7e438368e16 307 write_data(0x0000);
Pokitto 46:e7e438368e16 308
Pokitto 46:e7e438368e16 309 write_command(0x07);
Pokitto 46:e7e438368e16 310 write_data(0x1017);
Pokitto 46:e7e438368e16 311 wait_ms(200);
Pokitto 46:e7e438368e16 312 write_command(0x22);
Pokitto 46:e7e438368e16 313
Pokitto 46:e7e438368e16 314 lcdClear();
Pokitto 46:e7e438368e16 315 }
Pokitto 46:e7e438368e16 316
Pokitto 46:e7e438368e16 317 void Pokitto::lcdSleep(void){
Pokitto 46:e7e438368e16 318 write_command(0xFF);
Pokitto 46:e7e438368e16 319 write_data(0x0000);
Pokitto 46:e7e438368e16 320
Pokitto 46:e7e438368e16 321 write_command(0x07);
Pokitto 46:e7e438368e16 322 write_data(0x0000);
Pokitto 46:e7e438368e16 323 wait_ms(50);
Pokitto 46:e7e438368e16 324 write_command(0x10);// Enter Standby mode
Pokitto 46:e7e438368e16 325 write_data(0x0003);
Pokitto 46:e7e438368e16 326 wait_ms(200);
Pokitto 46:e7e438368e16 327
Pokitto 46:e7e438368e16 328 }
Pokitto 46:e7e438368e16 329
Pokitto 46:e7e438368e16 330 void Pokitto::lcdWakeUp (void){
Pokitto 46:e7e438368e16 331
Pokitto 46:e7e438368e16 332 wait_ms(200);
Pokitto 46:e7e438368e16 333 write_command(0xFF);
Pokitto 46:e7e438368e16 334 write_data(0x0000);
Pokitto 46:e7e438368e16 335
Pokitto 46:e7e438368e16 336 write_command(0x10);// Exit Sleep/ Standby mode
Pokitto 46:e7e438368e16 337 write_data(0x0000);
Pokitto 46:e7e438368e16 338 wait_ms(50);
Pokitto 46:e7e438368e16 339 write_command(0x07);
Pokitto 46:e7e438368e16 340 write_data(0x0117);
Pokitto 46:e7e438368e16 341 wait_ms(200);
Pokitto 46:e7e438368e16 342 }
Pokitto 46:e7e438368e16 343
Pokitto 46:e7e438368e16 344 void Pokitto::lcdFillSurface(uint16_t c) {
Pokitto 46:e7e438368e16 345 uint32_t i;
Pokitto 46:e7e438368e16 346 write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 347 write_data(0x0000); // 0
Pokitto 46:e7e438368e16 348 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 349 write_data(0);
Pokitto 46:e7e438368e16 350 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 351 setup_data_16(c);
Pokitto 46:e7e438368e16 352 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 353 for(i=0;i<220*176;i++)
Pokitto 46:e7e438368e16 354 {
Pokitto 46:e7e438368e16 355 CLR_WR;
Pokitto 46:e7e438368e16 356 SET_WR;
Pokitto 46:e7e438368e16 357 }
Pokitto 46:e7e438368e16 358 }
Pokitto 46:e7e438368e16 359
Pokitto 46:e7e438368e16 360 void Pokitto::lcdClear() {
Pokitto 46:e7e438368e16 361 uint32_t i;
Pokitto 46:e7e438368e16 362 write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 363 write_data(0x0000); // 0
Pokitto 46:e7e438368e16 364 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 365 write_data(0);
Pokitto 46:e7e438368e16 366 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 367 setup_data_16(0x0000);
Pokitto 46:e7e438368e16 368 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 369 for(i=0;i<220*176;i++)
Pokitto 46:e7e438368e16 370 {
Pokitto 46:e7e438368e16 371 CLR_WR;
Pokitto 46:e7e438368e16 372 SET_WR;
Pokitto 46:e7e438368e16 373 }
Pokitto 46:e7e438368e16 374 }
Pokitto 46:e7e438368e16 375
Pokitto 46:e7e438368e16 376 void Pokitto::lcdPixel(int16_t x, int16_t y, uint16_t color) {
Pokitto 46:e7e438368e16 377 if ((x < 0) || (x >= POK_LCD_W) || (y < 0) || (y >= POK_LCD_H))
Pokitto 46:e7e438368e16 378 return;
Pokitto 46:e7e438368e16 379 write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 380 write_data(y); // 0
Pokitto 46:e7e438368e16 381 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 382 write_data(x);
Pokitto 46:e7e438368e16 383 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 384 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 385 setup_data_16(color);
Pokitto 46:e7e438368e16 386 CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 387 }
Pokitto 46:e7e438368e16 388
Pokitto 46:e7e438368e16 389 void Pokitto::setWindow(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
Pokitto 46:e7e438368e16 390 write_command(0x37); write_data(x1);
Pokitto 46:e7e438368e16 391 write_command(0x36); write_data(x2);
Pokitto 46:e7e438368e16 392 write_command(0x39); write_data(y1);
Pokitto 46:e7e438368e16 393 write_command(0x38); write_data(y2);
Pokitto 46:e7e438368e16 394 write_command(0x20); write_data(x1);
Pokitto 46:e7e438368e16 395 write_command(0x21); write_data(y1);
Pokitto 46:e7e438368e16 396 }
Pokitto 46:e7e438368e16 397
Pokitto 46:e7e438368e16 398 void Pokitto::lcdTile(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t* gfx){
Pokitto 46:e7e438368e16 399 int width=x1-x0;
Pokitto 46:e7e438368e16 400 int height=y1-y0;
Pokitto 46:e7e438368e16 401 if (x0 > POK_LCD_W) return;
Pokitto 46:e7e438368e16 402 if (y0 > POK_LCD_H) return;
Pokitto 46:e7e438368e16 403 if (x0 < 0) x0=0;
Pokitto 46:e7e438368e16 404 if (y0 < 0) y0=0;
Pokitto 46:e7e438368e16 405
Pokitto 46:e7e438368e16 406 setWindow(y0, x0, y1-1, x1-1);
Pokitto 46:e7e438368e16 407 write_command(0x22);
Pokitto 46:e7e438368e16 408
Pokitto 46:e7e438368e16 409 for (int x=0; x<=width*height-1;x++) {
Pokitto 46:e7e438368e16 410 write_data(gfx[x]);
Pokitto 46:e7e438368e16 411 }
Pokitto 46:e7e438368e16 412 setWindow(0, 0, 175, 219);
Pokitto 46:e7e438368e16 413 }
Pokitto 46:e7e438368e16 414
Pokitto 46:e7e438368e16 415
Pokitto 46:e7e438368e16 416 void Pokitto::lcdRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
Pokitto 46:e7e438368e16 417 int16_t temp;
Pokitto 46:e7e438368e16 418 if (x0>x1) {temp=x0;x0=x1;x1=temp;}
Pokitto 46:e7e438368e16 419 if (y0>y1) {temp=y0;y0=y1;y1=temp;}
Pokitto 46:e7e438368e16 420 if (x0 > POK_LCD_W) return;
Pokitto 46:e7e438368e16 421 if (y0 > POK_LCD_H) return;
Pokitto 46:e7e438368e16 422 if (x1 > POK_LCD_W) x1=POK_LCD_W;
Pokitto 46:e7e438368e16 423 if (y1 > POK_LCD_H) y1=POK_LCD_H;
Pokitto 46:e7e438368e16 424 if (x0 < 0) x0=0;
Pokitto 46:e7e438368e16 425 if (y0 < 0) y0=0;
Pokitto 46:e7e438368e16 426
Pokitto 46:e7e438368e16 427 int16_t x,y;
Pokitto 46:e7e438368e16 428 for (x=x0; x<=x1;x++) {
Pokitto 46:e7e438368e16 429 write_command(0x20); // Horizontal DRAM Address (=y on pokitto screen)
Pokitto 46:e7e438368e16 430 write_data(y0);
Pokitto 46:e7e438368e16 431 write_command(0x21); // Vertical DRAM Address (=x on pokitto screen)
Pokitto 46:e7e438368e16 432 write_data(x);
Pokitto 46:e7e438368e16 433 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 434
Pokitto 46:e7e438368e16 435 CLR_CS_SET_CD_RD_WR; // go to vram write mode
Pokitto 46:e7e438368e16 436
Pokitto 46:e7e438368e16 437
Pokitto 46:e7e438368e16 438 for (y=y0; y<y1;y++) {
Pokitto 46:e7e438368e16 439 setup_data_16(color); // setup the data (flat color = no change between pixels)
Pokitto 46:e7e438368e16 440 CLR_WR;SET_WR; //CLR_WR;SET_WR;//toggle writeline, pokitto screen writes a column up to down
Pokitto 46:e7e438368e16 441 }
Pokitto 46:e7e438368e16 442 }
Pokitto 46:e7e438368e16 443 }
Pokitto 46:e7e438368e16 444
Pokitto 46:e7e438368e16 445 /***
Pokitto 46:e7e438368e16 446 * Update the screen buffer of 220x176 pixels, 4 colors to LCD.
Pokitto 46:e7e438368e16 447 *
Pokitto 46:e7e438368e16 448 * The update rect is used for drawing only part of the screen buffer to LCD. Because of speed optimizations, the
Pokitto 46:e7e438368e16 449 * x, y, and width of the update rect must be dividable by 4 pixels, and the height must be dividable by 8 pixels.
Pokitto 46:e7e438368e16 450 * Note: The update rect is currently used for 220x176, 4 colors, screen mode only.
Pokitto 46:e7e438368e16 451 * @param scrbuf The screen buffer.
Pokitto 46:e7e438368e16 452 * @param updRectX The update rect.
Pokitto 46:e7e438368e16 453 * @param updRectY The update rect.
Pokitto 46:e7e438368e16 454 * @param updRectW The update rect.
Pokitto 46:e7e438368e16 455 * @param updRectH The update rect.
Pokitto 46:e7e438368e16 456 * @param paletteptr The screen palette.
Pokitto 46:e7e438368e16 457 */
Pokitto 65:deed4aa606fb 458
Pokitto 65:deed4aa606fb 459
Pokitto 65:deed4aa606fb 460 #define MODE1_LOOP \
Pokitto 65:deed4aa606fb 461 " adds %[t], %[palette]" "\n" \
Pokitto 65:deed4aa606fb 462 " ldm %[t], {%[t], %[x]}" "\n" \
Pokitto 65:deed4aa606fb 463 " str %[t], [%[LCD], 0]" "\n" \
Pokitto 65:deed4aa606fb 464 " movs %[t], 252" "\n" \
Pokitto 65:deed4aa606fb 465 " str %[WRBit], [%[LCD], %[t]]" "\n" \
Pokitto 65:deed4aa606fb 466 " str %[WRBit], [%[LCD], 124]" "\n" \
Pokitto 65:deed4aa606fb 467 " str %[x], [%[LCD], 0]" "\n" \
Pokitto 65:deed4aa606fb 468 " str %[WRBit], [%[LCD], %[t]]" "\n" \
Pokitto 65:deed4aa606fb 469 " movs %[t], 0x0F" "\n" \
Pokitto 65:deed4aa606fb 470 " ands %[t], %[t], %[c]" "\n" \
Pokitto 65:deed4aa606fb 471 " str %[WRBit], [%[LCD], 124]" "\n" \
Pokitto 65:deed4aa606fb 472 \
Pokitto 65:deed4aa606fb 473 " lsls %[t], 3" "\n" \
Pokitto 65:deed4aa606fb 474 " adds %[t], %[palette]" "\n" \
Pokitto 65:deed4aa606fb 475 " ldm %[t], {%[t], %[x]}" "\n" \
Pokitto 65:deed4aa606fb 476 " str %[t], [%[LCD], 0]" "\n" \
Pokitto 65:deed4aa606fb 477 " movs %[t], 252" "\n" \
Pokitto 65:deed4aa606fb 478 " str %[WRBit], [%[LCD], %[t]]" "\n" \
Pokitto 65:deed4aa606fb 479 " str %[WRBit], [%[LCD], 124]" "\n" \
Pokitto 65:deed4aa606fb 480 " str %[x], [%[LCD], 0]" "\n" \
Pokitto 65:deed4aa606fb 481 " str %[WRBit], [%[LCD], %[t]]" "\n" \
Pokitto 65:deed4aa606fb 482 " lsrs %[c], 8" "\n" \
Pokitto 65:deed4aa606fb 483 " movs %[t], 0xF0" "\n" \
Pokitto 65:deed4aa606fb 484 " ands %[t], %[t], %[c]" "\n" \
Pokitto 65:deed4aa606fb 485 " lsrs %[t], %[t], 1" "\n" \
Pokitto 65:deed4aa606fb 486 " str %[WRBit], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 487
Pokitto 65:deed4aa606fb 488
Pokitto 46:e7e438368e16 489 void Pokitto::lcdRefreshMode1(uint8_t * scrbuf, uint8_t updRectX, uint8_t updRectY, uint8_t updRectW, uint8_t updRectH, uint16_t* paletteptr) {
Pokitto 46:e7e438368e16 490
Pokitto 65:deed4aa606fb 491
Pokitto 65:deed4aa606fb 492 #ifdef XPERIMENTAL
Pokitto 65:deed4aa606fb 493 //#define __ARMCC_VERSION 1
Pokitto 65:deed4aa606fb 494 #endif
Pokitto 65:deed4aa606fb 495
Pokitto 65:deed4aa606fb 496 #ifndef __ARMCC_VERSION
Pokitto 65:deed4aa606fb 497
Pokitto 65:deed4aa606fb 498 write_command(0x03); write_data(0x1038);
Pokitto 65:deed4aa606fb 499 write_command(0x20); // Horizontal DRAM Address
Pokitto 65:deed4aa606fb 500 write_data(0);
Pokitto 65:deed4aa606fb 501 write_command(0x21); // Vertical DRAM Address
Pokitto 65:deed4aa606fb 502 write_data(0);
Pokitto 65:deed4aa606fb 503 write_command(0x22); // write data to DRAM
Pokitto 65:deed4aa606fb 504 CLR_CS_SET_CD_RD_WR;
Pokitto 65:deed4aa606fb 505
Pokitto 65:deed4aa606fb 506 uint8_t *end=&scrbuf[POK_SCREENBUFFERSIZE>>1]+4;
Pokitto 65:deed4aa606fb 507
Pokitto 65:deed4aa606fb 508 volatile uint32_t palette[32];
Pokitto 65:deed4aa606fb 509 for( uint32_t i=0; i<16; ++i ){
Pokitto 65:deed4aa606fb 510 palette[(i<<1)+1] = static_cast<uint32_t>(paletteptr[i&3 ]) << 3;
Pokitto 65:deed4aa606fb 511 palette[(i<<1) ] = static_cast<uint32_t>(paletteptr[i>>2]) << 3;
Pokitto 65:deed4aa606fb 512 }
Pokitto 65:deed4aa606fb 513
Pokitto 65:deed4aa606fb 514 SET_MASK_P2;
Pokitto 65:deed4aa606fb 515
Pokitto 65:deed4aa606fb 516 uint32_t c, WRBit = 1<<12;
Pokitto 65:deed4aa606fb 517
Pokitto 65:deed4aa606fb 518 register uint32_t x asm("r2");
Pokitto 65:deed4aa606fb 519 register uint32_t t asm("r1");
Pokitto 65:deed4aa606fb 520
Pokitto 65:deed4aa606fb 521 asm volatile(
Pokitto 65:deed4aa606fb 522
Pokitto 65:deed4aa606fb 523 ".syntax unified" "\n"
Pokitto 65:deed4aa606fb 524 "ldm %[scrbuf]!, {%[c]}" "\n" // load 4 bytes (16 pixels)
Pokitto 65:deed4aa606fb 525 "movs %[t], 0xF0" "\n"
Pokitto 65:deed4aa606fb 526 "ands %[t], %[t], %[c]" "\n"
Pokitto 65:deed4aa606fb 527 "lsrs %[t], %[t], 1" "\n"
Pokitto 65:deed4aa606fb 528 "mode1Loop%=:" "\n"
Pokitto 65:deed4aa606fb 529 MODE1_LOOP
Pokitto 65:deed4aa606fb 530 MODE1_LOOP
Pokitto 65:deed4aa606fb 531 MODE1_LOOP
Pokitto 65:deed4aa606fb 532 " adds %[t], %[palette]" "\n"
Pokitto 65:deed4aa606fb 533 " ldm %[t], {%[t], %[x]}" "\n"
Pokitto 65:deed4aa606fb 534 " str %[t], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 535 " movs %[t], 252" "\n"
Pokitto 65:deed4aa606fb 536 " str %[WRBit], [%[LCD], %[t]]" "\n"
Pokitto 65:deed4aa606fb 537 " str %[WRBit], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 538 " str %[x], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 539 " str %[WRBit], [%[LCD], %[t]]" "\n"
Pokitto 65:deed4aa606fb 540 " movs %[t], 0x0F" "\n"
Pokitto 65:deed4aa606fb 541 " ands %[t], %[t], %[c]" "\n"
Pokitto 65:deed4aa606fb 542 " str %[WRBit], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 543
Pokitto 65:deed4aa606fb 544 " lsls %[t], 3" "\n"
Pokitto 65:deed4aa606fb 545 " adds %[t], %[palette]" "\n"
Pokitto 65:deed4aa606fb 546 " ldm %[t], {%[t], %[x]}" "\n"
Pokitto 65:deed4aa606fb 547 " str %[t], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 548 " movs %[t], 252" "\n"
Pokitto 65:deed4aa606fb 549 " str %[WRBit], [%[LCD], %[t]]" "\n"
Pokitto 65:deed4aa606fb 550 " str %[WRBit], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 551 " str %[x], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 552 " str %[WRBit], [%[LCD], %[t]]" "\n"
Pokitto 65:deed4aa606fb 553
Pokitto 65:deed4aa606fb 554 " ldm %[scrbuf]!, {%[c]}" "\n" // load next 4 bytes
Pokitto 65:deed4aa606fb 555 " movs %[t], 0xF0" "\n"
Pokitto 65:deed4aa606fb 556 " ands %[t], %[t], %[c]" "\n"
Pokitto 65:deed4aa606fb 557 " lsrs %[t], %[t], 1" "\n"
Pokitto 65:deed4aa606fb 558 " str %[WRBit], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 559
Pokitto 65:deed4aa606fb 560 "cmp %[end], %[scrbuf]" "\n"
Pokitto 65:deed4aa606fb 561 "bne mode1Loop%=" "\n" // if scrbuf < end, loop
Pokitto 65:deed4aa606fb 562
Pokitto 65:deed4aa606fb 563 : // outputs
Pokitto 65:deed4aa606fb 564 [c]"+l" (c),
Pokitto 65:deed4aa606fb 565 [t]"+l" (t),
Pokitto 65:deed4aa606fb 566 [end]"+h" (end),
Pokitto 65:deed4aa606fb 567 [scrbuf]"+l" (scrbuf),
Pokitto 65:deed4aa606fb 568 [WRBit]"+l" (WRBit),
Pokitto 65:deed4aa606fb 569 [x]"+l" (x)
Pokitto 65:deed4aa606fb 570
Pokitto 65:deed4aa606fb 571 : // inputs
Pokitto 65:deed4aa606fb 572 [LCD]"l" (0xA0002188),
Pokitto 65:deed4aa606fb 573 [palette]"l" (palette)
Pokitto 65:deed4aa606fb 574
Pokitto 65:deed4aa606fb 575 : // clobbers
Pokitto 65:deed4aa606fb 576 "cc"
Pokitto 65:deed4aa606fb 577 );
Pokitto 65:deed4aa606fb 578
Pokitto 65:deed4aa606fb 579
Pokitto 65:deed4aa606fb 580 #else
Pokitto 65:deed4aa606fb 581 uint16_t x,y,xptr;
Pokitto 46:e7e438368e16 582 uint16_t scanline[4][176]; // read 4 half-nibbles = 4 pixels at a time
Pokitto 65:deed4aa606fb 583 uint8_t *d, yoffset=0;
Pokitto 46:e7e438368e16 584
Pokitto 46:e7e438368e16 585 // If not the full screen is updated, check the validity of the update rect.
Pokitto 46:e7e438368e16 586 if ( updRectX != 0 || updRectY != 0 ||updRectW != LCDWIDTH ||updRectH != LCDHEIGHT ) {
Pokitto 46:e7e438368e16 587 uint8_t org_screenx = updRectX;
Pokitto 46:e7e438368e16 588 updRectX &= 0xfc; // Make the value dividable by 4.
Pokitto 46:e7e438368e16 589 updRectW += org_screenx - updRectX;
Pokitto 46:e7e438368e16 590 updRectW = (updRectW + 3) & 0xfc; // Make the value dividable by 4, round up.
Pokitto 46:e7e438368e16 591
Pokitto 46:e7e438368e16 592 uint8_t org_screeny = updRectY;
Pokitto 46:e7e438368e16 593 updRectY &= 0xfc; // Make the value dividable by 4.
Pokitto 46:e7e438368e16 594 updRectH += org_screeny - updRectY;
Pokitto 46:e7e438368e16 595 updRectH = (updRectH + 7) & 0xf8; // Make the value dividable by 8 (because of loop unroll optimization), round up.
Pokitto 46:e7e438368e16 596 }
Pokitto 46:e7e438368e16 597
Pokitto 46:e7e438368e16 598
Pokitto 46:e7e438368e16 599 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 600 xptr = 8;
Pokitto 46:e7e438368e16 601 setDRAMptr(8, 0);
Pokitto 46:e7e438368e16 602 #else
Pokitto 65:deed4aa606fb 603 xptr = 0;
Pokitto 46:e7e438368e16 604 setDRAMptr(0, 0);
Pokitto 46:e7e438368e16 605 #endif
Pokitto 46:e7e438368e16 606
Pokitto 46:e7e438368e16 607 for (x=updRectX; x<updRectX+updRectW; x+=4) {
Pokitto 46:e7e438368e16 608 d = scrbuf+(x>>2);// point to beginning of line in data
Pokitto 46:e7e438368e16 609
Pokitto 46:e7e438368e16 610 /** find colours in one scanline **/
Pokitto 65:deed4aa606fb 611 uint8_t s=0;
Pokitto 46:e7e438368e16 612 d += (updRectY * 220/4);
Pokitto 46:e7e438368e16 613 for (y=updRectY; y<updRectY+updRectH; y++) {
Pokitto 46:e7e438368e16 614 uint8_t tdata = *d;
Pokitto 46:e7e438368e16 615 uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
Pokitto 46:e7e438368e16 616 uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
Pokitto 46:e7e438368e16 617 uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
Pokitto 46:e7e438368e16 618 uint8_t t = tdata & 0x03;// highest half-nibble
Pokitto 46:e7e438368e16 619
Pokitto 46:e7e438368e16 620 /** put nibble values in the scanlines **/
Pokitto 46:e7e438368e16 621 scanline[0][y] = paletteptr[t];
Pokitto 46:e7e438368e16 622 scanline[1][y] = paletteptr[t2];
Pokitto 46:e7e438368e16 623 scanline[2][y] = paletteptr[t3];
Pokitto 46:e7e438368e16 624 scanline[3][y] = paletteptr[t4];
Pokitto 46:e7e438368e16 625
Pokitto 46:e7e438368e16 626 d += 220/4; // jump to read byte directly below in screenbuffer
Pokitto 46:e7e438368e16 627 }
Pokitto 46:e7e438368e16 628
Pokitto 46:e7e438368e16 629 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 630 if (x>=8 ) {
Pokitto 46:e7e438368e16 631 #else
Pokitto 46:e7e438368e16 632 {
Pokitto 46:e7e438368e16 633
Pokitto 46:e7e438368e16 634 #endif
Pokitto 46:e7e438368e16 635
Pokitto 46:e7e438368e16 636 // Draw 8 vertical pixels at a time for performance reasons
Pokitto 46:e7e438368e16 637 setDRAMptr(x, updRectY);
Pokitto 46:e7e438368e16 638 for (uint8_t s=updRectY; s<updRectY+updRectH;) {
Pokitto 46:e7e438368e16 639 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 640 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 641 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 642 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 643 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 644 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 645 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 646 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 647 }
Pokitto 46:e7e438368e16 648 setDRAMptr(x+1, updRectY);
Pokitto 46:e7e438368e16 649 for (uint8_t s=updRectY; s<updRectY+updRectH;) {
Pokitto 46:e7e438368e16 650 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 651 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 652 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 653 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 654 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 655 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 656 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 657 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 658 }
Pokitto 46:e7e438368e16 659 setDRAMptr(x+2, updRectY);
Pokitto 46:e7e438368e16 660 for (uint8_t s=updRectY; s<updRectY+updRectH;) {
Pokitto 46:e7e438368e16 661 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 662 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 663 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 664 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 665 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 666 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 667 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 668 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 669 }
Pokitto 46:e7e438368e16 670 setDRAMptr(x+3, updRectY);
Pokitto 46:e7e438368e16 671 for (uint8_t s=updRectY; s<updRectY+updRectH;) {
Pokitto 46:e7e438368e16 672 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 673 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 674 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 675 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 676 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 677 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 678 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 679 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 680 }
Pokitto 46:e7e438368e16 681 }
Pokitto 46:e7e438368e16 682 }
Pokitto 65:deed4aa606fb 683 #endif
Pokitto 46:e7e438368e16 684
Pokitto 46:e7e438368e16 685 #ifdef POK_SIM
Pokitto 46:e7e438368e16 686 simulator.refreshDisplay();
Pokitto 46:e7e438368e16 687 #endif
Pokitto 46:e7e438368e16 688 }
Pokitto 46:e7e438368e16 689
Pokitto 46:e7e438368e16 690 // Copy sprite pixels to the scanline
Pokitto 46:e7e438368e16 691 #define SPRITE_2BPP_INNER_LOOP(n)\
Pokitto 46:e7e438368e16 692 \
Pokitto 46:e7e438368e16 693 /* If the sprite is enabled and contained in this vertical scanline, copy 4 pixels. */\
Pokitto 46:e7e438368e16 694 if (sprScanlineAddr[(n)] &&\
Pokitto 46:e7e438368e16 695 y >= sprites[(n)].y && y < sprites[(n)].y + sprites[(n)].h ) {\
Pokitto 46:e7e438368e16 696 \
Pokitto 46:e7e438368e16 697 int16_t sprx = sprites[(n)].x;\
Pokitto 46:e7e438368e16 698 uint16_t s_data16b = 0; /* sprite data, 2 bytes */\
Pokitto 46:e7e438368e16 699 \
Pokitto 46:e7e438368e16 700 /* Get pixel block, 4 or 8 pixels horizontally. Use the predefined bitshift mode. */\
Pokitto 46:e7e438368e16 701 /* Note:it is cheapest to compare to 0 first. */\
Pokitto 46:e7e438368e16 702 if (sprScanlineBitshiftMode[(n)] == BITSHIFT_MODE_MIDDLE_BYTE) {\
Pokitto 46:e7e438368e16 703 s_data16b = *(sprScanlineAddr[(n)]);\
Pokitto 46:e7e438368e16 704 uint16_t leftByte = *(sprScanlineAddr[(n)]-1);\
Pokitto 46:e7e438368e16 705 s_data16b = (leftByte << 8) | s_data16b;\
Pokitto 46:e7e438368e16 706 }\
Pokitto 46:e7e438368e16 707 else if (sprScanlineBitshiftMode[(n)] == BITSHIFT_MODE_FIRST_BYTE) {\
Pokitto 46:e7e438368e16 708 s_data16b = *(sprScanlineAddr[(n)]);\
Pokitto 46:e7e438368e16 709 }\
Pokitto 46:e7e438368e16 710 else { /* BITSHIFT_MODE_LAST_BYTE */\
Pokitto 46:e7e438368e16 711 uint16_t leftByte = *(sprScanlineAddr[(n)]-1);\
Pokitto 46:e7e438368e16 712 s_data16b = (leftByte << 8) | s_data16b;\
Pokitto 46:e7e438368e16 713 }\
Pokitto 46:e7e438368e16 714 \
Pokitto 46:e7e438368e16 715 /* Shift sprite pixels according to sprite x. After shifting we have only 4 pixels. */\
Pokitto 46:e7e438368e16 716 uint8_t shiftRight = (sprx&0x3) << 1;\
Pokitto 46:e7e438368e16 717 s_data16b = (s_data16b >> shiftRight);\
Pokitto 46:e7e438368e16 718 \
Pokitto 46:e7e438368e16 719 /* Get individual pixels */\
Pokitto 46:e7e438368e16 720 uint8_t s_t4 = s_data16b & 0x03; s_data16b >>= 2; /* lowest half-nibble */\
Pokitto 46:e7e438368e16 721 uint8_t s_t3 = s_data16b & 0x03; s_data16b >>= 2; /* second lowest half-nibble */\
Pokitto 46:e7e438368e16 722 uint8_t s_t2 = s_data16b & 0x03; s_data16b >>= 2; /* second highest half-nibble */\
Pokitto 46:e7e438368e16 723 uint8_t s_t1 = s_data16b & 0x03; /* highest half-nibble */\
Pokitto 46:e7e438368e16 724 \
Pokitto 46:e7e438368e16 725 /* Store pixels as 16-bit colors from the palette */\
Pokitto 46:e7e438368e16 726 if (s_t4 != transparentColor) p4 = sprites[(n)].palette[s_t4];\
Pokitto 46:e7e438368e16 727 if (s_t3 != transparentColor) p3 = sprites[(n)].palette[s_t3];\
Pokitto 46:e7e438368e16 728 if (s_t2 != transparentColor) p2 = sprites[(n)].palette[s_t2];\
Pokitto 46:e7e438368e16 729 if (s_t1 != transparentColor) p = sprites[(n)].palette[s_t1];\
Pokitto 46:e7e438368e16 730 \
Pokitto 46:e7e438368e16 731 /* Advance scanline address */\
Pokitto 46:e7e438368e16 732 sprScanlineAddr[(n)] += (sprites[(n)].w >> 2);\
Pokitto 46:e7e438368e16 733 }
Pokitto 46:e7e438368e16 734
Pokitto 46:e7e438368e16 735 // Loop unrolling macros
Pokitto 46:e7e438368e16 736 #define UNROLLED_LOOP_1() SPRITE_2BPP_INNER_LOOP(0)
Pokitto 46:e7e438368e16 737 #define UNROLLED_LOOP_2() UNROLLED_LOOP_1() SPRITE_2BPP_INNER_LOOP(1)
Pokitto 46:e7e438368e16 738 #define UNROLLED_LOOP_3() UNROLLED_LOOP_2() SPRITE_2BPP_INNER_LOOP(2)
Pokitto 46:e7e438368e16 739 #define UNROLLED_LOOP_4() UNROLLED_LOOP_3() SPRITE_2BPP_INNER_LOOP(3)
Pokitto 46:e7e438368e16 740 #define UNROLLED_LOOP_5() UNROLLED_LOOP_4() SPRITE_2BPP_INNER_LOOP(4)
Pokitto 46:e7e438368e16 741 #define UNROLLED_LOOP_6() UNROLLED_LOOP_5() SPRITE_2BPP_INNER_LOOP(5)
Pokitto 46:e7e438368e16 742 #define UNROLLED_LOOP_7() UNROLLED_LOOP_6() SPRITE_2BPP_INNER_LOOP(6)
Pokitto 46:e7e438368e16 743 #define UNROLLED_LOOP_8() UNROLLED_LOOP_7() SPRITE_2BPP_INNER_LOOP(7)
Pokitto 46:e7e438368e16 744 #define UNROLLED_LOOP_9() UNROLLED_LOOP_8() SPRITE_2BPP_INNER_LOOP(8)
Pokitto 46:e7e438368e16 745 #define UNROLLED_LOOP_10() UNROLLED_LOOP_9() SPRITE_2BPP_INNER_LOOP(9)
Pokitto 46:e7e438368e16 746 #define UNROLLED_LOOP_11() UNROLLED_LOOP_10() SPRITE_2BPP_INNER_LOOP(10)
Pokitto 46:e7e438368e16 747 #define UNROLLED_LOOP_12() UNROLLED_LOOP_11() SPRITE_2BPP_INNER_LOOP(11)
Pokitto 46:e7e438368e16 748 #define UNROLLED_LOOP_13() UNROLLED_LOOP_12() SPRITE_2BPP_INNER_LOOP(12)
Pokitto 46:e7e438368e16 749 #define UNROLLED_LOOP_14() UNROLLED_LOOP_13() SPRITE_2BPP_INNER_LOOP(13)
Pokitto 46:e7e438368e16 750 #define UNROLLED_LOOP_15() UNROLLED_LOOP_14() SPRITE_2BPP_INNER_LOOP(14)
Pokitto 46:e7e438368e16 751 #define UNROLLED_LOOP_16() UNROLLED_LOOP_15() SPRITE_2BPP_INNER_LOOP(15)
Pokitto 46:e7e438368e16 752 #define UNROLLED_LOOP_N_(n) UNROLLED_LOOP_##n()
Pokitto 46:e7e438368e16 753 #define UNROLLED_LOOP_N(n) UNROLLED_LOOP_N_(n)
Pokitto 46:e7e438368e16 754
Pokitto 46:e7e438368e16 755 /***
Pokitto 46:e7e438368e16 756 * Update the screen buffer of 220x176 pixels, 4 colors and free size 4 color sprites to LCD.
Pokitto 46:e7e438368e16 757 *
Pokitto 46:e7e438368e16 758 * The update rect is used for drawing only part of the screen buffer to LCD. Because of speed optimizations, the
Pokitto 46:e7e438368e16 759 * x, y, and width of the update rect must be dividable by 4 pixels, and the height must be dividable by 8 pixels.
Pokitto 46:e7e438368e16 760 * Note: The update rect is currently used for 220x176, 4 colors, screen mode only.
Pokitto 46:e7e438368e16 761 * If drawSpritesOnly=true, only sprites are fully updated to LCD. However, the dirty rect of the screen buffer is
Pokitto 46:e7e438368e16 762 * drawn behind the sprite current and previous location.
Pokitto 46:e7e438368e16 763 * Note: Sprite is enabled if sprite.bitmapData is not NULL. Also all enabled sprites must be at the beginning of
Pokitto 46:e7e438368e16 764 * the sprites array. No gaps are allowed in the array.
Pokitto 46:e7e438368e16 765 * @param scrbuf The screen buffer.
Pokitto 46:e7e438368e16 766 * @param updRectX The update rect.
Pokitto 46:e7e438368e16 767 * @param updRectY The update rect.
Pokitto 46:e7e438368e16 768 * @param updRectW The update rect.
Pokitto 46:e7e438368e16 769 * @param updRectH The update rect.
Pokitto 46:e7e438368e16 770 * @param paletteptr The screen palette.
Pokitto 46:e7e438368e16 771 * @param sprites The sprite array.
Pokitto 46:e7e438368e16 772 * @param drawSpritesOnly True, if only sprites are drawn. False, if both sprites and the screen buffer are drawn.
Pokitto 46:e7e438368e16 773 */
Pokitto 46:e7e438368e16 774 void Pokitto::lcdRefreshMode1Spr(
Pokitto 46:e7e438368e16 775 uint8_t * scrbuf, uint8_t updRectX, uint8_t updRectY, uint8_t updRectW, uint8_t updRectH, uint16_t* paletteptr,
Pokitto 46:e7e438368e16 776 SpriteInfo* sprites, bool drawSpritesOnly) {
Pokitto 46:e7e438368e16 777
Pokitto 46:e7e438368e16 778 // In direct mode draw only sprites and their dirty rects. Return now if there are no sprites
Pokitto 46:e7e438368e16 779 if (drawSpritesOnly && (sprites == NULL || sprites[0].bitmapData == NULL))
Pokitto 46:e7e438368e16 780 return;
Pokitto 46:e7e438368e16 781
Pokitto 46:e7e438368e16 782 uint16_t x,y;
Pokitto 46:e7e438368e16 783 uint16_t scanline[4][176]; // read 4 half-nibbles (= 4 pixels) at a time
Pokitto 46:e7e438368e16 784 const uint8_t transparentColor = 0; // fixed palette index 0 for transparency
Pokitto 46:e7e438368e16 785
Pokitto 46:e7e438368e16 786 // If not the full screen is updated, check the validity of the update rect.
Pokitto 46:e7e438368e16 787 if ( updRectX != 0 || updRectY != 0 ||updRectW != LCDWIDTH ||updRectH != LCDHEIGHT ) {
Pokitto 46:e7e438368e16 788 uint8_t org_screenx = updRectX;
Pokitto 46:e7e438368e16 789 updRectX &= 0xfc; // Make the value dividable by 4.
Pokitto 46:e7e438368e16 790 updRectW += org_screenx - updRectX;
Pokitto 46:e7e438368e16 791 updRectW = (updRectW + 3) & 0xfc; // Make the value dividable by 4, round up.
Pokitto 46:e7e438368e16 792
Pokitto 46:e7e438368e16 793 uint8_t org_screeny = updRectY;
Pokitto 46:e7e438368e16 794 updRectY &= 0xfc; // Make the value dividable by 4.
Pokitto 46:e7e438368e16 795 updRectH += org_screeny - updRectY;
Pokitto 46:e7e438368e16 796 updRectH = (updRectH + 7) & 0xf8; // Make the value dividable by 8 (because of loop unroll optimization), round up.
Pokitto 46:e7e438368e16 797 }
Pokitto 46:e7e438368e16 798
Pokitto 46:e7e438368e16 799 // Calculate the current amount of sprites
Pokitto 46:e7e438368e16 800 // Note: Sprites must be taken into use from index 0 upwards, because the first sprite with bitmapData==NULL is considered as the last sprite
Pokitto 46:e7e438368e16 801 uint8_t spriteCount = 0;
Pokitto 46:e7e438368e16 802 if (sprites != NULL)
Pokitto 46:e7e438368e16 803 for (;sprites[spriteCount].bitmapData != NULL && spriteCount < SPRITE_COUNT; spriteCount++);
Pokitto 46:e7e438368e16 804
Pokitto 46:e7e438368e16 805 // If drawing the screen buffer, set the start pos to LCD commands only here.
Pokitto 46:e7e438368e16 806 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 807 if (!drawSpritesOnly) setDRAMptr(8, 0);
Pokitto 46:e7e438368e16 808 #else
Pokitto 46:e7e438368e16 809 if (!drawSpritesOnly) setDRAMptr(0, 0);
Pokitto 46:e7e438368e16 810 #endif
Pokitto 46:e7e438368e16 811
Pokitto 46:e7e438368e16 812 //*** GO THROUGH EACH VERTICAL GROUP OF 4 SCANLINES.***
Pokitto 46:e7e438368e16 813
Pokitto 46:e7e438368e16 814 for (x=0; x<LCDWIDTH; x+=4) {
Pokitto 46:e7e438368e16 815
Pokitto 46:e7e438368e16 816 uint8_t *screenBufScanlineAddr = scrbuf + (x>>2);// point to beginning of line in data
Pokitto 46:e7e438368e16 817
Pokitto 46:e7e438368e16 818 /*Prepare scanline start address for sprites that are visible in this vertical scanline. Sprite width cannot exceed the screen width*/
Pokitto 46:e7e438368e16 819 uint8_t *sprScanlineAddr[SPRITE_COUNT]; // Sprite start address for the scanline
Pokitto 46:e7e438368e16 820 uint8_t sprScanlineBitshiftMode[SPRITE_COUNT]; // Sprite bitshift mode for the scanline
Pokitto 46:e7e438368e16 821 const uint8_t BITSHIFT_MODE_MIDDLE_BYTE = 0;
Pokitto 46:e7e438368e16 822 const uint8_t BITSHIFT_MODE_FIRST_BYTE = 1;
Pokitto 46:e7e438368e16 823 const uint8_t BITSHIFT_MODE_LAST_BYTE = 2;
Pokitto 46:e7e438368e16 824 uint8_t scanlineMinY = 255; // Init to uninitialized value. Do not draw by default.
Pokitto 46:e7e438368e16 825 uint8_t scanlineMaxY = 0; // Init to uninitialized value. Do not draw by default.
Pokitto 46:e7e438368e16 826
Pokitto 46:e7e438368e16 827 //*** CALCULATE DIRTY RECTS AND RESOLVE WHICH SPRITES BELONG TO THIS SCANLINE GROUP ***
Pokitto 46:e7e438368e16 828
Pokitto 46:e7e438368e16 829 if (sprites != NULL) {
Pokitto 46:e7e438368e16 830
Pokitto 46:e7e438368e16 831 // Check all the sprites for this scanline. That is used for handling the given update rect
Pokitto 46:e7e438368e16 832 // Note that the last round is when (sprindex == spriteCount). That is used to add the screen buffer
Pokitto 46:e7e438368e16 833 // update rect to the dirty rect.
Pokitto 46:e7e438368e16 834 for (int sprindex = 0; sprindex <= spriteCount; sprindex++) {
Pokitto 46:e7e438368e16 835
Pokitto 46:e7e438368e16 836 int16_t sprx, spry, sprOldX, sprOldY;
Pokitto 46:e7e438368e16 837 uint8_t sprw, sprh;
Pokitto 46:e7e438368e16 838 bool isCurrentSpriteOutOfScreen = false;
Pokitto 46:e7e438368e16 839 bool isOldSpriteOutOfScreen = false;
Pokitto 46:e7e438368e16 840
Pokitto 46:e7e438368e16 841 if (sprindex < spriteCount) {
Pokitto 46:e7e438368e16 842
Pokitto 46:e7e438368e16 843 sprx = sprites[sprindex].x;
Pokitto 46:e7e438368e16 844 spry = sprites[sprindex].y;
Pokitto 46:e7e438368e16 845 sprw = sprites[sprindex].w;
Pokitto 46:e7e438368e16 846 sprh = sprites[sprindex].h;
Pokitto 46:e7e438368e16 847 sprOldX = sprites[sprindex].oldx;
Pokitto 46:e7e438368e16 848 sprOldY = sprites[sprindex].oldy;
Pokitto 46:e7e438368e16 849 }
Pokitto 46:e7e438368e16 850
Pokitto 46:e7e438368e16 851 // Handle the screen buffer update rect after all sprites
Pokitto 46:e7e438368e16 852 else if(!drawSpritesOnly){
Pokitto 46:e7e438368e16 853
Pokitto 46:e7e438368e16 854 sprx = updRectX;
Pokitto 46:e7e438368e16 855 spry = updRectY;
Pokitto 46:e7e438368e16 856 sprw = updRectW;
Pokitto 46:e7e438368e16 857 sprh = updRectH;
Pokitto 46:e7e438368e16 858 sprOldX = updRectX;
Pokitto 46:e7e438368e16 859 sprOldY = updRectY;
Pokitto 46:e7e438368e16 860 isCurrentSpriteOutOfScreen = false;
Pokitto 46:e7e438368e16 861 isOldSpriteOutOfScreen = false;
Pokitto 46:e7e438368e16 862 }
Pokitto 46:e7e438368e16 863
Pokitto 46:e7e438368e16 864 // Check for out-of-screen
Pokitto 46:e7e438368e16 865 if (sprx >= LCDWIDTH || spry >= LCDHEIGHT)
Pokitto 46:e7e438368e16 866 isCurrentSpriteOutOfScreen = true;
Pokitto 46:e7e438368e16 867 if (sprOldX >= LCDWIDTH || sprOldY >= LCDHEIGHT)
Pokitto 46:e7e438368e16 868 isOldSpriteOutOfScreen = true;
Pokitto 46:e7e438368e16 869
Pokitto 46:e7e438368e16 870 // Skip if current and old sprites are out-of-screen
Pokitto 46:e7e438368e16 871 if (isCurrentSpriteOutOfScreen && isOldSpriteOutOfScreen)
Pokitto 46:e7e438368e16 872 continue;
Pokitto 46:e7e438368e16 873
Pokitto 46:e7e438368e16 874 // Detect the dirty rect x-span by combining the previous and current sprite position.
Pokitto 51:113b1d84c34f 875 int16_t sprDirtyXMin = avrmin(sprx, sprOldX);
Pokitto 51:113b1d84c34f 876 int16_t sprDirtyXMax = avrmax(sprx, sprOldX);
Pokitto 46:e7e438368e16 877 if (isCurrentSpriteOutOfScreen)
Pokitto 46:e7e438368e16 878 sprDirtyXMax = sprOldX;
Pokitto 46:e7e438368e16 879 if (isOldSpriteOutOfScreen)
Pokitto 46:e7e438368e16 880 sprDirtyXMax = sprx;
Pokitto 46:e7e438368e16 881
Pokitto 46:e7e438368e16 882 // Is current x inside the sprite combined dirty rect ?
Pokitto 46:e7e438368e16 883 int16_t sprDirtyXMaxEnd = sprDirtyXMax + sprw - 1 + 4; // Add 4 pixels to dirty rect width (needed?)
Pokitto 46:e7e438368e16 884 if (sprDirtyXMin <= x+3 && x <= sprDirtyXMaxEnd) {
Pokitto 46:e7e438368e16 885
Pokitto 46:e7e438368e16 886 // *** COMBINE DIRTY RECTS FOR THIS SCANLINE GROUP ***
Pokitto 46:e7e438368e16 887
Pokitto 46:e7e438368e16 888 // Dirty rect
Pokitto 51:113b1d84c34f 889 int sprDirtyYMin = avrmin(spry, sprOldY);
Pokitto 51:113b1d84c34f 890 sprDirtyYMin = avrmax((int)sprDirtyYMin, 0);
Pokitto 51:113b1d84c34f 891 int sprDirtyYMax = avrmax(spry, sprOldY);
Pokitto 46:e7e438368e16 892 if (isCurrentSpriteOutOfScreen)
Pokitto 46:e7e438368e16 893 sprDirtyYMax = sprOldY;
Pokitto 46:e7e438368e16 894 if (isOldSpriteOutOfScreen)
Pokitto 46:e7e438368e16 895 sprDirtyYMax = spry;
Pokitto 46:e7e438368e16 896 int sprDirtyYMaxEnd = sprDirtyYMax + sprh - 1;
Pokitto 51:113b1d84c34f 897 sprDirtyYMaxEnd = avrmin(sprDirtyYMaxEnd, LCDHEIGHT - 1); // Should use LCDHEIGHT instead of screenH? Same with other screen* ?
Pokitto 46:e7e438368e16 898
Pokitto 46:e7e438368e16 899 // Get the scanline min and max y values for drawing
Pokitto 46:e7e438368e16 900 if (sprDirtyYMin < scanlineMinY)
Pokitto 46:e7e438368e16 901 scanlineMinY = sprDirtyYMin;
Pokitto 46:e7e438368e16 902 if (sprDirtyYMaxEnd > scanlineMaxY)
Pokitto 46:e7e438368e16 903 scanlineMaxY = sprDirtyYMaxEnd;
Pokitto 46:e7e438368e16 904
Pokitto 46:e7e438368e16 905 // *** PREPARE SPRITE FOR DRAWING ***
Pokitto 46:e7e438368e16 906
Pokitto 46:e7e438368e16 907 // Check if the sprite should be active for this vertical scanline group.
Pokitto 46:e7e438368e16 908 if (sprindex < spriteCount && // not for update rect
Pokitto 46:e7e438368e16 909 !isCurrentSpriteOutOfScreen && //out-of-screen
Pokitto 46:e7e438368e16 910 sprx <= x+3 && x < sprx + sprw) { // note: cover group of 4 pixels of the scanline (x+3)
Pokitto 46:e7e438368e16 911
Pokitto 46:e7e438368e16 912 // Find the byte number in the sprite data
Pokitto 46:e7e438368e16 913 int16_t byteNum = ((x+3) - sprx)>>2;
Pokitto 46:e7e438368e16 914
Pokitto 46:e7e438368e16 915 // Get the start addres of the spite data in this scanline.
Pokitto 46:e7e438368e16 916 sprScanlineAddr[sprindex] = const_cast<uint8_t*>(sprites[sprindex].bitmapData + byteNum);
Pokitto 46:e7e438368e16 917
Pokitto 46:e7e438368e16 918 // If the sprite goes over the top, it must be clipped from the top.
Pokitto 46:e7e438368e16 919 if(spry < 0)
Pokitto 46:e7e438368e16 920 sprScanlineAddr[sprindex] += (-spry) * (sprw >> 2);
Pokitto 46:e7e438368e16 921
Pokitto 46:e7e438368e16 922 // Select the bitshift mode for the blit algorithm
Pokitto 46:e7e438368e16 923 if (byteNum == 0)
Pokitto 46:e7e438368e16 924 sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_FIRST_BYTE;
Pokitto 46:e7e438368e16 925 else if (byteNum >= (sprw >> 2))
Pokitto 46:e7e438368e16 926 sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_LAST_BYTE;
Pokitto 46:e7e438368e16 927 else
Pokitto 46:e7e438368e16 928 sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_MIDDLE_BYTE;
Pokitto 46:e7e438368e16 929 }
Pokitto 46:e7e438368e16 930 else
Pokitto 46:e7e438368e16 931 sprScanlineAddr[sprindex] = NULL; // Deactive sprite for this scanline
Pokitto 46:e7e438368e16 932 }
Pokitto 46:e7e438368e16 933 else
Pokitto 46:e7e438368e16 934 sprScanlineAddr[sprindex] = NULL; // Deactive sprite for this scanline
Pokitto 46:e7e438368e16 935 }
Pokitto 46:e7e438368e16 936 }
Pokitto 46:e7e438368e16 937
Pokitto 46:e7e438368e16 938 // *** ADJUST THE SCANLINE GROUP HEIGHT ***
Pokitto 46:e7e438368e16 939
Pokitto 46:e7e438368e16 940 // The height must dividable by 8. That is needed because later we copy 8 pixels at a time to the LCD.
Pokitto 46:e7e438368e16 941 if (scanlineMaxY - scanlineMinY + 1 > 0) {
Pokitto 46:e7e438368e16 942 uint8_t scanlineH = scanlineMaxY - scanlineMinY + 1;
Pokitto 46:e7e438368e16 943 uint8_t addW = 8 - (scanlineH & 0x7);
Pokitto 46:e7e438368e16 944
Pokitto 46:e7e438368e16 945 // if height is not dividable by 8, make it be.
Pokitto 46:e7e438368e16 946 if (addW != 0) {
Pokitto 46:e7e438368e16 947 if (scanlineMinY > addW )
Pokitto 46:e7e438368e16 948 scanlineMinY -= addW;
Pokitto 46:e7e438368e16 949 else if( scanlineMaxY + addW < updRectY+updRectH)
Pokitto 46:e7e438368e16 950 scanlineMaxY += addW;
Pokitto 46:e7e438368e16 951 else {
Pokitto 46:e7e438368e16 952 // Draw full height scanline
Pokitto 46:e7e438368e16 953 scanlineMinY = updRectY;
Pokitto 46:e7e438368e16 954 scanlineMaxY = updRectY+updRectH-1;
Pokitto 46:e7e438368e16 955 }
Pokitto 46:e7e438368e16 956 }
Pokitto 46:e7e438368e16 957 }
Pokitto 46:e7e438368e16 958
Pokitto 46:e7e438368e16 959 // *** COMBINE THE SCANLINE GROUP OF THE SCREEN BUFFER AND ALL SPRITES ***
Pokitto 46:e7e438368e16 960
Pokitto 46:e7e438368e16 961 // Find colours in this group of 4 scanlines
Pokitto 46:e7e438368e16 962 screenBufScanlineAddr += (scanlineMinY * 220/4);
Pokitto 46:e7e438368e16 963 for (y=scanlineMinY; y<=scanlineMaxY; y++)
Pokitto 46:e7e438368e16 964 {
Pokitto 46:e7e438368e16 965 // get the screen buffer data first
Pokitto 46:e7e438368e16 966 uint8_t tdata = *screenBufScanlineAddr;
Pokitto 46:e7e438368e16 967 uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
Pokitto 46:e7e438368e16 968 uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
Pokitto 46:e7e438368e16 969 uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
Pokitto 46:e7e438368e16 970 uint8_t t = tdata & 0x03;// highest half-nibble
Pokitto 46:e7e438368e16 971
Pokitto 46:e7e438368e16 972 // Convert to 16-bit colors in palette
Pokitto 46:e7e438368e16 973 uint16_t p = paletteptr[t];
Pokitto 46:e7e438368e16 974 uint16_t p2 = paletteptr[t2];
Pokitto 46:e7e438368e16 975 uint16_t p3 = paletteptr[t3];
Pokitto 46:e7e438368e16 976 uint16_t p4 = paletteptr[t4];
Pokitto 46:e7e438368e16 977
Pokitto 46:e7e438368e16 978 #if 0
Pokitto 46:e7e438368e16 979 // Dirty rect visual test
Pokitto 46:e7e438368e16 980 p = COLOR_BLUE >> (Core::frameCount % 5);
Pokitto 46:e7e438368e16 981 p2 = COLOR_BLUE >> (Core::frameCount % 5);
Pokitto 46:e7e438368e16 982 p3 = COLOR_BLUE >> (Core::frameCount % 5);
Pokitto 46:e7e438368e16 983 p4 = COLOR_BLUE >> (Core::frameCount % 5);
Pokitto 46:e7e438368e16 984 #endif
Pokitto 46:e7e438368e16 985
Pokitto 46:e7e438368e16 986 // Add active sprite pixels
Pokitto 46:e7e438368e16 987 if (sprites != NULL) {
Pokitto 46:e7e438368e16 988
Pokitto 46:e7e438368e16 989 // Use loop unrolling for speed optimization
Pokitto 46:e7e438368e16 990 UNROLLED_LOOP_N(SPRITE_COUNT)
Pokitto 46:e7e438368e16 991 }
Pokitto 46:e7e438368e16 992
Pokitto 46:e7e438368e16 993 // put the result nibble values in the scanline
Pokitto 46:e7e438368e16 994 scanline[0][y] = p;
Pokitto 46:e7e438368e16 995 scanline[1][y] = p2;
Pokitto 46:e7e438368e16 996 scanline[2][y] = p3;
Pokitto 46:e7e438368e16 997 scanline[3][y] = p4;
Pokitto 46:e7e438368e16 998
Pokitto 46:e7e438368e16 999 screenBufScanlineAddr += 220>>2; // jump to read byte directly below in screenbuffer
Pokitto 46:e7e438368e16 1000 }
Pokitto 46:e7e438368e16 1001
Pokitto 46:e7e438368e16 1002 // *** DRAW THE SCANLINE GROUP TO LCD
Pokitto 46:e7e438368e16 1003
Pokitto 46:e7e438368e16 1004 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 1005 if (x>=8 && scanlineMaxY - scanlineMinY +1 > 0) {
Pokitto 46:e7e438368e16 1006 #else
Pokitto 46:e7e438368e16 1007 if (scanlineMaxY - scanlineMinY +1 > 0) {
Pokitto 46:e7e438368e16 1008 #endif
Pokitto 46:e7e438368e16 1009 // Draw 8 vertical pixels at a time for performance reasons
Pokitto 46:e7e438368e16 1010
Pokitto 46:e7e438368e16 1011 setDRAMptr(x, scanlineMinY);
Pokitto 46:e7e438368e16 1012 for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
Pokitto 46:e7e438368e16 1013 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1014 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1015 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1016 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1017 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1018 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1019 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1020 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1021 }
Pokitto 46:e7e438368e16 1022
Pokitto 46:e7e438368e16 1023 setDRAMptr(x+1, scanlineMinY);
Pokitto 46:e7e438368e16 1024 for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
Pokitto 46:e7e438368e16 1025 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1026 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1027 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1028 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1029 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1030 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1031 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1032 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1033 }
Pokitto 46:e7e438368e16 1034
Pokitto 46:e7e438368e16 1035 setDRAMptr(x+2, scanlineMinY);
Pokitto 46:e7e438368e16 1036 for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
Pokitto 46:e7e438368e16 1037 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1038 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1039 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1040 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1041 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1042 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1043 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1044 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1045 }
Pokitto 46:e7e438368e16 1046
Pokitto 46:e7e438368e16 1047 setDRAMptr(x+3, scanlineMinY);
Pokitto 46:e7e438368e16 1048 for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
Pokitto 46:e7e438368e16 1049 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1050 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1051 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1052 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1053 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1054 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1055 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1056 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1057 }
Pokitto 46:e7e438368e16 1058 }
Pokitto 46:e7e438368e16 1059 }
Pokitto 46:e7e438368e16 1060
Pokitto 46:e7e438368e16 1061 // Update old x and y for the sprites
Pokitto 46:e7e438368e16 1062 if (sprites != NULL) {
Pokitto 46:e7e438368e16 1063 for (int sprindex = 0; sprindex < spriteCount; sprindex++) {
Pokitto 46:e7e438368e16 1064 sprites[sprindex].oldx = sprites[sprindex].x;
Pokitto 46:e7e438368e16 1065 sprites[sprindex].oldy = sprites[sprindex].y;
Pokitto 46:e7e438368e16 1066 }
Pokitto 46:e7e438368e16 1067 }
Pokitto 46:e7e438368e16 1068
Pokitto 46:e7e438368e16 1069 #ifdef POK_SIM
Pokitto 46:e7e438368e16 1070 simulator.refreshDisplay();
Pokitto 46:e7e438368e16 1071 #endif
Pokitto 46:e7e438368e16 1072 }
Pokitto 46:e7e438368e16 1073
Pokitto 65:deed4aa606fb 1074
Pokitto 51:113b1d84c34f 1075 #define MODE2_INNER_LOOP_B \
Pokitto 51:113b1d84c34f 1076 " ldm %[scanline]!, {%[c]}" "\n" \
Pokitto 51:113b1d84c34f 1077 " str %[c], [%[LCD], 0]" "\n" \
Pokitto 51:113b1d84c34f 1078 " str %[t], [%[LCD], 124]" "\n" \
Pokitto 51:113b1d84c34f 1079 " movs %[c], 252" "\n" \
Pokitto 51:113b1d84c34f 1080 " str %[t], [%[LCD], %[c]]" "\n" \
Pokitto 51:113b1d84c34f 1081 " str %[t], [%[LCD], 124]" "\n" \
Pokitto 51:113b1d84c34f 1082 " subs %[x], 1" "\n" \
Pokitto 51:113b1d84c34f 1083 " str %[t], [%[LCD], %[c]]" "\n" \
Pokitto 65:deed4aa606fb 1084
Pokitto 51:113b1d84c34f 1085
Pokitto 51:113b1d84c34f 1086 void Pokitto::lcdRefreshMode2(uint8_t * scrbuf, uint16_t* paletteptr ) {
Pokitto 65:deed4aa606fb 1087 uint32_t x,y,byte,c,t=1<<12;
Pokitto 51:113b1d84c34f 1088 uint32_t scanline[110];
Pokitto 51:113b1d84c34f 1089
Pokitto 51:113b1d84c34f 1090 write_command(0x03); write_data(0x1038);
Pokitto 51:113b1d84c34f 1091 write_command(0x20); // Horizontal DRAM Address
Pokitto 51:113b1d84c34f 1092 write_data(0); // 0
Pokitto 51:113b1d84c34f 1093 write_command(0x21); // Vertical DRAM Address
Pokitto 65:deed4aa606fb 1094
Pokitto 65:deed4aa606fb 1095 #ifndef __ARMCC_VERSION
Pokitto 65:deed4aa606fb 1096 write_data(1); // still has pixel 0 bug
Pokitto 51:113b1d84c34f 1097 write_command(0x22); // write data to DRAM
Pokitto 51:113b1d84c34f 1098 CLR_CS_SET_CD_RD_WR;
Pokitto 51:113b1d84c34f 1099 SET_MASK_P2;
Pokitto 51:113b1d84c34f 1100
Pokitto 65:deed4aa606fb 1101 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 65:deed4aa606fb 1102 setDRAMptr(0, 8);
Pokitto 65:deed4aa606fb 1103 y=4;
Pokitto 65:deed4aa606fb 1104 #endif
Pokitto 65:deed4aa606fb 1105
Pokitto 65:deed4aa606fb 1106 asm volatile(
Pokitto 51:113b1d84c34f 1107 ".syntax unified" "\n"
Pokitto 65:deed4aa606fb 1108
Pokitto 51:113b1d84c34f 1109 "mov r10, %[scanline]" "\n"
Pokitto 51:113b1d84c34f 1110 "mov r11, %[t]" "\n"
Pokitto 65:deed4aa606fb 1111
Pokitto 51:113b1d84c34f 1112 "mode2OuterLoop:" "\n"
Pokitto 65:deed4aa606fb 1113
Pokitto 51:113b1d84c34f 1114 "movs %[x], 110" "\n"
Pokitto 51:113b1d84c34f 1115 "mode2InnerLoopA:"
Pokitto 51:113b1d84c34f 1116
Pokitto 51:113b1d84c34f 1117
Pokitto 65:deed4aa606fb 1118 " ldrb %[byte], [%[scrbuf],0]" "\n"
Pokitto 51:113b1d84c34f 1119 " lsrs %[c], %[byte], 4" "\n"
Pokitto 51:113b1d84c34f 1120
Pokitto 51:113b1d84c34f 1121 " movs %[t], 15" "\n"
Pokitto 65:deed4aa606fb 1122 " ands %[byte], %[t]" "\n"
Pokitto 65:deed4aa606fb 1123
Pokitto 65:deed4aa606fb 1124 " lsls %[c], 1" "\n"
Pokitto 65:deed4aa606fb 1125 " ldrh %[t], [%[paletteptr], %[c]]" "\n"
Pokitto 65:deed4aa606fb 1126 " lsls %[t], %[t], 3" "\n"
Pokitto 65:deed4aa606fb 1127 " str %[t], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 1128 " mov %[c], r11" "\n"
Pokitto 65:deed4aa606fb 1129 " str %[c], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 1130 " stm %[scanline]!, {%[t]}" "\n"
Pokitto 65:deed4aa606fb 1131 " movs %[t], 252" "\n"
Pokitto 65:deed4aa606fb 1132 " str %[c], [%[LCD], %[t]]" "\n"
Pokitto 65:deed4aa606fb 1133 " str %[c], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 1134 " lsls %[byte], %[byte], 1" "\n"
Pokitto 51:113b1d84c34f 1135 " str %[c], [%[LCD], %[t]]" "\n"
Pokitto 46:e7e438368e16 1136
Pokitto 65:deed4aa606fb 1137 " ldrh %[t], [%[paletteptr], %[byte]]" "\n"
Pokitto 65:deed4aa606fb 1138 " lsls %[t], %[t], 3" "\n"
Pokitto 65:deed4aa606fb 1139 " str %[t], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 1140 " mov %[c], r11" "\n"
Pokitto 65:deed4aa606fb 1141 " str %[c], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 1142 " stm %[scanline]!, {%[t]}" "\n"
Pokitto 65:deed4aa606fb 1143 " movs %[t], 252" "\n"
Pokitto 51:113b1d84c34f 1144 " str %[c], [%[LCD], %[t]]" "\n"
Pokitto 65:deed4aa606fb 1145 " str %[c], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 1146 " adds %[scrbuf], %[scrbuf], 1" "\n"
Pokitto 65:deed4aa606fb 1147 " str %[c], [%[LCD], %[t]]" "\n"
Pokitto 65:deed4aa606fb 1148
Pokitto 65:deed4aa606fb 1149 " subs %[x], 2" "\n"
Pokitto 51:113b1d84c34f 1150 " bne mode2InnerLoopA" "\n"
Pokitto 46:e7e438368e16 1151
Pokitto 51:113b1d84c34f 1152 "mov %[scanline], r10" "\n"
Pokitto 51:113b1d84c34f 1153 "movs %[x], 110" "\n"
Pokitto 51:113b1d84c34f 1154 "mov %[t], r11" "\n"
Pokitto 51:113b1d84c34f 1155 "mode2InnerLoopB:"
Pokitto 65:deed4aa606fb 1156 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1157 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1158 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1159 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1160 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1161 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1162 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1163 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1164 MODE2_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1165 MODE2_INNER_LOOP_B
Pokitto 51:113b1d84c34f 1166 " bne mode2InnerLoopB" "\n"
Pokitto 65:deed4aa606fb 1167
Pokitto 51:113b1d84c34f 1168 "mov %[scanline], r10" "\n"
Pokitto 51:113b1d84c34f 1169 "movs %[t], 1" "\n"
Pokitto 51:113b1d84c34f 1170 "movs %[c], 88" "\n"
Pokitto 51:113b1d84c34f 1171 "add %[y], %[t]" "\n" // y++... derpy, but it's the outer loop
Pokitto 51:113b1d84c34f 1172 "cmp %[y], %[c]" "\n"
Pokitto 51:113b1d84c34f 1173 "bne mode2OuterLoop" "\n" // if y != 88, loop
Pokitto 65:deed4aa606fb 1174
Pokitto 51:113b1d84c34f 1175 : // outputs
Pokitto 51:113b1d84c34f 1176 [c]"+l" (c),
Pokitto 51:113b1d84c34f 1177 [t]"+l" (t),
Pokitto 51:113b1d84c34f 1178 [x]"+l" (x),
Pokitto 51:113b1d84c34f 1179 [y]"+h" (y), // +:Read-Write l:lower (0-7) register
Pokitto 51:113b1d84c34f 1180 [scrbuf]"+l" (scrbuf)
Pokitto 65:deed4aa606fb 1181
Pokitto 51:113b1d84c34f 1182 : // inputs
Pokitto 51:113b1d84c34f 1183 [LCD]"l" (0xA0002188),
Pokitto 51:113b1d84c34f 1184 [scanline]"l" (scanline),
Pokitto 51:113b1d84c34f 1185 [paletteptr]"l" (paletteptr),
Pokitto 51:113b1d84c34f 1186 [byte]"l" (byte)
Pokitto 51:113b1d84c34f 1187 : // clobbers
Pokitto 51:113b1d84c34f 1188 "cc", "r10", "r11"
Pokitto 51:113b1d84c34f 1189 );
Pokitto 51:113b1d84c34f 1190
Pokitto 65:deed4aa606fb 1191
Pokitto 51:113b1d84c34f 1192 #else
Pokitto 65:deed4aa606fb 1193 write_data(0); // does not have pixel 0 bug
Pokitto 65:deed4aa606fb 1194 write_command(0x22); // write data to DRAM
Pokitto 65:deed4aa606fb 1195 CLR_CS_SET_CD_RD_WR;
Pokitto 65:deed4aa606fb 1196 SET_MASK_P2;
Pokitto 65:deed4aa606fb 1197
Pokitto 51:113b1d84c34f 1198 uint8_t* d = scrbuf;// point to beginning of line in data
Pokitto 51:113b1d84c34f 1199
Pokitto 51:113b1d84c34f 1200 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 51:113b1d84c34f 1201 setDRAMptr(0, 8);
Pokitto 51:113b1d84c34f 1202 wait_us(200); // Add wait to compensate skipping of 8 lines. Makes FPS counter to show the correct value.
Pokitto 51:113b1d84c34f 1203 for(y=4;y<88;y++)
Pokitto 51:113b1d84c34f 1204 #else
Pokitto 51:113b1d84c34f 1205 for(y=0;y<88;y++)
Pokitto 51:113b1d84c34f 1206 #endif
Pokitto 46:e7e438368e16 1207 {
Pokitto 51:113b1d84c34f 1208
Pokitto 51:113b1d84c34f 1209
Pokitto 46:e7e438368e16 1210 uint8_t s=0;
Pokitto 51:113b1d84c34f 1211 for(x=0;x<110;x+=2)
Pokitto 46:e7e438368e16 1212 {
Pokitto 51:113b1d84c34f 1213 uint8_t t = *d++;
Pokitto 51:113b1d84c34f 1214 uint32_t color;
Pokitto 51:113b1d84c34f 1215 color = uint32_t(paletteptr[t>>4])<<3;
Pokitto 71:531419862202 1216 scanline[s++]= color;
Pokitto 71:531419862202 1217 *LCD=color;TGL_WR;TGL_WR;
Pokitto 51:113b1d84c34f 1218 color = uint32_t(paletteptr[t&0xF])<<3;
Pokitto 71:531419862202 1219 scanline[s++]= color;
Pokitto 71:531419862202 1220 *LCD=color;TGL_WR;TGL_WR;
Pokitto 46:e7e438368e16 1221 }
Pokitto 46:e7e438368e16 1222
Pokitto 51:113b1d84c34f 1223 s=0;
Pokitto 51:113b1d84c34f 1224 for (s=0;s<110;) {
Pokitto 51:113b1d84c34f 1225 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1226 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1227 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1228 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1229 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1230 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1231 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1232 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1233 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 51:113b1d84c34f 1234 *LCD = (scanline[s]);TGL_WR_OP(s++);TGL_WR;
Pokitto 46:e7e438368e16 1235 }
Pokitto 46:e7e438368e16 1236
Pokitto 46:e7e438368e16 1237 }
Pokitto 51:113b1d84c34f 1238 #endif
Pokitto 51:113b1d84c34f 1239
Pokitto 51:113b1d84c34f 1240 CLR_MASK_P2;
Pokitto 46:e7e438368e16 1241 }
Pokitto 46:e7e438368e16 1242
Pokitto 46:e7e438368e16 1243 void Pokitto::lcdRefreshMode3(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 46:e7e438368e16 1244 uint16_t x,y;
Pokitto 46:e7e438368e16 1245 uint16_t scanline[2][176]; // read two nibbles = pixels at a time
Pokitto 46:e7e438368e16 1246 uint8_t *d;
Pokitto 46:e7e438368e16 1247
Pokitto 46:e7e438368e16 1248 write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 1249 write_data(0); // 0
Pokitto 46:e7e438368e16 1250 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 1251 write_data(0);
Pokitto 46:e7e438368e16 1252 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 1253 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 1254
Pokitto 46:e7e438368e16 1255 for(x=0;x<220;x+=2)
Pokitto 46:e7e438368e16 1256 {
Pokitto 46:e7e438368e16 1257 d = scrbuf+(x>>1);// point to beginning of line in data
Pokitto 46:e7e438368e16 1258 /** find colours in one scanline **/
Pokitto 46:e7e438368e16 1259 uint8_t s=0;
Pokitto 46:e7e438368e16 1260 for(y=0;y<176;y++)
Pokitto 46:e7e438368e16 1261 {
Pokitto 46:e7e438368e16 1262 uint8_t t = *d >> 4; // higher nibble
Pokitto 46:e7e438368e16 1263 uint8_t t2 = *d & 0xF; // lower nibble
Pokitto 46:e7e438368e16 1264 /** higher nibble = left pixel in pixel pair **/
Pokitto 46:e7e438368e16 1265 scanline[0][s] = paletteptr[t];
Pokitto 46:e7e438368e16 1266 scanline[1][s++] = paletteptr[t2];
Pokitto 46:e7e438368e16 1267 /** testing only **/
Pokitto 46:e7e438368e16 1268 //scanline[0][s] = 0xFFFF*(s&1);
Pokitto 46:e7e438368e16 1269 //scanline[1][s] = 0xFFFF*(!(s&1));
Pokitto 46:e7e438368e16 1270 //s++;
Pokitto 46:e7e438368e16 1271 /** until here **/
Pokitto 46:e7e438368e16 1272 d+=220/2; // jump to read byte directly below in screenbuffer
Pokitto 46:e7e438368e16 1273 }
Pokitto 46:e7e438368e16 1274 s=0;
Pokitto 46:e7e438368e16 1275 /** draw scanlines **/
Pokitto 46:e7e438368e16 1276 /** leftmost scanline**/
Pokitto 46:e7e438368e16 1277
Pokitto 46:e7e438368e16 1278 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 1279 if (x<8) continue;
Pokitto 46:e7e438368e16 1280 setDRAMptr(x, 0);
Pokitto 46:e7e438368e16 1281 #endif
Pokitto 46:e7e438368e16 1282
Pokitto 46:e7e438368e16 1283 for (s=0;s<176;) {
Pokitto 46:e7e438368e16 1284 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1285 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1286 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1287 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1288 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1289 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1290 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1291 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1292 }
Pokitto 46:e7e438368e16 1293
Pokitto 46:e7e438368e16 1294 /** rightmost scanline**/
Pokitto 46:e7e438368e16 1295 //setDRAMptr(xptr++,yoffset);
Pokitto 46:e7e438368e16 1296 for (s=0;s<176;) {
Pokitto 46:e7e438368e16 1297 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1298 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1299 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1300 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1301 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1302 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1303 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1304 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1305 }
Pokitto 46:e7e438368e16 1306 }
Pokitto 46:e7e438368e16 1307 }
Pokitto 46:e7e438368e16 1308
Pokitto 46:e7e438368e16 1309 void Pokitto::lcdRefreshGB(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 46:e7e438368e16 1310 uint16_t x,y;
Pokitto 46:e7e438368e16 1311 uint16_t scanline[48];
Pokitto 46:e7e438368e16 1312 uint8_t * d;
Pokitto 46:e7e438368e16 1313
Pokitto 46:e7e438368e16 1314 #if POK_STRETCH
Pokitto 46:e7e438368e16 1315 //uint16_t xptr = 8;
Pokitto 46:e7e438368e16 1316 #else
Pokitto 46:e7e438368e16 1317 //xptr = 26;
Pokitto 46:e7e438368e16 1318 #endif
Pokitto 46:e7e438368e16 1319
Pokitto 46:e7e438368e16 1320 write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 1321 write_data(0); // 0
Pokitto 46:e7e438368e16 1322 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 1323 write_data(0);
Pokitto 46:e7e438368e16 1324 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 1325 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 1326
Pokitto 46:e7e438368e16 1327 /** draw border **/
Pokitto 46:e7e438368e16 1328 for (int s=0;s<5*176;) {
Pokitto 46:e7e438368e16 1329 setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;s++;
Pokitto 46:e7e438368e16 1330 }
Pokitto 46:e7e438368e16 1331
Pokitto 46:e7e438368e16 1332 for(x=0;x<84;x++)
Pokitto 46:e7e438368e16 1333 {
Pokitto 46:e7e438368e16 1334
Pokitto 46:e7e438368e16 1335 d = scrbuf + x;// point to beginning of line in data
Pokitto 46:e7e438368e16 1336
Pokitto 46:e7e438368e16 1337 /** find colours in one scanline **/
Pokitto 46:e7e438368e16 1338 uint8_t s=0;
Pokitto 46:e7e438368e16 1339 for(y=0;y<6;y++)
Pokitto 46:e7e438368e16 1340 {
Pokitto 46:e7e438368e16 1341 uint8_t t = *d;
Pokitto 46:e7e438368e16 1342 #if POK_COLORDEPTH > 1
Pokitto 46:e7e438368e16 1343 uint8_t t2 = *(d+504);
Pokitto 46:e7e438368e16 1344 #endif
Pokitto 46:e7e438368e16 1345 #if POK_COLORDEPTH > 2
Pokitto 46:e7e438368e16 1346 uint8_t t3 = *(d+504+504);
Pokitto 46:e7e438368e16 1347 #endif
Pokitto 46:e7e438368e16 1348 #if POK_COLORDEPTH > 3
Pokitto 46:e7e438368e16 1349 uint8_t t4 = *(d+504+504+504);
Pokitto 46:e7e438368e16 1350 #endif
Pokitto 46:e7e438368e16 1351 uint8_t paletteindex = 0;
Pokitto 46:e7e438368e16 1352
Pokitto 46:e7e438368e16 1353 /** bit 1 **/
Pokitto 46:e7e438368e16 1354 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1355 paletteindex = (t & 0x1);
Pokitto 46:e7e438368e16 1356 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1357 paletteindex = ((t & 0x1)) | ((t2 & 0x01)<<1);
Pokitto 46:e7e438368e16 1358 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1359 paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2);
Pokitto 46:e7e438368e16 1360 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1361 paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2) | ((t4 & 0x1)<<3);
Pokitto 46:e7e438368e16 1362 #endif
Pokitto 46:e7e438368e16 1363 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1364
Pokitto 46:e7e438368e16 1365 /** bit 2 **/
Pokitto 46:e7e438368e16 1366 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1367 paletteindex = (t & 0x2)>>1;
Pokitto 46:e7e438368e16 1368 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1369 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x02));
Pokitto 46:e7e438368e16 1370 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1371 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1);
Pokitto 46:e7e438368e16 1372 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1373 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1) | ((t4 & 0x2)<<2);
Pokitto 46:e7e438368e16 1374 #endif
Pokitto 46:e7e438368e16 1375 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1376
Pokitto 46:e7e438368e16 1377 /** bit 3 **/
Pokitto 46:e7e438368e16 1378 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1379 paletteindex = (t & 0x4)>>2;
Pokitto 46:e7e438368e16 1380 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1381 paletteindex = ((t & 4)>>2) | ((t2 & 0x04)>>1);
Pokitto 46:e7e438368e16 1382 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1383 paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4);
Pokitto 46:e7e438368e16 1384 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1385 paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4) | ((t4 & 0x4)<<1);
Pokitto 46:e7e438368e16 1386 #endif
Pokitto 46:e7e438368e16 1387 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1388
Pokitto 46:e7e438368e16 1389 /** bit 4 **/
Pokitto 46:e7e438368e16 1390 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1391 paletteindex = (t & 0x8)>>3;
Pokitto 46:e7e438368e16 1392 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1393 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x08)>>2);
Pokitto 46:e7e438368e16 1394 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1395 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1);
Pokitto 46:e7e438368e16 1396 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1397 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1) | (t4 & 0x8);
Pokitto 46:e7e438368e16 1398 #endif
Pokitto 46:e7e438368e16 1399 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1400
Pokitto 46:e7e438368e16 1401 /** bit 5 **/
Pokitto 46:e7e438368e16 1402 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1403 paletteindex = (t & 0x10)>>4;
Pokitto 46:e7e438368e16 1404 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1405 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3);
Pokitto 46:e7e438368e16 1406 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1407 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2);
Pokitto 46:e7e438368e16 1408 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1409 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2) | ((t4 & 0x10)>>1);
Pokitto 46:e7e438368e16 1410 #endif
Pokitto 46:e7e438368e16 1411 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1412
Pokitto 46:e7e438368e16 1413 /** bit 6 **/
Pokitto 46:e7e438368e16 1414 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1415 paletteindex = (t & 0x20)>>5;
Pokitto 46:e7e438368e16 1416 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1417 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4);
Pokitto 46:e7e438368e16 1418 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1419 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3);
Pokitto 46:e7e438368e16 1420 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1421 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3) | ((t4 & 0x20)>>2);
Pokitto 46:e7e438368e16 1422 #endif
Pokitto 46:e7e438368e16 1423 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1424
Pokitto 46:e7e438368e16 1425 /** bit 7 **/
Pokitto 46:e7e438368e16 1426 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1427 paletteindex = (t & 0x40)>>6;
Pokitto 46:e7e438368e16 1428 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1429 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5);
Pokitto 46:e7e438368e16 1430 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1431 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) ;
Pokitto 46:e7e438368e16 1432 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1433 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) | ((t4 & 0x40)>>3);
Pokitto 46:e7e438368e16 1434 #endif
Pokitto 46:e7e438368e16 1435 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1436
Pokitto 46:e7e438368e16 1437 /** bit 8 **/
Pokitto 46:e7e438368e16 1438 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1439 paletteindex = (t & 0x80)>>7;
Pokitto 46:e7e438368e16 1440 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1441 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6);
Pokitto 46:e7e438368e16 1442 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1443 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5);
Pokitto 46:e7e438368e16 1444 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1445 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5) | ((t4 & 0x80)>>4);
Pokitto 46:e7e438368e16 1446 #endif
Pokitto 46:e7e438368e16 1447 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1448
Pokitto 46:e7e438368e16 1449 d+=84; // jump to byte directly below
Pokitto 46:e7e438368e16 1450 }
Pokitto 46:e7e438368e16 1451
Pokitto 46:e7e438368e16 1452
Pokitto 46:e7e438368e16 1453 /*write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 1454 write_data(0x10); // 0
Pokitto 46:e7e438368e16 1455 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 1456 write_data(xptr++);
Pokitto 46:e7e438368e16 1457 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 1458 CLR_CS_SET_CD_RD_WR;*/
Pokitto 46:e7e438368e16 1459 /** draw border **/
Pokitto 46:e7e438368e16 1460 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;
Pokitto 46:e7e438368e16 1461
Pokitto 46:e7e438368e16 1462 s=0;
Pokitto 46:e7e438368e16 1463
Pokitto 46:e7e438368e16 1464 /** draw scanlines **/
Pokitto 46:e7e438368e16 1465 for (s=0;s<48;) {
Pokitto 46:e7e438368e16 1466 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1467 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1468 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1469 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1470 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1471 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1472 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1473 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1474 }
Pokitto 46:e7e438368e16 1475 /** draw border **/
Pokitto 46:e7e438368e16 1476 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;
Pokitto 46:e7e438368e16 1477
Pokitto 46:e7e438368e16 1478
Pokitto 46:e7e438368e16 1479 /*write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 1480 write_data(0x10); // 0
Pokitto 46:e7e438368e16 1481 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 1482 write_data(xptr++);
Pokitto 46:e7e438368e16 1483 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 1484 CLR_CS_SET_CD_RD_WR;*/
Pokitto 46:e7e438368e16 1485 /** draw border **/
Pokitto 46:e7e438368e16 1486 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;
Pokitto 46:e7e438368e16 1487
Pokitto 46:e7e438368e16 1488 for (s=0;s<48;) {
Pokitto 46:e7e438368e16 1489 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1490 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1491 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1492 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1493 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1494 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1495 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1496 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1497 }
Pokitto 46:e7e438368e16 1498
Pokitto 46:e7e438368e16 1499 /** draw border **/
Pokitto 46:e7e438368e16 1500 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;
Pokitto 46:e7e438368e16 1501
Pokitto 46:e7e438368e16 1502
Pokitto 46:e7e438368e16 1503 #if POK_STRETCH
Pokitto 46:e7e438368e16 1504 //if (x>16 && x<68)
Pokitto 46:e7e438368e16 1505 if (x&2)// && x&2)
Pokitto 46:e7e438368e16 1506 {
Pokitto 46:e7e438368e16 1507 /*write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 1508 write_data(0x10); // 0
Pokitto 46:e7e438368e16 1509 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 1510 write_data(xptr++);
Pokitto 46:e7e438368e16 1511 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 1512 CLR_CS_SET_CD_RD_WR;*/
Pokitto 46:e7e438368e16 1513 /** draw border **/
Pokitto 46:e7e438368e16 1514 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;
Pokitto 46:e7e438368e16 1515
Pokitto 46:e7e438368e16 1516
Pokitto 46:e7e438368e16 1517 for (s=0;s<48;) {
Pokitto 46:e7e438368e16 1518 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1519 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1520 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1521 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1522 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1523 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1524 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1525 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1526 }
Pokitto 46:e7e438368e16 1527
Pokitto 46:e7e438368e16 1528 /** draw border **/
Pokitto 46:e7e438368e16 1529 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;
Pokitto 46:e7e438368e16 1530
Pokitto 46:e7e438368e16 1531 }
Pokitto 46:e7e438368e16 1532 #endif
Pokitto 46:e7e438368e16 1533 }
Pokitto 46:e7e438368e16 1534 /** draw border **/
Pokitto 46:e7e438368e16 1535 for (int s=0;s<5*176;) {
Pokitto 46:e7e438368e16 1536 setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;s++;
Pokitto 46:e7e438368e16 1537 }
Pokitto 46:e7e438368e16 1538 }
Pokitto 46:e7e438368e16 1539
Pokitto 46:e7e438368e16 1540
Pokitto 46:e7e438368e16 1541 void Pokitto::lcdRefreshAB(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 46:e7e438368e16 1542 uint16_t x,y;
Pokitto 46:e7e438368e16 1543 uint16_t scanline[64];
Pokitto 46:e7e438368e16 1544 uint8_t *d;
Pokitto 46:e7e438368e16 1545 //lcdClear();
Pokitto 46:e7e438368e16 1546 #if POK_STRETCH
Pokitto 46:e7e438368e16 1547 uint16_t xptr = 14;
Pokitto 46:e7e438368e16 1548 uint8_t yoffset = 24;
Pokitto 46:e7e438368e16 1549 #else
Pokitto 46:e7e438368e16 1550 uint16_t xptr = 0;
Pokitto 46:e7e438368e16 1551 uint8_t yoffset = 0;
Pokitto 46:e7e438368e16 1552 #endif
Pokitto 46:e7e438368e16 1553
Pokitto 46:e7e438368e16 1554 for(x=0;x<128;x++)
Pokitto 46:e7e438368e16 1555 {
Pokitto 46:e7e438368e16 1556 write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 1557 write_data(yoffset); // 0
Pokitto 46:e7e438368e16 1558 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 1559 write_data(xptr++);
Pokitto 46:e7e438368e16 1560 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 1561 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 1562 //setDRAMptr(xptr++,yoffset);
Pokitto 46:e7e438368e16 1563
Pokitto 46:e7e438368e16 1564 d = scrbuf + x;// point to beginning of line in data
Pokitto 46:e7e438368e16 1565
Pokitto 46:e7e438368e16 1566 /** find colours in one scanline **/
Pokitto 46:e7e438368e16 1567 uint8_t s=0;
Pokitto 46:e7e438368e16 1568 for(y=0;y<8;y++)
Pokitto 46:e7e438368e16 1569 {
Pokitto 46:e7e438368e16 1570 uint8_t t = *d;
Pokitto 46:e7e438368e16 1571 #if POK_COLORDEPTH > 1
Pokitto 46:e7e438368e16 1572 uint8_t t2 = *(d+AB_JUMP);
Pokitto 46:e7e438368e16 1573 #endif // POK_COLORDEPTH
Pokitto 46:e7e438368e16 1574 #if POK_COLORDEPTH > 2
Pokitto 46:e7e438368e16 1575 uint8_t t3 = *(d+AB_JUMP+AB_JUMP);
Pokitto 46:e7e438368e16 1576 #endif // POK_COLORDEPTH
Pokitto 46:e7e438368e16 1577 #if POK_COLORDEPTH > 3
Pokitto 46:e7e438368e16 1578 uint8_t t4 = *(d+AB_JUMP+AB_JUMP+AB_JUMP);
Pokitto 46:e7e438368e16 1579 #endif // POK_COLORDEPTH
Pokitto 46:e7e438368e16 1580 uint8_t paletteindex = 0;
Pokitto 46:e7e438368e16 1581
Pokitto 46:e7e438368e16 1582 /** bit 1 **/
Pokitto 46:e7e438368e16 1583 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1584 paletteindex = (t & 0x1);
Pokitto 46:e7e438368e16 1585 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1586 paletteindex = ((t & 0x1)) | ((t2 & 0x01)<<1);
Pokitto 46:e7e438368e16 1587 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1588 paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2);
Pokitto 46:e7e438368e16 1589 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1590 paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2) | ((t4 & 0x1)<<3);
Pokitto 46:e7e438368e16 1591 #endif
Pokitto 46:e7e438368e16 1592 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1593
Pokitto 46:e7e438368e16 1594 /** bit 2 **/
Pokitto 46:e7e438368e16 1595 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1596 paletteindex = (t & 0x2)>>1;
Pokitto 46:e7e438368e16 1597 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1598 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x02));
Pokitto 46:e7e438368e16 1599 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1600 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1);
Pokitto 46:e7e438368e16 1601 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1602 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1) | ((t4 & 0x2)<<2);
Pokitto 46:e7e438368e16 1603 #endif
Pokitto 46:e7e438368e16 1604 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1605
Pokitto 46:e7e438368e16 1606 /** bit 3 **/
Pokitto 46:e7e438368e16 1607 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1608 paletteindex = (t & 0x4)>>2;
Pokitto 46:e7e438368e16 1609 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1610 paletteindex = ((t & 4)>>2) | ((t2 & 0x04)>>1);
Pokitto 46:e7e438368e16 1611 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1612 paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4);
Pokitto 46:e7e438368e16 1613 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1614 paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4) | ((t4 & 0x4)<<1);
Pokitto 46:e7e438368e16 1615 #endif
Pokitto 46:e7e438368e16 1616 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1617
Pokitto 46:e7e438368e16 1618 /** bit 4 **/
Pokitto 46:e7e438368e16 1619 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1620 paletteindex = (t & 0x8)>>3;
Pokitto 46:e7e438368e16 1621 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1622 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x08)>>2);
Pokitto 46:e7e438368e16 1623 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1624 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1);
Pokitto 46:e7e438368e16 1625 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1626 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1) | (t4 & 0x8);
Pokitto 46:e7e438368e16 1627 #endif
Pokitto 46:e7e438368e16 1628 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1629
Pokitto 46:e7e438368e16 1630 /** bit 5 **/
Pokitto 46:e7e438368e16 1631 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1632 paletteindex = (t & 0x10)>>4;
Pokitto 46:e7e438368e16 1633 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1634 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3);
Pokitto 46:e7e438368e16 1635 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1636 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2);
Pokitto 46:e7e438368e16 1637 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1638 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2) | ((t4 & 0x10)>>1);
Pokitto 46:e7e438368e16 1639 #endif
Pokitto 46:e7e438368e16 1640 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1641
Pokitto 46:e7e438368e16 1642 /** bit 6 **/
Pokitto 46:e7e438368e16 1643 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1644 paletteindex = (t & 0x20)>>5;
Pokitto 46:e7e438368e16 1645 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1646 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4);
Pokitto 46:e7e438368e16 1647 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1648 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3);
Pokitto 46:e7e438368e16 1649 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1650 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3) | ((t4 & 0x20)>>2);
Pokitto 46:e7e438368e16 1651 #endif
Pokitto 46:e7e438368e16 1652 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1653
Pokitto 46:e7e438368e16 1654 /** bit 7 **/
Pokitto 46:e7e438368e16 1655 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1656 paletteindex = (t & 0x40)>>6;
Pokitto 46:e7e438368e16 1657 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1658 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5);
Pokitto 46:e7e438368e16 1659 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1660 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) ;
Pokitto 46:e7e438368e16 1661 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1662 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) | ((t4 & 0x40)>>3);
Pokitto 46:e7e438368e16 1663 #endif
Pokitto 46:e7e438368e16 1664 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1665
Pokitto 46:e7e438368e16 1666 /** bit 8 **/
Pokitto 46:e7e438368e16 1667 #if POK_COLORDEPTH == 1
Pokitto 46:e7e438368e16 1668 paletteindex = (t & 0x80)>>7;
Pokitto 46:e7e438368e16 1669 #elif POK_COLORDEPTH == 2
Pokitto 46:e7e438368e16 1670 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6);
Pokitto 46:e7e438368e16 1671 #elif POK_COLORDEPTH == 3
Pokitto 46:e7e438368e16 1672 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5);
Pokitto 46:e7e438368e16 1673 #elif POK_COLORDEPTH == 4
Pokitto 46:e7e438368e16 1674 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5) | ((t4 & 0x80)>>4);
Pokitto 46:e7e438368e16 1675 #endif
Pokitto 46:e7e438368e16 1676 scanline[s++] = paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1677
Pokitto 46:e7e438368e16 1678 d+=128; // jump to byte directly below
Pokitto 46:e7e438368e16 1679 }
Pokitto 46:e7e438368e16 1680
Pokitto 46:e7e438368e16 1681 s=0;
Pokitto 46:e7e438368e16 1682
Pokitto 46:e7e438368e16 1683 /** draw scanlines **/
Pokitto 46:e7e438368e16 1684 for (s=0;s<64;) {
Pokitto 46:e7e438368e16 1685 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1686 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1687 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1688 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1689 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1690 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1691 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1692 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1693 }
Pokitto 46:e7e438368e16 1694
Pokitto 46:e7e438368e16 1695 #if POK_STRETCH
Pokitto 46:e7e438368e16 1696 if (x&1) {
Pokitto 46:e7e438368e16 1697 write_command(0x20); // Horizontal DRAM Address
Pokitto 46:e7e438368e16 1698 write_data(yoffset); // 0
Pokitto 46:e7e438368e16 1699 write_command(0x21); // Vertical DRAM Address
Pokitto 46:e7e438368e16 1700 write_data(xptr++);
Pokitto 46:e7e438368e16 1701 write_command(0x22); // write data to DRAM
Pokitto 46:e7e438368e16 1702 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 1703 //setDRAMptr(xptr++,yoffset);
Pokitto 46:e7e438368e16 1704
Pokitto 46:e7e438368e16 1705 for (s=0;s<64;) {
Pokitto 46:e7e438368e16 1706 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1707 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1708 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1709 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1710 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1711 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1712 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1713 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1714 }
Pokitto 46:e7e438368e16 1715 }
Pokitto 46:e7e438368e16 1716 #endif
Pokitto 46:e7e438368e16 1717 }
Pokitto 46:e7e438368e16 1718 }
Pokitto 46:e7e438368e16 1719
Pokitto 46:e7e438368e16 1720 void Pokitto::lcdRefreshModeGBC(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 46:e7e438368e16 1721 uint16_t x,y,xptr;
Pokitto 46:e7e438368e16 1722 uint16_t scanline[4][144]; // read 4 half-nibbles = 4 pixels at a time
Pokitto 46:e7e438368e16 1723 uint8_t *d, yoffset=0;
Pokitto 46:e7e438368e16 1724
Pokitto 46:e7e438368e16 1725 xptr = 0;
Pokitto 46:e7e438368e16 1726 setDRAMptr(xptr,yoffset);
Pokitto 46:e7e438368e16 1727
Pokitto 46:e7e438368e16 1728
Pokitto 46:e7e438368e16 1729 for(x=0;x<160;x+=4)
Pokitto 46:e7e438368e16 1730 {
Pokitto 46:e7e438368e16 1731 d = scrbuf+(x>>2);// point to beginning of line in data
Pokitto 46:e7e438368e16 1732 /** find colours in one scanline **/
Pokitto 46:e7e438368e16 1733 uint8_t s=0;
Pokitto 46:e7e438368e16 1734 for(y=0;y<144;y++)
Pokitto 46:e7e438368e16 1735 {
Pokitto 46:e7e438368e16 1736 uint8_t tdata = *d;
Pokitto 46:e7e438368e16 1737 uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
Pokitto 46:e7e438368e16 1738 uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
Pokitto 46:e7e438368e16 1739 uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
Pokitto 46:e7e438368e16 1740 uint8_t t = tdata & 0x03;// highest half-nibble
Pokitto 46:e7e438368e16 1741
Pokitto 46:e7e438368e16 1742 /** put nibble values in the scanlines **/
Pokitto 46:e7e438368e16 1743
Pokitto 46:e7e438368e16 1744 scanline[0][s] = paletteptr[t];
Pokitto 46:e7e438368e16 1745 scanline[1][s] = paletteptr[t2];
Pokitto 46:e7e438368e16 1746 scanline[2][s] = paletteptr[t3];
Pokitto 46:e7e438368e16 1747 scanline[3][s++] = paletteptr[t4];
Pokitto 46:e7e438368e16 1748
Pokitto 46:e7e438368e16 1749 d+=160/4; // jump to read byte directly below in screenbuffer
Pokitto 46:e7e438368e16 1750 }
Pokitto 46:e7e438368e16 1751
Pokitto 46:e7e438368e16 1752 s=0;
Pokitto 46:e7e438368e16 1753 /** draw scanlines **/
Pokitto 46:e7e438368e16 1754 for (s=0;s<144;) {
Pokitto 46:e7e438368e16 1755 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1756 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1757 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1758 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1759 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1760 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1761 }
Pokitto 46:e7e438368e16 1762 setDRAMptr(++xptr,yoffset);
Pokitto 46:e7e438368e16 1763 for (s=0;s<144;) {
Pokitto 46:e7e438368e16 1764 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1765 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1766 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1767 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1768 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1769 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1770 }
Pokitto 46:e7e438368e16 1771 setDRAMptr(++xptr,yoffset);
Pokitto 46:e7e438368e16 1772 for (s=0;s<144;) {
Pokitto 46:e7e438368e16 1773 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1774 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1775 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1776 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1777 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1778 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1779 }
Pokitto 46:e7e438368e16 1780 setDRAMptr(++xptr,yoffset);
Pokitto 46:e7e438368e16 1781 for (s=0;s<144;) {
Pokitto 46:e7e438368e16 1782 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1783 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1784 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1785 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1786 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1787 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1788 }
Pokitto 46:e7e438368e16 1789 setDRAMptr(++xptr,yoffset);
Pokitto 46:e7e438368e16 1790 }
Pokitto 46:e7e438368e16 1791 }
Pokitto 46:e7e438368e16 1792
Pokitto 46:e7e438368e16 1793
Pokitto 46:e7e438368e16 1794 void Pokitto::lcdRefreshT1(uint8_t* tilebuf, uint8_t* tilecolorbuf, uint8_t* tileset, uint16_t* paletteptr) {
Pokitto 46:e7e438368e16 1795 #ifdef POK_TILEMODE
Pokitto 46:e7e438368e16 1796 uint16_t x,y,data,xptr;
Pokitto 46:e7e438368e16 1797 uint16_t scanline[176];
Pokitto 46:e7e438368e16 1798 uint8_t yoffset=0, tilebyte, tileindex, tilex=0, tiley=0,xcount;
Pokitto 46:e7e438368e16 1799
Pokitto 46:e7e438368e16 1800
Pokitto 46:e7e438368e16 1801 if (!tileset) return;
Pokitto 46:e7e438368e16 1802
Pokitto 46:e7e438368e16 1803 #if LCDWIDTH < POK_LCD_W
Pokitto 46:e7e438368e16 1804 xptr = (POK_LCD_W-LCDWIDTH)/2;
Pokitto 46:e7e438368e16 1805 #else
Pokitto 46:e7e438368e16 1806 xptr = 0;
Pokitto 46:e7e438368e16 1807 #endif
Pokitto 46:e7e438368e16 1808 #if LCDHEIGHT < POK_LCD_H
Pokitto 46:e7e438368e16 1809 yoffset = (POK_LCD_H-LCDHEIGHT)/2;
Pokitto 46:e7e438368e16 1810 #else
Pokitto 46:e7e438368e16 1811 yoffset = 0;
Pokitto 46:e7e438368e16 1812 #endif
Pokitto 46:e7e438368e16 1813
Pokitto 46:e7e438368e16 1814 for(x=0, xcount=0 ;x<LCDWIDTH;x++,xcount++) // loop through vertical columns
Pokitto 46:e7e438368e16 1815 {
Pokitto 46:e7e438368e16 1816 setDRAMptr(xptr++,yoffset); //point to VRAM
Pokitto 46:e7e438368e16 1817
Pokitto 46:e7e438368e16 1818 /** find colours in one scanline **/
Pokitto 46:e7e438368e16 1819 uint8_t s=0, tiley=0;
Pokitto 46:e7e438368e16 1820 //tileindex = tilebuf[tilex*POK_TILES_Y];
Pokitto 46:e7e438368e16 1821 if (xcount==POK_TILE_W) {
Pokitto 46:e7e438368e16 1822 tilex++;
Pokitto 46:e7e438368e16 1823 xcount=0;
Pokitto 46:e7e438368e16 1824 }
Pokitto 46:e7e438368e16 1825
Pokitto 46:e7e438368e16 1826 for(y=0;y<LCDHEIGHT;)
Pokitto 46:e7e438368e16 1827 {
Pokitto 46:e7e438368e16 1828 uint8_t tileval = tilebuf[tilex+tiley*POK_TILES_X]; //get tile number
Pokitto 46:e7e438368e16 1829 uint16_t index = tileval*POK_TILE_W+xcount;
Pokitto 46:e7e438368e16 1830 uint8_t tilebyte = tileset[index]; //get bitmap data
Pokitto 46:e7e438368e16 1831 for (uint8_t ycount=0, bitcount=0; ycount<POK_TILE_H; ycount++, y++, bitcount++) {
Pokitto 46:e7e438368e16 1832 if (bitcount==8) {
Pokitto 46:e7e438368e16 1833 bitcount=0;
Pokitto 46:e7e438368e16 1834 index += 176; //jump to byte below in the tileset bitmap
Pokitto 46:e7e438368e16 1835 tilebyte = tileset[index]; //get bitmap data
Pokitto 46:e7e438368e16 1836 }
Pokitto 46:e7e438368e16 1837 //tilebyte = tile[(tileindex>>4)+*POK_TILE_W]; //tilemaps are 16x16
Pokitto 46:e7e438368e16 1838 //uint8_t paletteindex = ((tilebyte>>(bitcount&0x7)) & 0x1);
Pokitto 46:e7e438368e16 1839 if (!tileval) scanline[s++] = COLOR_MAGENTA*((tilebyte>>bitcount)&0x1);//paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1840 else scanline[s++] = paletteptr[((tilebyte>>bitcount)&0x1)*tileval];//paletteptr[paletteindex];
Pokitto 46:e7e438368e16 1841 }
Pokitto 46:e7e438368e16 1842 tiley++; //move to next tile
Pokitto 46:e7e438368e16 1843 }
Pokitto 46:e7e438368e16 1844 s=0;
Pokitto 46:e7e438368e16 1845
Pokitto 46:e7e438368e16 1846 /** draw scanlines **/
Pokitto 46:e7e438368e16 1847 for (s=0;s<LCDHEIGHT;) {
Pokitto 46:e7e438368e16 1848 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 1849 }
Pokitto 46:e7e438368e16 1850 }
Pokitto 46:e7e438368e16 1851 #endif
Pokitto 46:e7e438368e16 1852 }
Pokitto 46:e7e438368e16 1853
Pokitto 51:113b1d84c34f 1854 #define MODE13_INNER_LOOP_A \
Pokitto 65:deed4aa606fb 1855 " add %[t], %[t], r10" "\n" \
Pokitto 51:113b1d84c34f 1856 " uxtb %[c], %[t] " "\n" \
Pokitto 51:113b1d84c34f 1857 " lsls %[c], 1" "\n" \
Pokitto 51:113b1d84c34f 1858 " ldrh %[t], [%[paletteptr], %[c]]" "\n" \
Pokitto 51:113b1d84c34f 1859 " lsls %[t], %[t], 3" "\n" \
Pokitto 51:113b1d84c34f 1860 " str %[t], [%[LCD], 0]" "\n" \
Pokitto 65:deed4aa606fb 1861 " movs %[c], 252" "\n" \
Pokitto 65:deed4aa606fb 1862 " str %[offset], [%[LCD], %[c]]" "\n" \
Pokitto 65:deed4aa606fb 1863 " stm %[scanline]!, {%[t]}" "\n" \
Pokitto 65:deed4aa606fb 1864 " str %[offset], [%[LCD], 124]" "\n" \
Pokitto 65:deed4aa606fb 1865 " str %[offset], [%[LCD], %[c]]" "\n" \
Pokitto 51:113b1d84c34f 1866 " adds %[scrbuf], %[scrbuf], 1" "\n" \
Pokitto 65:deed4aa606fb 1867 " ldrb %[t], [%[scrbuf],0]" "\n" \
Pokitto 65:deed4aa606fb 1868 " str %[offset], [%[LCD], 124]" "\n"
Pokitto 46:e7e438368e16 1869
Pokitto 65:deed4aa606fb 1870 // This can be made 1 cycle faster (x -= 10 instead of x--),
Pokitto 65:deed4aa606fb 1871 // but there will be noise
Pokitto 65:deed4aa606fb 1872 #define MODE13_INNER_LOOP_B \
Pokitto 65:deed4aa606fb 1873 " str %[c], [%[LCD], 0]" "\n" \
Pokitto 65:deed4aa606fb 1874 " str %[offset], [%[LCD], %[t]]" "\n" \
Pokitto 65:deed4aa606fb 1875 " ldr %[c], [%[scanline]]" "\n" \
Pokitto 65:deed4aa606fb 1876 " str %[offset], [%[LCD], 124]" "\n" \
Pokitto 65:deed4aa606fb 1877 " str %[offset], [%[LCD], %[t]]" "\n" \
Pokitto 65:deed4aa606fb 1878 " adds %[scanline], 4" "\n" \
Pokitto 65:deed4aa606fb 1879 " subs %[x], 1" "\n" \
Pokitto 65:deed4aa606fb 1880 " str %[offset], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 1881
Pokitto 65:deed4aa606fb 1882
Pokitto 51:113b1d84c34f 1883 void Pokitto::lcdRefreshMode13(uint8_t * scrbuf, uint16_t* paletteptr, uint8_t offset){
Pokitto 51:113b1d84c34f 1884 uint32_t scanline[110]; // read two nibbles = pixels at a time
Pokitto 65:deed4aa606fb 1885
Pokitto 51:113b1d84c34f 1886 write_command_16(0x03); write_data_16(0x1038);
Pokitto 51:113b1d84c34f 1887 write_command(0x20); write_data(0);
Pokitto 65:deed4aa606fb 1888 write_command(0x21); write_data(0);
Pokitto 51:113b1d84c34f 1889 write_command(0x22);
Pokitto 51:113b1d84c34f 1890 CLR_CS_SET_CD_RD_WR;
Pokitto 51:113b1d84c34f 1891 SET_MASK_P2;
Pokitto 65:deed4aa606fb 1892
Pokitto 65:deed4aa606fb 1893 uint32_t x, y=0, c, t;
Pokitto 65:deed4aa606fb 1894
Pokitto 51:113b1d84c34f 1895 #ifndef __ARMCC_VERSION
Pokitto 65:deed4aa606fb 1896 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 65:deed4aa606fb 1897 setDRAMptr(0, 8);
Pokitto 65:deed4aa606fb 1898 y=4;
Pokitto 65:deed4aa606fb 1899 #endif
Pokitto 65:deed4aa606fb 1900
Pokitto 51:113b1d84c34f 1901 asm volatile(
Pokitto 51:113b1d84c34f 1902 ".syntax unified" "\n"
Pokitto 65:deed4aa606fb 1903
Pokitto 65:deed4aa606fb 1904 "mov r10, %[offset]" "\n"
Pokitto 65:deed4aa606fb 1905 "movs %[offset], 1" "\n"
Pokitto 65:deed4aa606fb 1906 "lsls %[offset], %[offset], 12" "\n"
Pokitto 65:deed4aa606fb 1907
Pokitto 51:113b1d84c34f 1908 "mode13OuterLoop:" "\n"
Pokitto 65:deed4aa606fb 1909
Pokitto 51:113b1d84c34f 1910 "movs %[x], 110" "\n"
Pokitto 65:deed4aa606fb 1911 "ldrb %[t], [%[scrbuf],0]" "\n"
Pokitto 51:113b1d84c34f 1912 "mode13InnerLoopA:"
Pokitto 51:113b1d84c34f 1913 MODE13_INNER_LOOP_A
Pokitto 51:113b1d84c34f 1914 MODE13_INNER_LOOP_A
Pokitto 65:deed4aa606fb 1915 " subs %[x], 2" "\n"
Pokitto 51:113b1d84c34f 1916 " bne mode13InnerLoopA" "\n"
Pokitto 46:e7e438368e16 1917
Pokitto 65:deed4aa606fb 1918 "subs %[scanline], 220" "\n"
Pokitto 65:deed4aa606fb 1919 "subs %[scanline], 220" "\n"
Pokitto 65:deed4aa606fb 1920
Pokitto 51:113b1d84c34f 1921 "movs %[x], 110" "\n"
Pokitto 65:deed4aa606fb 1922 "movs %[t], 252" "\n"
Pokitto 65:deed4aa606fb 1923 "ldm %[scanline]!, {%[c]}" "\n"
Pokitto 51:113b1d84c34f 1924 "mode13InnerLoopB:"
Pokitto 65:deed4aa606fb 1925 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1926 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1927 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1928 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1929 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1930 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1931 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1932 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1933 MODE13_INNER_LOOP_B
Pokitto 65:deed4aa606fb 1934 MODE13_INNER_LOOP_B
Pokitto 51:113b1d84c34f 1935 " bne mode13InnerLoopB" "\n"
Pokitto 65:deed4aa606fb 1936
Pokitto 65:deed4aa606fb 1937 "subs %[scanline], 220" "\n"
Pokitto 65:deed4aa606fb 1938 "subs %[scanline], 224" "\n"
Pokitto 51:113b1d84c34f 1939 "movs %[t], 1" "\n"
Pokitto 51:113b1d84c34f 1940 "movs %[c], 88" "\n"
Pokitto 65:deed4aa606fb 1941 "add %[y], %[t]" "\n"
Pokitto 51:113b1d84c34f 1942 "cmp %[y], %[c]" "\n"
Pokitto 51:113b1d84c34f 1943 "bne mode13OuterLoop" "\n" // if y != 88, loop
Pokitto 65:deed4aa606fb 1944
Pokitto 51:113b1d84c34f 1945 : // outputs
Pokitto 51:113b1d84c34f 1946 [c]"+l" (c),
Pokitto 51:113b1d84c34f 1947 [t]"+l" (t),
Pokitto 51:113b1d84c34f 1948 [x]"+l" (x),
Pokitto 51:113b1d84c34f 1949 [y]"+h" (y), // +:Read-Write l:lower (0-7) register
Pokitto 65:deed4aa606fb 1950 [scrbuf]"+l" (scrbuf),
Pokitto 65:deed4aa606fb 1951 [offset]"+l" (offset)
Pokitto 65:deed4aa606fb 1952
Pokitto 51:113b1d84c34f 1953 : // inputs
Pokitto 51:113b1d84c34f 1954 [LCD]"l" (0xA0002188),
Pokitto 51:113b1d84c34f 1955 [scanline]"l" (scanline),
Pokitto 65:deed4aa606fb 1956 [paletteptr]"l" (paletteptr)
Pokitto 65:deed4aa606fb 1957
Pokitto 51:113b1d84c34f 1958 : // clobbers
Pokitto 65:deed4aa606fb 1959 "cc", "r10"
Pokitto 51:113b1d84c34f 1960 );
Pokitto 46:e7e438368e16 1961
Pokitto 51:113b1d84c34f 1962 #else
Pokitto 51:113b1d84c34f 1963 uint8_t* d = scrbuf;// point to beginning of line in data
Pokitto 51:113b1d84c34f 1964 for(y=0;y<88;y++){
Pokitto 65:deed4aa606fb 1965
Pokitto 51:113b1d84c34f 1966 uint32_t* s = scanline;
Pokitto 65:deed4aa606fb 1967
Pokitto 51:113b1d84c34f 1968 for(x=0;x<110;x+=10){
Pokitto 65:deed4aa606fb 1969 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1970 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1971 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1972 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1973 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1974 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1975 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1976 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1977 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 65:deed4aa606fb 1978 *LCD = *s = paletteptr[(*d + offset)&255]<<3; TGL_WR_OP(s++);TGL_WR_OP(d++);
Pokitto 51:113b1d84c34f 1979 }
Pokitto 65:deed4aa606fb 1980
Pokitto 51:113b1d84c34f 1981 s = scanline;
Pokitto 51:113b1d84c34f 1982 uint32_t c = *s;
Pokitto 51:113b1d84c34f 1983 for(x=0;x<110;x+=10){
Pokitto 51:113b1d84c34f 1984 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1985 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1986 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1987 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1988 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1989 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1990 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1991 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1992 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1993 *LCD = c; TGL_WR_OP(s++);TGL_WR_OP(c=*s);
Pokitto 51:113b1d84c34f 1994 }
Pokitto 65:deed4aa606fb 1995
Pokitto 51:113b1d84c34f 1996 }
Pokitto 51:113b1d84c34f 1997 #endif
Pokitto 51:113b1d84c34f 1998 }
Pokitto 46:e7e438368e16 1999
Pokitto 65:deed4aa606fb 2000
Pokitto 65:deed4aa606fb 2001
Pokitto 65:deed4aa606fb 2002 void Pokitto::lcdRefreshMode64( uint8_t * scrbuf, uint16_t* paletteptr ){
Pokitto 65:deed4aa606fb 2003 uint8_t *end = &scrbuf[ POK_SCREENBUFFERSIZE+4 ];
Pokitto 65:deed4aa606fb 2004 write_command_16(0x03); write_data_16(0x1038);
Pokitto 65:deed4aa606fb 2005 write_command(0x20); write_data(0);
Pokitto 65:deed4aa606fb 2006 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 65:deed4aa606fb 2007 write_data(8);
Pokitto 65:deed4aa606fb 2008 scrbuf += 110*8;
Pokitto 65:deed4aa606fb 2009 #else
Pokitto 65:deed4aa606fb 2010 write_data(0);
Pokitto 65:deed4aa606fb 2011 #endif
Pokitto 65:deed4aa606fb 2012 write_command(0x21); write_data(0);
Pokitto 65:deed4aa606fb 2013 write_command(0x22);
Pokitto 65:deed4aa606fb 2014 CLR_CS_SET_CD_RD_WR;
Pokitto 65:deed4aa606fb 2015 SET_MASK_P2;
Pokitto 65:deed4aa606fb 2016
Pokitto 65:deed4aa606fb 2017 uint32_t TGL = 1<<12, CLR = 252, c, t;
Pokitto 65:deed4aa606fb 2018 #ifndef __ARMCC_VERSION
Pokitto 65:deed4aa606fb 2019 asm volatile(
Pokitto 65:deed4aa606fb 2020 ".syntax unified" "\n"
Pokitto 65:deed4aa606fb 2021 "ldm %[scrbuf]!, {%[c]}" "\n"
Pokitto 65:deed4aa606fb 2022 "lsls %[t], %[c], 24" "\n"
Pokitto 65:deed4aa606fb 2023 "mode64loop%=:" "\n"
Pokitto 65:deed4aa606fb 2024 "lsrs %[c], %[c], 8" "\n"
Pokitto 65:deed4aa606fb 2025 "lsrs %[t], %[t], 23" "\n"
Pokitto 65:deed4aa606fb 2026 "ldrh %[t], [%[paletteptr], %[t]]" "\n"
Pokitto 65:deed4aa606fb 2027 "lsls %[t], 3" "\n"
Pokitto 65:deed4aa606fb 2028 "str %[t], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 2029 "str %[TGL], [%[LCD], %[CLR]]" "\n"
Pokitto 65:deed4aa606fb 2030 "lsls %[t], %[c], 24" "\n"
Pokitto 65:deed4aa606fb 2031 "lsrs %[c], %[c], 8" "\n"
Pokitto 65:deed4aa606fb 2032 "lsrs %[t], %[t], 23" "\n"
Pokitto 65:deed4aa606fb 2033 "str %[TGL], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2034 "str %[TGL], [%[LCD], %[CLR]]" "\n"
Pokitto 65:deed4aa606fb 2035 "ldrh %[t], [%[paletteptr], %[t]]" "\n"
Pokitto 65:deed4aa606fb 2036 "lsls %[t], 3" "\n"
Pokitto 65:deed4aa606fb 2037 "str %[TGL], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2038
Pokitto 65:deed4aa606fb 2039 "str %[t], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 2040 "str %[TGL], [%[LCD], %[CLR]]" "\n"
Pokitto 65:deed4aa606fb 2041 "lsls %[t], %[c], 24" "\n"
Pokitto 65:deed4aa606fb 2042 "lsrs %[t], %[t], 23" "\n"
Pokitto 65:deed4aa606fb 2043 "str %[TGL], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2044 "str %[TGL], [%[LCD], %[CLR]]" "\n"
Pokitto 65:deed4aa606fb 2045 "ldrh %[t], [%[paletteptr], %[t]]" "\n"
Pokitto 65:deed4aa606fb 2046 "lsls %[t], 3" "\n"
Pokitto 65:deed4aa606fb 2047 "str %[TGL], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2048 "str %[t], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 2049 "str %[TGL], [%[LCD], %[CLR]]" "\n"
Pokitto 65:deed4aa606fb 2050 "lsrs %[c], %[c], 8" "\n"
Pokitto 65:deed4aa606fb 2051 "lsls %[t], %[c], 1" "\n"
Pokitto 65:deed4aa606fb 2052 "str %[TGL], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2053 "str %[TGL], [%[LCD], %[CLR]]" "\n"
Pokitto 65:deed4aa606fb 2054 "ldrh %[t], [%[paletteptr], %[t]]" "\n"
Pokitto 65:deed4aa606fb 2055 "lsls %[t], 3" "\n"
Pokitto 65:deed4aa606fb 2056 "str %[TGL], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2057
Pokitto 65:deed4aa606fb 2058 "str %[t], [%[LCD], 0]" "\n"
Pokitto 65:deed4aa606fb 2059 "str %[TGL], [%[LCD], %[CLR]]" "\n"
Pokitto 65:deed4aa606fb 2060 "ldm %[scrbuf]!, {%[c]}" "\n"
Pokitto 65:deed4aa606fb 2061 "str %[TGL], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2062 "str %[TGL], [%[LCD], %[CLR]]" "\n"
Pokitto 65:deed4aa606fb 2063 "lsls %[t], %[c], 24" "\n"
Pokitto 65:deed4aa606fb 2064 "cmp %[scrbuf], %[end]" "\n"
Pokitto 65:deed4aa606fb 2065 "str %[TGL], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2066
Pokitto 65:deed4aa606fb 2067 "bne mode64loop%=" "\n"
Pokitto 65:deed4aa606fb 2068
Pokitto 65:deed4aa606fb 2069 : // outputs
Pokitto 65:deed4aa606fb 2070 [c]"+l" (c),
Pokitto 65:deed4aa606fb 2071 [t]"+l" (t),
Pokitto 65:deed4aa606fb 2072 [scrbuf]"+l" (scrbuf)
Pokitto 65:deed4aa606fb 2073
Pokitto 65:deed4aa606fb 2074 : // inputs
Pokitto 65:deed4aa606fb 2075 [CLR]"l" (CLR),
Pokitto 65:deed4aa606fb 2076 [TGL]"l" (TGL),
Pokitto 65:deed4aa606fb 2077 [LCD]"l" (0xA0002188),
Pokitto 65:deed4aa606fb 2078 [paletteptr]"l" (paletteptr),
Pokitto 65:deed4aa606fb 2079 [end]"h" (end)
Pokitto 65:deed4aa606fb 2080
Pokitto 65:deed4aa606fb 2081 : // clobbers
Pokitto 65:deed4aa606fb 2082 "cc"
Pokitto 65:deed4aa606fb 2083 );
Pokitto 65:deed4aa606fb 2084
Pokitto 65:deed4aa606fb 2085 #else
Pokitto 65:deed4aa606fb 2086
Pokitto 65:deed4aa606fb 2087 c = uint32_t(paletteptr[(*scrbuf)&255])<<3;
Pokitto 65:deed4aa606fb 2088 while( scrbuf < end-4 ){
Pokitto 65:deed4aa606fb 2089 *LCD = c; TGL_WR_OP(scrbuf++);TGL_WR_OP( c = uint32_t(paletteptr[(*scrbuf)&255])<<3 );
Pokitto 65:deed4aa606fb 2090 *LCD = c; TGL_WR_OP(scrbuf++);TGL_WR_OP( c = uint32_t(paletteptr[(*scrbuf)&255])<<3 );
Pokitto 65:deed4aa606fb 2091 *LCD = c; TGL_WR_OP(scrbuf++);TGL_WR_OP( c = uint32_t(paletteptr[(*scrbuf)&255])<<3 );
Pokitto 65:deed4aa606fb 2092 *LCD = c; TGL_WR_OP(scrbuf++);TGL_WR_OP( c = uint32_t(paletteptr[(*scrbuf)&255])<<3 );
Pokitto 65:deed4aa606fb 2093 }
Pokitto 65:deed4aa606fb 2094
Pokitto 65:deed4aa606fb 2095 #endif
Pokitto 65:deed4aa606fb 2096 }
Pokitto 65:deed4aa606fb 2097
Pokitto 65:deed4aa606fb 2098
Pokitto 65:deed4aa606fb 2099
Pokitto 46:e7e438368e16 2100 void Pokitto::lcdRefreshMode14(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 65:deed4aa606fb 2101 uint16_t x,y,data,xptr;
Pokitto 46:e7e438368e16 2102 uint16_t scanline[176]; uint16_t* scptr;
Pokitto 46:e7e438368e16 2103 uint8_t *d;
Pokitto 46:e7e438368e16 2104
Pokitto 46:e7e438368e16 2105 write_command(0x20); write_data(0);
Pokitto 46:e7e438368e16 2106 write_command(0x21); write_data(0);
Pokitto 46:e7e438368e16 2107 write_command(0x22);
Pokitto 46:e7e438368e16 2108 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 2109
Pokitto 46:e7e438368e16 2110 for(x=0;x<220;x++)
Pokitto 46:e7e438368e16 2111 {
Pokitto 46:e7e438368e16 2112 d = scrbuf+x;
Pokitto 46:e7e438368e16 2113 scptr = &scanline[0];
Pokitto 46:e7e438368e16 2114
Pokitto 46:e7e438368e16 2115 /** find colours in one scanline **/
Pokitto 46:e7e438368e16 2116 /*for(y=0;y<22;y++)
Pokitto 46:e7e438368e16 2117 {
Pokitto 46:e7e438368e16 2118
Pokitto 46:e7e438368e16 2119 uint16_t t = *d;
Pokitto 46:e7e438368e16 2120 uint16_t t2 = *(d+POK_BITFRAME);
Pokitto 46:e7e438368e16 2121 uint16_t t3 = *(d+POK_BITFRAME+POK_BITFRAME);
Pokitto 46:e7e438368e16 2122
Pokitto 46:e7e438368e16 2123 *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
Pokitto 46:e7e438368e16 2124 *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
Pokitto 46:e7e438368e16 2125 *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
Pokitto 46:e7e438368e16 2126 *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
Pokitto 46:e7e438368e16 2127
Pokitto 46:e7e438368e16 2128 *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
Pokitto 46:e7e438368e16 2129 *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
Pokitto 46:e7e438368e16 2130 *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
Pokitto 46:e7e438368e16 2131 *scptr++ = (t & 0x1)*R_MASK | (t2 & 0x1)*G_MASK | (t3 & 0x1)*B_MASK; t >>= 1;t2 >>= 1;t3 >>= 1;
Pokitto 46:e7e438368e16 2132
Pokitto 46:e7e438368e16 2133
Pokitto 46:e7e438368e16 2134 d+=220; // jump to word directly below
Pokitto 46:e7e438368e16 2135 }
Pokitto 46:e7e438368e16 2136 */
Pokitto 46:e7e438368e16 2137 /** alternative way: go through one color at a time **/
Pokitto 46:e7e438368e16 2138 scptr = &scanline[0]; // set to beginning of scanline
Pokitto 46:e7e438368e16 2139 for(y=0;y<22;y++, d +=220)
Pokitto 46:e7e438368e16 2140 {
Pokitto 46:e7e438368e16 2141 uint16_t t = *d & 0xFF;
Pokitto 46:e7e438368e16 2142
Pokitto 46:e7e438368e16 2143 *scptr++ = R_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2144 *scptr++ = R_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2145 *scptr++ = R_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2146 *scptr++ = R_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2147 *scptr++ = R_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2148 *scptr++ = R_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2149 *scptr++ = R_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2150 *scptr++ = R_MASK * (t&0x1);
Pokitto 46:e7e438368e16 2151 }
Pokitto 46:e7e438368e16 2152 scptr = &scanline[0]; // set to beginning of scanline
Pokitto 46:e7e438368e16 2153 d = scrbuf+x+POK_BITFRAME;
Pokitto 46:e7e438368e16 2154 for(y=0;y<22;y++, d +=220)
Pokitto 46:e7e438368e16 2155 {
Pokitto 46:e7e438368e16 2156 uint16_t t = *d & 0xFF;
Pokitto 46:e7e438368e16 2157
Pokitto 46:e7e438368e16 2158 *scptr++ |= G_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2159 *scptr++ |= G_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2160 *scptr++ |= G_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2161 *scptr++ |= G_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2162 *scptr++ |= G_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2163 *scptr++ |= G_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2164 *scptr++ |= G_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2165 *scptr++ |= G_MASK * (t&0x1);
Pokitto 46:e7e438368e16 2166 }
Pokitto 46:e7e438368e16 2167 scptr = &scanline[0]; // set to beginning of scanline
Pokitto 46:e7e438368e16 2168 d = scrbuf+x+POK_BITFRAME*2;
Pokitto 46:e7e438368e16 2169 for(y=0;y<22;y++, d +=220)
Pokitto 46:e7e438368e16 2170 {
Pokitto 46:e7e438368e16 2171 uint16_t t = *d & 0xFF;
Pokitto 46:e7e438368e16 2172
Pokitto 46:e7e438368e16 2173 *scptr++ |= B_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2174 *scptr++ |= B_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2175 *scptr++ |= B_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2176 *scptr++ |= B_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2177 *scptr++ |= B_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2178 *scptr++ |= B_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2179 *scptr++ |= B_MASK * (t&0x1); t >>= 1;
Pokitto 46:e7e438368e16 2180 *scptr++ |= B_MASK * (t&0x1);
Pokitto 46:e7e438368e16 2181 }
Pokitto 46:e7e438368e16 2182
Pokitto 46:e7e438368e16 2183
Pokitto 46:e7e438368e16 2184 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 2185 if (x<8) continue;
Pokitto 46:e7e438368e16 2186 setDRAMptr(x, 0);
Pokitto 46:e7e438368e16 2187 #endif
Pokitto 46:e7e438368e16 2188
Pokitto 46:e7e438368e16 2189 /** draw scanlines **/
Pokitto 46:e7e438368e16 2190 for (int s=0;s<176;) {
Pokitto 46:e7e438368e16 2191 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2192 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2193 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2194 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2195 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2196 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2197 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2198 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2199
Pokitto 46:e7e438368e16 2200 }
Pokitto 46:e7e438368e16 2201
Pokitto 46:e7e438368e16 2202 }
Pokitto 46:e7e438368e16 2203 }
Pokitto 46:e7e438368e16 2204
Pokitto 46:e7e438368e16 2205 //#define ADEKTOSMODE15
Pokitto 46:e7e438368e16 2206
Pokitto 46:e7e438368e16 2207 #ifdef ADEKTOSMODE15
Pokitto 46:e7e438368e16 2208 void Pokitto::lcdRefreshMode15(uint16_t* pal, uint8_t* scrbuf){
Pokitto 46:e7e438368e16 2209 write_command(0x03); write_data(0x1038); //realy only need to call this once
Pokitto 46:e7e438368e16 2210 write_command(0x20); write_data(0);
Pokitto 46:e7e438368e16 2211 write_command(0x21); write_data(0);
Pokitto 46:e7e438368e16 2212
Pokitto 46:e7e438368e16 2213 write_command(0x22);
Pokitto 46:e7e438368e16 2214
Pokitto 46:e7e438368e16 2215 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 2216 for (int x=0,xt=0; x<0x4BA0;x++,xt++) {
Pokitto 46:e7e438368e16 2217 if (xt==110) xt=0;
Pokitto 46:e7e438368e16 2218 if (xt<8) {
Pokitto 46:e7e438368e16 2219 write_data(0);
Pokitto 46:e7e438368e16 2220 write_data(0);
Pokitto 46:e7e438368e16 2221 } else {
Pokitto 46:e7e438368e16 2222 write_data(pal[(((scrbuf[x]) & 0xf0) >> 4)]);
Pokitto 46:e7e438368e16 2223 write_data(pal[( (scrbuf[x]) & 0x0f)]);
Pokitto 46:e7e438368e16 2224 }
Pokitto 46:e7e438368e16 2225
Pokitto 46:e7e438368e16 2226 }
Pokitto 46:e7e438368e16 2227 #else
Pokitto 46:e7e438368e16 2228 for (int x=0; x<0x4BA0;x++) {
Pokitto 46:e7e438368e16 2229 write_data(pal[(((scrbuf[x]) & 0xf0) >> 4)]);
Pokitto 46:e7e438368e16 2230 write_data(pal[( (scrbuf[x]) & 0x0f)]);
Pokitto 46:e7e438368e16 2231 }
Pokitto 46:e7e438368e16 2232 #endif //PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 2233 }
Pokitto 46:e7e438368e16 2234
Pokitto 46:e7e438368e16 2235 #else
Pokitto 46:e7e438368e16 2236
Pokitto 46:e7e438368e16 2237 void Pokitto::lcdRefreshMode15(uint16_t* paletteptr, uint8_t* scrbuf){
Pokitto 65:deed4aa606fb 2238 // #define __ARMCC_VERSION
Pokitto 65:deed4aa606fb 2239 #ifndef __ARMCC_VERSION
Pokitto 65:deed4aa606fb 2240
Pokitto 65:deed4aa606fb 2241 #define MODE15_LOOP \
Pokitto 65:deed4aa606fb 2242 "ands %[tmp], %[color]" "\n" \
Pokitto 65:deed4aa606fb 2243 "lsrs %[tmp], 2" "\n" \
Pokitto 65:deed4aa606fb 2244 "ldr %[tmp], [%[palette], %[tmp]]" "\n" \
Pokitto 65:deed4aa606fb 2245 "str %[tmp], [%[LCD]]" "\n" \
Pokitto 65:deed4aa606fb 2246 "str %[WRBit], [%[LCD], %[CLR]]" "\n" \
Pokitto 65:deed4aa606fb 2247 "movs %[tmp], 0x0F" "\n" \
Pokitto 65:deed4aa606fb 2248 "ands %[tmp], %[color]" "\n" \
Pokitto 65:deed4aa606fb 2249 "str %[WRBit], [%[LCD], 124]" "\n" \
Pokitto 65:deed4aa606fb 2250 "lsls %[tmp], 2" "\n" \
Pokitto 65:deed4aa606fb 2251 "ldr %[tmp], [%[palette], %[tmp]]" "\n" \
Pokitto 65:deed4aa606fb 2252 "str %[tmp], [%[LCD]]" "\n" \
Pokitto 65:deed4aa606fb 2253 "str %[WRBit], [%[LCD], %[CLR]]" "\n" \
Pokitto 65:deed4aa606fb 2254 "movs %[tmp], 0xF0" "\n" \
Pokitto 65:deed4aa606fb 2255 "lsrs %[color], 8" "\n" \
Pokitto 65:deed4aa606fb 2256 "str %[WRBit], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2257
Pokitto 65:deed4aa606fb 2258 #define MODE15_ENDLOOP \
Pokitto 65:deed4aa606fb 2259 "ands %[tmp], %[color]" "\n" \
Pokitto 65:deed4aa606fb 2260 "lsrs %[tmp], 2" "\n" \
Pokitto 65:deed4aa606fb 2261 "ldr %[tmp], [%[palette], %[tmp]]" "\n" \
Pokitto 65:deed4aa606fb 2262 "str %[tmp], [%[LCD]]" "\n" \
Pokitto 65:deed4aa606fb 2263 "str %[WRBit], [%[LCD], %[CLR]]" "\n" \
Pokitto 65:deed4aa606fb 2264 "movs %[tmp], 0x0F" "\n" \
Pokitto 65:deed4aa606fb 2265 "ands %[tmp], %[color]" "\n" \
Pokitto 65:deed4aa606fb 2266 "str %[WRBit], [%[LCD], 124]" "\n" \
Pokitto 65:deed4aa606fb 2267 "lsls %[tmp], 2" "\n" \
Pokitto 65:deed4aa606fb 2268 "ldr %[tmp], [%[palette], %[tmp]]" "\n" \
Pokitto 65:deed4aa606fb 2269 "str %[tmp], [%[LCD]]" "\n" \
Pokitto 65:deed4aa606fb 2270 "str %[WRBit], [%[LCD], %[CLR]]" "\n" \
Pokitto 65:deed4aa606fb 2271 "ldm %[scrbuf]!, {%[color]}" "\n" \
Pokitto 65:deed4aa606fb 2272 "movs %[tmp], 0xF0" "\n" \
Pokitto 65:deed4aa606fb 2273 "str %[WRBit], [%[LCD], 124]" "\n"
Pokitto 65:deed4aa606fb 2274
Pokitto 65:deed4aa606fb 2275 uint8_t *end=&scrbuf[POK_SCREENBUFFERSIZE]+4;
Pokitto 65:deed4aa606fb 2276 volatile uint32_t palette[16];
Pokitto 65:deed4aa606fb 2277 for( uint32_t i=0; i<16; ++i )
Pokitto 65:deed4aa606fb 2278 palette[i] = uint32_t(paletteptr[i]) << 3;
Pokitto 65:deed4aa606fb 2279
Pokitto 65:deed4aa606fb 2280 write_command(0x03); write_data(0x1038);
Pokitto 65:deed4aa606fb 2281 write_command(0x21); // Vertical DRAM Address
Pokitto 65:deed4aa606fb 2282 write_data(0);
Pokitto 65:deed4aa606fb 2283 write_command(0x20); // Horizontal DRAM Address
Pokitto 65:deed4aa606fb 2284 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 65:deed4aa606fb 2285 write_data(8);
Pokitto 65:deed4aa606fb 2286 scrbuf += 110*8;
Pokitto 65:deed4aa606fb 2287 #else
Pokitto 65:deed4aa606fb 2288 write_data(0);
Pokitto 65:deed4aa606fb 2289 #endif
Pokitto 65:deed4aa606fb 2290 write_command(0x22); // write data to DRAM
Pokitto 65:deed4aa606fb 2291 CLR_CS_SET_CD_RD_WR;
Pokitto 65:deed4aa606fb 2292
Pokitto 65:deed4aa606fb 2293
Pokitto 65:deed4aa606fb 2294 SET_MASK_P2;
Pokitto 65:deed4aa606fb 2295
Pokitto 65:deed4aa606fb 2296 uint32_t WRBit = 1<<12, color, tmp;
Pokitto 65:deed4aa606fb 2297 asm volatile(
Pokitto 65:deed4aa606fb 2298 ".syntax unified" "\n"
Pokitto 65:deed4aa606fb 2299 "ldm %[scrbuf]!, {%[color]}" "\n"
Pokitto 65:deed4aa606fb 2300 "movs %[tmp], 0xF0" "\n"
Pokitto 65:deed4aa606fb 2301 "mode15Loop%=:" "\n"
Pokitto 65:deed4aa606fb 2302 MODE15_LOOP
Pokitto 65:deed4aa606fb 2303 MODE15_LOOP
Pokitto 65:deed4aa606fb 2304 MODE15_LOOP
Pokitto 65:deed4aa606fb 2305 MODE15_ENDLOOP
Pokitto 65:deed4aa606fb 2306 "cmp %[end], %[scrbuf]" "\n"
Pokitto 65:deed4aa606fb 2307 "bne mode15Loop%=" "\n"
Pokitto 65:deed4aa606fb 2308 :
Pokitto 65:deed4aa606fb 2309 [tmp]"+l" (tmp),
Pokitto 65:deed4aa606fb 2310 [color]"+l" (color),
Pokitto 65:deed4aa606fb 2311 [end]"+h" (end),
Pokitto 65:deed4aa606fb 2312 [scrbuf]"+l" (scrbuf),
Pokitto 65:deed4aa606fb 2313 [WRBit]"+l" (WRBit)
Pokitto 65:deed4aa606fb 2314
Pokitto 65:deed4aa606fb 2315 :
Pokitto 65:deed4aa606fb 2316 [CLR]"l" (252),
Pokitto 65:deed4aa606fb 2317 [LCD]"l" (0xA0002188),
Pokitto 65:deed4aa606fb 2318 [palette]"l" (palette)
Pokitto 65:deed4aa606fb 2319
Pokitto 65:deed4aa606fb 2320 :
Pokitto 65:deed4aa606fb 2321 "cc"
Pokitto 65:deed4aa606fb 2322 );
Pokitto 65:deed4aa606fb 2323
Pokitto 65:deed4aa606fb 2324 #else
Pokitto 65:deed4aa606fb 2325
Pokitto 65:deed4aa606fb 2326 uint16_t x,y,xptr;
Pokitto 46:e7e438368e16 2327 uint16_t scanline[2][176]; // read two nibbles = pixels at a time
Pokitto 65:deed4aa606fb 2328 uint8_t *d, yoffset=0;
Pokitto 46:e7e438368e16 2329
Pokitto 65:deed4aa606fb 2330 xptr = 0;
Pokitto 46:e7e438368e16 2331 //setDRAMptr(xptr,yoffset);
Pokitto 46:e7e438368e16 2332
Pokitto 46:e7e438368e16 2333 write_command(0x20); write_data(0);
Pokitto 46:e7e438368e16 2334 write_command(0x21); write_data(0);
Pokitto 46:e7e438368e16 2335 write_command(0x22);
Pokitto 46:e7e438368e16 2336 CLR_CS_SET_CD_RD_WR;
Pokitto 46:e7e438368e16 2337
Pokitto 46:e7e438368e16 2338 for(x=0;x<220;x+=2)
Pokitto 46:e7e438368e16 2339 {
Pokitto 46:e7e438368e16 2340 d = scrbuf+(x>>1);// point to beginning of line in data
Pokitto 46:e7e438368e16 2341 // find colours in one scanline
Pokitto 46:e7e438368e16 2342 uint8_t s=0;
Pokitto 46:e7e438368e16 2343 for(y=0;y<176;y++)
Pokitto 46:e7e438368e16 2344 {
Pokitto 46:e7e438368e16 2345 uint8_t t = *d >> 4; // higher nibble
Pokitto 46:e7e438368e16 2346 uint8_t t2 = *d & 0xF; // lower nibble
Pokitto 46:e7e438368e16 2347 // higher nibble = left pixel in pixel pair
Pokitto 46:e7e438368e16 2348 scanline[0][s] = paletteptr[t];
Pokitto 46:e7e438368e16 2349 scanline[1][s++] = paletteptr[t2];
Pokitto 46:e7e438368e16 2350
Pokitto 46:e7e438368e16 2351 d+=220/2; // jump to read byte directly below in screenbuffer
Pokitto 46:e7e438368e16 2352 }
Pokitto 46:e7e438368e16 2353 s=0;
Pokitto 46:e7e438368e16 2354 // draw scanlines
Pokitto 46:e7e438368e16 2355
Pokitto 46:e7e438368e16 2356 #ifdef PROJ_SHOW_FPS_COUNTER
Pokitto 46:e7e438368e16 2357 if (x<8) continue;
Pokitto 46:e7e438368e16 2358 setDRAMptr(x, 0);
Pokitto 46:e7e438368e16 2359 #endif
Pokitto 46:e7e438368e16 2360
Pokitto 46:e7e438368e16 2361 for (s=0;s<176;) {
Pokitto 46:e7e438368e16 2362 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2363 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2364 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2365 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2366 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2367 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2368 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2369 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2370 }
Pokitto 46:e7e438368e16 2371
Pokitto 46:e7e438368e16 2372 for (s=0;s<176;) {
Pokitto 46:e7e438368e16 2373 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2374 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2375 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2376 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2377 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2378 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2379 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2380 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2381 }
Pokitto 46:e7e438368e16 2382 }
Pokitto 65:deed4aa606fb 2383
Pokitto 65:deed4aa606fb 2384 #endif
Pokitto 65:deed4aa606fb 2385
Pokitto 46:e7e438368e16 2386 }
Pokitto 46:e7e438368e16 2387 #endif //ADEKTOSMODE15
Pokitto 46:e7e438368e16 2388
Pokitto 65:deed4aa606fb 2389 void Pokitto::lcdRefreshMixMode(const uint8_t * screenBuffer, const uint16_t * palettePointer, const uint8_t * scanType)
Pokitto 65:deed4aa606fb 2390 {
Pokitto 65:deed4aa606fb 2391 write_command(0x03);
Pokitto 65:deed4aa606fb 2392 write_data(0x1038);
Pokitto 65:deed4aa606fb 2393
Pokitto 65:deed4aa606fb 2394 // Horizontal DRAM Address
Pokitto 65:deed4aa606fb 2395 write_command(0x20);
Pokitto 65:deed4aa606fb 2396 write_data(0);
Pokitto 65:deed4aa606fb 2397
Pokitto 65:deed4aa606fb 2398 // Vertical DRAM Address
Pokitto 65:deed4aa606fb 2399 write_command(0x21);
Pokitto 65:deed4aa606fb 2400 write_data(0);
Pokitto 65:deed4aa606fb 2401
Pokitto 65:deed4aa606fb 2402 // write data to DRAM
Pokitto 65:deed4aa606fb 2403 write_command(0x22);
Pokitto 65:deed4aa606fb 2404 CLR_CS_SET_CD_RD_WR;
Pokitto 65:deed4aa606fb 2405 SET_MASK_P2;
Pokitto 65:deed4aa606fb 2406
Pokitto 65:deed4aa606fb 2407 uint32_t scanline[220];
Pokitto 65:deed4aa606fb 2408
Pokitto 65:deed4aa606fb 2409 // point to beginning of line in data
Pokitto 65:deed4aa606fb 2410 const uint8_t * d = screenBuffer;
Pokitto 65:deed4aa606fb 2411 for(uint32_t y = 0; y < 176; ++y)
Pokitto 65:deed4aa606fb 2412 {
Pokitto 65:deed4aa606fb 2413 // find colours in one scanline
Pokitto 65:deed4aa606fb 2414 uint8_t scanTypeIndex = y >> 1;
Pokitto 65:deed4aa606fb 2415 uint8_t lineIndex = 0;
Pokitto 65:deed4aa606fb 2416 switch(scanType[scanTypeIndex])
Pokitto 65:deed4aa606fb 2417 {
Pokitto 65:deed4aa606fb 2418 case 0:
Pokitto 65:deed4aa606fb 2419 {
Pokitto 65:deed4aa606fb 2420 // point to beginning of line in data
Pokitto 65:deed4aa606fb 2421 d = &screenBuffer[110 * scanTypeIndex];
Pokitto 65:deed4aa606fb 2422 for(uint8_t x = 0; x < (220 / 2); ++x)
Pokitto 65:deed4aa606fb 2423 {
Pokitto 65:deed4aa606fb 2424 uint32_t color = static_cast<uint32_t>(palettePointer[*d]) << 3;
Pokitto 65:deed4aa606fb 2425 ++d;
Pokitto 65:deed4aa606fb 2426 scanline[lineIndex] = color;
Pokitto 65:deed4aa606fb 2427 ++lineIndex;
Pokitto 65:deed4aa606fb 2428 scanline[lineIndex] = color;
Pokitto 65:deed4aa606fb 2429 ++lineIndex;
Pokitto 65:deed4aa606fb 2430 }
Pokitto 65:deed4aa606fb 2431 break;
Pokitto 65:deed4aa606fb 2432 }
Pokitto 65:deed4aa606fb 2433 case 1:
Pokitto 65:deed4aa606fb 2434 {
Pokitto 65:deed4aa606fb 2435 for(uint8_t x = 0; x < (220 / 4); ++x)
Pokitto 65:deed4aa606fb 2436 {
Pokitto 65:deed4aa606fb 2437 uint8_t t = *d;
Pokitto 65:deed4aa606fb 2438 ++d;
Pokitto 65:deed4aa606fb 2439
Pokitto 65:deed4aa606fb 2440 uint32_t color1 = static_cast<uint32_t>(palettePointer[256 + (t >> 4)]) << 3;
Pokitto 65:deed4aa606fb 2441 scanline[lineIndex] = color1;
Pokitto 65:deed4aa606fb 2442 ++lineIndex;
Pokitto 65:deed4aa606fb 2443 scanline[lineIndex] = color1;
Pokitto 65:deed4aa606fb 2444 ++lineIndex;
Pokitto 65:deed4aa606fb 2445
Pokitto 65:deed4aa606fb 2446 uint32_t color2 = static_cast<uint32_t>(palettePointer[256 + (t & 0xF)]) << 3;
Pokitto 65:deed4aa606fb 2447 scanline[lineIndex] = color2;
Pokitto 65:deed4aa606fb 2448 ++lineIndex;
Pokitto 65:deed4aa606fb 2449 scanline[lineIndex] = color2;
Pokitto 65:deed4aa606fb 2450 ++lineIndex;
Pokitto 65:deed4aa606fb 2451 }
Pokitto 65:deed4aa606fb 2452 break;
Pokitto 65:deed4aa606fb 2453 }
Pokitto 65:deed4aa606fb 2454 case 2:
Pokitto 65:deed4aa606fb 2455 {
Pokitto 65:deed4aa606fb 2456 for(uint8_t x = 0; x < (220 / 4); ++x)
Pokitto 65:deed4aa606fb 2457 {
Pokitto 65:deed4aa606fb 2458 uint8_t t = *d;
Pokitto 65:deed4aa606fb 2459 ++d;
Pokitto 65:deed4aa606fb 2460
Pokitto 65:deed4aa606fb 2461 scanline[lineIndex] = static_cast<uint32_t>(palettePointer[272 + ((t >> 6) & 0x03)]) << 3;
Pokitto 65:deed4aa606fb 2462 ++lineIndex;
Pokitto 65:deed4aa606fb 2463
Pokitto 65:deed4aa606fb 2464 scanline[lineIndex] = static_cast<uint32_t>(palettePointer[272 + ((t >> 4) & 0x03)]) << 3;
Pokitto 65:deed4aa606fb 2465 ++lineIndex;
Pokitto 65:deed4aa606fb 2466
Pokitto 65:deed4aa606fb 2467 scanline[lineIndex] = static_cast<uint32_t>(palettePointer[272 + ((t >> 2) & 0x03)]) << 3;
Pokitto 65:deed4aa606fb 2468 ++lineIndex;
Pokitto 65:deed4aa606fb 2469
Pokitto 65:deed4aa606fb 2470 scanline[lineIndex] = static_cast<uint32_t>(palettePointer[272 + ((t >> 0) & 0x03)]) << 3;
Pokitto 65:deed4aa606fb 2471 ++lineIndex;
Pokitto 65:deed4aa606fb 2472 }
Pokitto 65:deed4aa606fb 2473 break;
Pokitto 65:deed4aa606fb 2474 }
Pokitto 65:deed4aa606fb 2475 }
Pokitto 65:deed4aa606fb 2476
Pokitto 65:deed4aa606fb 2477 uint32_t color = scanline[0];
Pokitto 65:deed4aa606fb 2478 #define WRITE_SCANLINE *LCD = color; TGL_WR_OP(color = scanline[++i]);
Pokitto 65:deed4aa606fb 2479
Pokitto 65:deed4aa606fb 2480 volatile uint32_t * LCD = reinterpret_cast< volatile uint32_t * >(0xA0002188);
Pokitto 65:deed4aa606fb 2481 for (uint8_t i = 0; i < 220;)
Pokitto 65:deed4aa606fb 2482 {
Pokitto 65:deed4aa606fb 2483 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2484 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2485 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2486 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2487 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2488 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2489 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2490 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2491 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2492 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2493 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2494 WRITE_SCANLINE WRITE_SCANLINE WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2495 }
Pokitto 65:deed4aa606fb 2496
Pokitto 65:deed4aa606fb 2497 #undef WRITE_SCANLINE
Pokitto 65:deed4aa606fb 2498 }
Pokitto 65:deed4aa606fb 2499
Pokitto 65:deed4aa606fb 2500 CLR_MASK_P2;
Pokitto 65:deed4aa606fb 2501 }
Pokitto 65:deed4aa606fb 2502
Pokitto 65:deed4aa606fb 2503
Pokitto 46:e7e438368e16 2504 void Pokitto::blitWord(uint16_t c) {
Pokitto 46:e7e438368e16 2505 setup_data_16(c);CLR_WR;SET_WR;
Pokitto 46:e7e438368e16 2506 }
Pokitto 46:e7e438368e16 2507
Pokitto 46:e7e438368e16 2508
Pokitto 65:deed4aa606fb 2509