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

Committer:
Pokitto
Date:
Tue Jan 30 10:41:47 2018 +0000
Revision:
31:f4b9b85c7b62
Sound output improvements added:  louder, clearer, faster!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pokitto 31:f4b9b85c7b62 1 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 2 /*!
Pokitto 31:f4b9b85c7b62 3 @file HWLCD.cpp
Pokitto 31:f4b9b85c7b62 4 @author Jonne Valola
Pokitto 31:f4b9b85c7b62 5
Pokitto 31:f4b9b85c7b62 6 @section LICENSE
Pokitto 31:f4b9b85c7b62 7
Pokitto 31:f4b9b85c7b62 8 Software License Agreement (BSD License)
Pokitto 31:f4b9b85c7b62 9
Pokitto 31:f4b9b85c7b62 10 Copyright (c) 2016, Jonne Valola
Pokitto 31:f4b9b85c7b62 11 All rights reserved.
Pokitto 31:f4b9b85c7b62 12
Pokitto 31:f4b9b85c7b62 13 Redistribution and use in source and binary forms, with or without
Pokitto 31:f4b9b85c7b62 14 modification, are permitted provided that the following conditions are met:
Pokitto 31:f4b9b85c7b62 15 1. Redistributions of source code must retain the above copyright
Pokitto 31:f4b9b85c7b62 16 notice, this list of conditions and the following disclaimer.
Pokitto 31:f4b9b85c7b62 17 2. Redistributions in binary form must reproduce the above copyright
Pokitto 31:f4b9b85c7b62 18 notice, this list of conditions and the following disclaimer in the
Pokitto 31:f4b9b85c7b62 19 documentation and/or other materials provided with the distribution.
Pokitto 31:f4b9b85c7b62 20 3. Neither the name of the copyright holders nor the
Pokitto 31:f4b9b85c7b62 21 names of its contributors may be used to endorse or promote products
Pokitto 31:f4b9b85c7b62 22 derived from this software without specific prior written permission.
Pokitto 31:f4b9b85c7b62 23
Pokitto 31:f4b9b85c7b62 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
Pokitto 31:f4b9b85c7b62 25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Pokitto 31:f4b9b85c7b62 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Pokitto 31:f4b9b85c7b62 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
Pokitto 31:f4b9b85c7b62 28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Pokitto 31:f4b9b85c7b62 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Pokitto 31:f4b9b85c7b62 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
Pokitto 31:f4b9b85c7b62 31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Pokitto 31:f4b9b85c7b62 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Pokitto 31:f4b9b85c7b62 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Pokitto 31:f4b9b85c7b62 34 */
Pokitto 31:f4b9b85c7b62 35 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 36
Pokitto 31:f4b9b85c7b62 37 #include "HWLCD.h" //HWLCD.h" #include "HWLCD.h"
Pokitto 31:f4b9b85c7b62 38 #include "Pokitto_settings.h"
Pokitto 31:f4b9b85c7b62 39
Pokitto 31:f4b9b85c7b62 40 #ifndef DISABLEAVRMIN
Pokitto 31:f4b9b85c7b62 41 #define max(a,b) ((a)>(b)?(a):(b))
Pokitto 31:f4b9b85c7b62 42 #define min(a,b) ((a)<(b)?(a):(b))
Pokitto 31:f4b9b85c7b62 43 #endif // DISABLEAVRMIN
Pokitto 31:f4b9b85c7b62 44
Pokitto 31:f4b9b85c7b62 45 #define AB_JUMP 1024 // jump one 1-bit Arduboy screen forward to get next color bit
Pokitto 31:f4b9b85c7b62 46 #define GB_JUMP 504 // jump one 1-bit Gamebuino screen forward to get next color bit
Pokitto 31:f4b9b85c7b62 47
Pokitto 31:f4b9b85c7b62 48 using namespace Pokitto;
Pokitto 31:f4b9b85c7b62 49
Pokitto 31:f4b9b85c7b62 50 uint16_t prevdata=0; // if data does not change, do not adjust LCD bus lines
Pokitto 31:f4b9b85c7b62 51
Pokitto 31:f4b9b85c7b62 52 #if POK_BOARDREV == 2
Pokitto 31:f4b9b85c7b62 53 pwmout_t backlightpwm;
Pokitto 31:f4b9b85c7b62 54 #endif
Pokitto 31:f4b9b85c7b62 55
Pokitto 31:f4b9b85c7b62 56
Pokitto 31:f4b9b85c7b62 57 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 58 /*!
Pokitto 31:f4b9b85c7b62 59 @brief set up the 16-bit bus
Pokitto 31:f4b9b85c7b62 60 */
Pokitto 31:f4b9b85c7b62 61 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 62
Pokitto 31:f4b9b85c7b62 63 static inline void setup_data_16(uint16_t data)
Pokitto 31:f4b9b85c7b62 64 {
Pokitto 31:f4b9b85c7b62 65 uint32_t p2=0;
Pokitto 31:f4b9b85c7b62 66
Pokitto 31:f4b9b85c7b62 67 if (data != prevdata) {
Pokitto 31:f4b9b85c7b62 68
Pokitto 31:f4b9b85c7b62 69 prevdata=data;
Pokitto 31:f4b9b85c7b62 70
Pokitto 31:f4b9b85c7b62 71 /** D0...D16 = P2_3 ... P2_18 **/
Pokitto 31:f4b9b85c7b62 72 p2 = data << 3;
Pokitto 31:f4b9b85c7b62 73
Pokitto 31:f4b9b85c7b62 74 //__disable_irq(); // Disable Interrupts
Pokitto 31:f4b9b85c7b62 75 SET_MASK_P2;
Pokitto 31:f4b9b85c7b62 76 LPC_GPIO_PORT->MPIN[2] = p2; // write bits to port
Pokitto 31:f4b9b85c7b62 77 CLR_MASK_P2;
Pokitto 31:f4b9b85c7b62 78 //__enable_irq(); // Enable Interrupts
Pokitto 31:f4b9b85c7b62 79 }
Pokitto 31:f4b9b85c7b62 80 }
Pokitto 31:f4b9b85c7b62 81
Pokitto 31:f4b9b85c7b62 82
Pokitto 31:f4b9b85c7b62 83 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 84 /*!
Pokitto 31:f4b9b85c7b62 85 @brief Write a command to the lcd, 16-bit bus
Pokitto 31:f4b9b85c7b62 86 */
Pokitto 31:f4b9b85c7b62 87 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 88 inline void write_command_16(uint16_t data)
Pokitto 31:f4b9b85c7b62 89 {
Pokitto 31:f4b9b85c7b62 90 CLR_CS; // select lcd
Pokitto 31:f4b9b85c7b62 91 CLR_CD; // clear CD = command
Pokitto 31:f4b9b85c7b62 92 SET_RD; // RD high, do not read
Pokitto 31:f4b9b85c7b62 93 setup_data_16(data); // function that inputs the data into the relevant bus lines
Pokitto 31:f4b9b85c7b62 94 CLR_WR; // WR low
Pokitto 31:f4b9b85c7b62 95 SET_WR; // WR low, then high = write strobe
Pokitto 31:f4b9b85c7b62 96 SET_CS; // de-select lcd
Pokitto 31:f4b9b85c7b62 97 }
Pokitto 31:f4b9b85c7b62 98
Pokitto 31:f4b9b85c7b62 99 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 100 /*!
Pokitto 31:f4b9b85c7b62 101 @brief Write data to the lcd, 16-bit bus
Pokitto 31:f4b9b85c7b62 102 */
Pokitto 31:f4b9b85c7b62 103 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 104 inline void write_data_16(uint16_t data)
Pokitto 31:f4b9b85c7b62 105 {
Pokitto 31:f4b9b85c7b62 106 CLR_CS;
Pokitto 31:f4b9b85c7b62 107 SET_CD;
Pokitto 31:f4b9b85c7b62 108 SET_RD;
Pokitto 31:f4b9b85c7b62 109 setup_data_16(data);
Pokitto 31:f4b9b85c7b62 110 CLR_WR;
Pokitto 31:f4b9b85c7b62 111 SET_WR;
Pokitto 31:f4b9b85c7b62 112 SET_CS;
Pokitto 31:f4b9b85c7b62 113 }
Pokitto 31:f4b9b85c7b62 114
Pokitto 31:f4b9b85c7b62 115 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 116 /*!
Pokitto 31:f4b9b85c7b62 117 @brief Point to a (x,y) location in the LCD DRAM
Pokitto 31:f4b9b85c7b62 118 */
Pokitto 31:f4b9b85c7b62 119 /**************************************************************************/
Pokitto 31:f4b9b85c7b62 120 static inline void setDRAMptr(uint8_t xptr, uint8_t yoffset)
Pokitto 31:f4b9b85c7b62 121 {
Pokitto 31:f4b9b85c7b62 122 write_command(0x20); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 123 write_data(yoffset);
Pokitto 31:f4b9b85c7b62 124 write_command(0x21); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 125 write_data(xptr); //
Pokitto 31:f4b9b85c7b62 126 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 127 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 128 }
Pokitto 31:f4b9b85c7b62 129
Pokitto 31:f4b9b85c7b62 130 void Pokitto::initBacklight() {
Pokitto 31:f4b9b85c7b62 131 #if POK_BOARDREV == 2
Pokitto 31:f4b9b85c7b62 132 pwmout_init(&backlightpwm,POK_BACKLIGHT_PIN);
Pokitto 31:f4b9b85c7b62 133 pwmout_period_us(&backlightpwm,5);
Pokitto 31:f4b9b85c7b62 134 pwmout_write(&backlightpwm,POK_BACKLIGHT_INITIALVALUE);
Pokitto 31:f4b9b85c7b62 135 #endif
Pokitto 31:f4b9b85c7b62 136 }
Pokitto 31:f4b9b85c7b62 137
Pokitto 31:f4b9b85c7b62 138 void Pokitto::setBacklight(float value) {
Pokitto 31:f4b9b85c7b62 139 if (value>0.999f) value = 0.999f;
Pokitto 31:f4b9b85c7b62 140 pwmout_write(&backlightpwm,value);
Pokitto 31:f4b9b85c7b62 141 }
Pokitto 31:f4b9b85c7b62 142
Pokitto 31:f4b9b85c7b62 143 void Pokitto::lcdInit() {
Pokitto 31:f4b9b85c7b62 144 initBacklight();
Pokitto 31:f4b9b85c7b62 145
Pokitto 31:f4b9b85c7b62 146 SET_RESET;
Pokitto 31:f4b9b85c7b62 147 wait_ms(10);
Pokitto 31:f4b9b85c7b62 148 CLR_RESET;
Pokitto 31:f4b9b85c7b62 149 wait_ms(10);
Pokitto 31:f4b9b85c7b62 150 SET_RESET;
Pokitto 31:f4b9b85c7b62 151 wait_ms(10);
Pokitto 31:f4b9b85c7b62 152 //************* Start Initial Sequence **********//
Pokitto 31:f4b9b85c7b62 153 write_command(0x01); // driver output control, this also affects direction
Pokitto 31:f4b9b85c7b62 154 write_data(0x11C); // originally: 0x11C 100011100 SS,NL4,NL3,NL2
Pokitto 31:f4b9b85c7b62 155 // NL4...0 is the number of scan lines to drive the screen !!!
Pokitto 31:f4b9b85c7b62 156 // so 11100 is 1c = 220 lines, correct
Pokitto 31:f4b9b85c7b62 157 // test 1: 0x1C 11100 SS=0,NL4,NL3,NL2 -> no effect
Pokitto 31:f4b9b85c7b62 158 // test 2: 0x31C 1100011100 GS=1,SS=1,NL4,NL3,NL2 -> no effect
Pokitto 31:f4b9b85c7b62 159 // test 3: 0x51C 10100011100 SM=1,GS=0,SS=1,NL4,NL3,NL2 -> no effect
Pokitto 31:f4b9b85c7b62 160 // test 4: 0x71C SM=1,GS=1,SS=1,NL4,NL3,NL2
Pokitto 31:f4b9b85c7b62 161 // test 5: 0x
Pokitto 31:f4b9b85c7b62 162 // seems to have no effect... is this perhaps only for RGB mode ?
Pokitto 31:f4b9b85c7b62 163
Pokitto 31:f4b9b85c7b62 164 write_command(0x02); // LCD driving control
Pokitto 31:f4b9b85c7b62 165 write_data(0x0100); // INV = 1
Pokitto 31:f4b9b85c7b62 166
Pokitto 31:f4b9b85c7b62 167 write_command(0x03); // Entry mode... lets try if this affects the direction
Pokitto 31:f4b9b85c7b62 168 write_data(0x1030); // originally 0x1030 1000000110000 BGR,ID1,ID0
Pokitto 31:f4b9b85c7b62 169 // test 1: 0x1038 1000000111000 BGR,ID1,ID0,AM=1 ->drawing DRAM horizontally
Pokitto 31:f4b9b85c7b62 170 // test 4: am=1, id0=0, id1=0, 1000000001000,0x1008 -> same as above, but flipped on long
Pokitto 31:f4b9b85c7b62 171 // test 2: am=0, id0=0, 1000000100000, 0x1020 -> flipped on long axis
Pokitto 31:f4b9b85c7b62 172 // test 3: am=0, id1=0, 1000000010000, 0x1010 -> picture flowed over back to screen
Pokitto 31:f4b9b85c7b62 173
Pokitto 31:f4b9b85c7b62 174
Pokitto 31:f4b9b85c7b62 175 write_command(0x08); // Display control 2
Pokitto 31:f4b9b85c7b62 176 write_data(0x0808); // 100000001000 FP2,BP2
Pokitto 31:f4b9b85c7b62 177
Pokitto 31:f4b9b85c7b62 178 write_command(0x0C); // RGB display interface
Pokitto 31:f4b9b85c7b62 179 write_data(0x0000); // all off
Pokitto 31:f4b9b85c7b62 180
Pokitto 31:f4b9b85c7b62 181 write_command(0x0F); // Frame marker position
Pokitto 31:f4b9b85c7b62 182 write_data(0x0001); // OSC_EN
Pokitto 31:f4b9b85c7b62 183
Pokitto 31:f4b9b85c7b62 184 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 185 write_data(0x0000); // 0
Pokitto 31:f4b9b85c7b62 186
Pokitto 31:f4b9b85c7b62 187 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 188 write_data(0x0000); // 0
Pokitto 31:f4b9b85c7b62 189
Pokitto 31:f4b9b85c7b62 190 //*************Power On sequence ****************//
Pokitto 31:f4b9b85c7b62 191 write_command(0x10);
Pokitto 31:f4b9b85c7b62 192 write_data(0x0000);
Pokitto 31:f4b9b85c7b62 193
Pokitto 31:f4b9b85c7b62 194 write_command(0x11);
Pokitto 31:f4b9b85c7b62 195 write_data(0x1000);
Pokitto 31:f4b9b85c7b62 196 wait_ms(10);
Pokitto 31:f4b9b85c7b62 197 //------------------------ Set GRAM area --------------------------------//
Pokitto 31:f4b9b85c7b62 198 write_command(0x30); // Gate scan position
Pokitto 31:f4b9b85c7b62 199 write_data(0x0000); // if GS=0, 00h=G1, else 00h=G220
Pokitto 31:f4b9b85c7b62 200
Pokitto 31:f4b9b85c7b62 201 write_command(0x31); // Vertical scroll control
Pokitto 31:f4b9b85c7b62 202 write_data(0x00DB); // scroll start line 11011011 = 219
Pokitto 31:f4b9b85c7b62 203
Pokitto 31:f4b9b85c7b62 204 write_command(0x32); // Vertical scroll control
Pokitto 31:f4b9b85c7b62 205 write_data(0x0000); // scroll end line 0
Pokitto 31:f4b9b85c7b62 206
Pokitto 31:f4b9b85c7b62 207 write_command(0x33); // Vertical scroll control
Pokitto 31:f4b9b85c7b62 208 write_data(0x0000); // 0=vertical scroll disabled
Pokitto 31:f4b9b85c7b62 209
Pokitto 31:f4b9b85c7b62 210 write_command(0x34); // Partial screen driving control
Pokitto 31:f4b9b85c7b62 211 write_data(0x00DB); // db = full screen (end)
Pokitto 31:f4b9b85c7b62 212
Pokitto 31:f4b9b85c7b62 213 write_command(0x35); // partial screen
Pokitto 31:f4b9b85c7b62 214 write_data(0x0000); // 0 = start
Pokitto 31:f4b9b85c7b62 215
Pokitto 31:f4b9b85c7b62 216 write_command(0x36); // Horizontal and vertical RAM position
Pokitto 31:f4b9b85c7b62 217 write_data(0x00AF); //end address 175
Pokitto 31:f4b9b85c7b62 218
Pokitto 31:f4b9b85c7b62 219 write_command(0x37);
Pokitto 31:f4b9b85c7b62 220 write_data(0x0000); // start address 0
Pokitto 31:f4b9b85c7b62 221
Pokitto 31:f4b9b85c7b62 222 write_command(0x38);
Pokitto 31:f4b9b85c7b62 223 write_data(0x00DB); //end address 219
Pokitto 31:f4b9b85c7b62 224
Pokitto 31:f4b9b85c7b62 225 write_command(0x39); // start address 0
Pokitto 31:f4b9b85c7b62 226 write_data(0x0000);
Pokitto 31:f4b9b85c7b62 227 wait_ms(10);
Pokitto 31:f4b9b85c7b62 228 write_command(0xff); // start gamma register control
Pokitto 31:f4b9b85c7b62 229 write_data(0x0003);
Pokitto 31:f4b9b85c7b62 230
Pokitto 31:f4b9b85c7b62 231 // ----------- Adjust the Gamma Curve ----------//
Pokitto 31:f4b9b85c7b62 232 write_command(0x50);
Pokitto 31:f4b9b85c7b62 233 write_data(0x0203);
Pokitto 31:f4b9b85c7b62 234
Pokitto 31:f4b9b85c7b62 235 write_command(0x051);
Pokitto 31:f4b9b85c7b62 236 write_data(0x0A09);
Pokitto 31:f4b9b85c7b62 237
Pokitto 31:f4b9b85c7b62 238 write_command(0x52);
Pokitto 31:f4b9b85c7b62 239 write_data(0x0005);
Pokitto 31:f4b9b85c7b62 240
Pokitto 31:f4b9b85c7b62 241 write_command(0x53);
Pokitto 31:f4b9b85c7b62 242 write_data(0x1021);
Pokitto 31:f4b9b85c7b62 243
Pokitto 31:f4b9b85c7b62 244 write_command(0x54);
Pokitto 31:f4b9b85c7b62 245 write_data(0x0602);
Pokitto 31:f4b9b85c7b62 246
Pokitto 31:f4b9b85c7b62 247 write_command(0x55);
Pokitto 31:f4b9b85c7b62 248 write_data(0x0003);
Pokitto 31:f4b9b85c7b62 249
Pokitto 31:f4b9b85c7b62 250 write_command(0x56);
Pokitto 31:f4b9b85c7b62 251 write_data(0x0703);
Pokitto 31:f4b9b85c7b62 252
Pokitto 31:f4b9b85c7b62 253 write_command(0x57);
Pokitto 31:f4b9b85c7b62 254 write_data(0x0507);
Pokitto 31:f4b9b85c7b62 255
Pokitto 31:f4b9b85c7b62 256 write_command(0x58);
Pokitto 31:f4b9b85c7b62 257 write_data(0x1021);
Pokitto 31:f4b9b85c7b62 258
Pokitto 31:f4b9b85c7b62 259 write_command(0x59);
Pokitto 31:f4b9b85c7b62 260 write_data(0x0703);
Pokitto 31:f4b9b85c7b62 261
Pokitto 31:f4b9b85c7b62 262 write_command(0xB0);
Pokitto 31:f4b9b85c7b62 263 write_data(0x2501);
Pokitto 31:f4b9b85c7b62 264
Pokitto 31:f4b9b85c7b62 265 write_command(0xFF);
Pokitto 31:f4b9b85c7b62 266 write_data(0x0000);
Pokitto 31:f4b9b85c7b62 267
Pokitto 31:f4b9b85c7b62 268 write_command(0x07);
Pokitto 31:f4b9b85c7b62 269 write_data(0x1017);
Pokitto 31:f4b9b85c7b62 270 wait_ms(200);
Pokitto 31:f4b9b85c7b62 271 write_command(0x22);
Pokitto 31:f4b9b85c7b62 272
Pokitto 31:f4b9b85c7b62 273 lcdClear();
Pokitto 31:f4b9b85c7b62 274 }
Pokitto 31:f4b9b85c7b62 275
Pokitto 31:f4b9b85c7b62 276 void Pokitto::lcdSleep(void){
Pokitto 31:f4b9b85c7b62 277 write_command(0xFF);
Pokitto 31:f4b9b85c7b62 278 write_data(0x0000);
Pokitto 31:f4b9b85c7b62 279
Pokitto 31:f4b9b85c7b62 280 write_command(0x07);
Pokitto 31:f4b9b85c7b62 281 write_data(0x0000);
Pokitto 31:f4b9b85c7b62 282 wait_ms(50);
Pokitto 31:f4b9b85c7b62 283 write_command(0x10);// Enter Standby mode
Pokitto 31:f4b9b85c7b62 284 write_data(0x0003);
Pokitto 31:f4b9b85c7b62 285 wait_ms(200);
Pokitto 31:f4b9b85c7b62 286
Pokitto 31:f4b9b85c7b62 287 }
Pokitto 31:f4b9b85c7b62 288
Pokitto 31:f4b9b85c7b62 289 void Pokitto::lcdWakeUp (void){
Pokitto 31:f4b9b85c7b62 290
Pokitto 31:f4b9b85c7b62 291 wait_ms(200);
Pokitto 31:f4b9b85c7b62 292 write_command(0xFF);
Pokitto 31:f4b9b85c7b62 293 write_data(0x0000);
Pokitto 31:f4b9b85c7b62 294
Pokitto 31:f4b9b85c7b62 295 write_command(0x10);// Exit Sleep/ Standby mode
Pokitto 31:f4b9b85c7b62 296 write_data(0x0000);
Pokitto 31:f4b9b85c7b62 297 wait_ms(50);
Pokitto 31:f4b9b85c7b62 298 write_command(0x07);
Pokitto 31:f4b9b85c7b62 299 write_data(0x0117);
Pokitto 31:f4b9b85c7b62 300 wait_ms(200);
Pokitto 31:f4b9b85c7b62 301 }
Pokitto 31:f4b9b85c7b62 302
Pokitto 31:f4b9b85c7b62 303 void Pokitto::lcdFillSurface(uint16_t c) {
Pokitto 31:f4b9b85c7b62 304 uint32_t i;
Pokitto 31:f4b9b85c7b62 305 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 306 write_data(0x0000); // 0
Pokitto 31:f4b9b85c7b62 307 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 308 write_data(0);
Pokitto 31:f4b9b85c7b62 309 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 310 setup_data_16(c);
Pokitto 31:f4b9b85c7b62 311 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 312 for(i=0;i<220*176;i++)
Pokitto 31:f4b9b85c7b62 313 {
Pokitto 31:f4b9b85c7b62 314 CLR_WR;
Pokitto 31:f4b9b85c7b62 315 SET_WR;
Pokitto 31:f4b9b85c7b62 316 }
Pokitto 31:f4b9b85c7b62 317 }
Pokitto 31:f4b9b85c7b62 318
Pokitto 31:f4b9b85c7b62 319 void Pokitto::lcdClear() {
Pokitto 31:f4b9b85c7b62 320 uint32_t i;
Pokitto 31:f4b9b85c7b62 321 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 322 write_data(0x0000); // 0
Pokitto 31:f4b9b85c7b62 323 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 324 write_data(0);
Pokitto 31:f4b9b85c7b62 325 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 326 setup_data_16(0x0000);
Pokitto 31:f4b9b85c7b62 327 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 328 for(i=0;i<220*176;i++)
Pokitto 31:f4b9b85c7b62 329 {
Pokitto 31:f4b9b85c7b62 330 CLR_WR;
Pokitto 31:f4b9b85c7b62 331 SET_WR;
Pokitto 31:f4b9b85c7b62 332 }
Pokitto 31:f4b9b85c7b62 333 }
Pokitto 31:f4b9b85c7b62 334
Pokitto 31:f4b9b85c7b62 335 void Pokitto::lcdPixel(int16_t x, int16_t y, uint16_t color) {
Pokitto 31:f4b9b85c7b62 336 if ((x < 0) || (x >= POK_LCD_W) || (y < 0) || (y >= POK_LCD_H))
Pokitto 31:f4b9b85c7b62 337 return;
Pokitto 31:f4b9b85c7b62 338 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 339 write_data(y); // 0
Pokitto 31:f4b9b85c7b62 340 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 341 write_data(x);
Pokitto 31:f4b9b85c7b62 342 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 343 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 344 setup_data_16(color);
Pokitto 31:f4b9b85c7b62 345 CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 346 }
Pokitto 31:f4b9b85c7b62 347
Pokitto 31:f4b9b85c7b62 348 void Pokitto::setWindow(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
Pokitto 31:f4b9b85c7b62 349 write_command(0x37); write_data(x1);
Pokitto 31:f4b9b85c7b62 350 write_command(0x36); write_data(x2);
Pokitto 31:f4b9b85c7b62 351 write_command(0x39); write_data(y1);
Pokitto 31:f4b9b85c7b62 352 write_command(0x38); write_data(y2);
Pokitto 31:f4b9b85c7b62 353 write_command(0x20); write_data(x1);
Pokitto 31:f4b9b85c7b62 354 write_command(0x21); write_data(y1);
Pokitto 31:f4b9b85c7b62 355 }
Pokitto 31:f4b9b85c7b62 356
Pokitto 31:f4b9b85c7b62 357 void Pokitto::lcdTile(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t* gfx){
Pokitto 31:f4b9b85c7b62 358 int width=x1-x0;
Pokitto 31:f4b9b85c7b62 359 int height=y1-y0;
Pokitto 31:f4b9b85c7b62 360 if (x0 > POK_LCD_W) return;
Pokitto 31:f4b9b85c7b62 361 if (y0 > POK_LCD_H) return;
Pokitto 31:f4b9b85c7b62 362 if (x0 < 0) x0=0;
Pokitto 31:f4b9b85c7b62 363 if (y0 < 0) y0=0;
Pokitto 31:f4b9b85c7b62 364
Pokitto 31:f4b9b85c7b62 365 setWindow(y0, x0, y1-1, x1-1);
Pokitto 31:f4b9b85c7b62 366 write_command(0x22);
Pokitto 31:f4b9b85c7b62 367
Pokitto 31:f4b9b85c7b62 368 for (int x=0; x<=width*height-1;x++) {
Pokitto 31:f4b9b85c7b62 369 write_data(gfx[x]);
Pokitto 31:f4b9b85c7b62 370 }
Pokitto 31:f4b9b85c7b62 371 setWindow(0, 0, 175, 219);
Pokitto 31:f4b9b85c7b62 372 }
Pokitto 31:f4b9b85c7b62 373
Pokitto 31:f4b9b85c7b62 374
Pokitto 31:f4b9b85c7b62 375 void Pokitto::lcdRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
Pokitto 31:f4b9b85c7b62 376 int16_t temp;
Pokitto 31:f4b9b85c7b62 377 if (x0>x1) {temp=x0;x0=x1;x1=temp;}
Pokitto 31:f4b9b85c7b62 378 if (y0>y1) {temp=y0;y0=y1;y1=temp;}
Pokitto 31:f4b9b85c7b62 379 if (x0 > POK_LCD_W) return;
Pokitto 31:f4b9b85c7b62 380 if (y0 > POK_LCD_H) return;
Pokitto 31:f4b9b85c7b62 381 if (x1 > POK_LCD_W) x1=POK_LCD_W;
Pokitto 31:f4b9b85c7b62 382 if (y1 > POK_LCD_H) y1=POK_LCD_W;
Pokitto 31:f4b9b85c7b62 383 if (x0 < 0) x0=0;
Pokitto 31:f4b9b85c7b62 384 if (y0 < 0) y0=0;
Pokitto 31:f4b9b85c7b62 385
Pokitto 31:f4b9b85c7b62 386 int16_t x,y;
Pokitto 31:f4b9b85c7b62 387 for (x=x0; x<=x1;x++) {
Pokitto 31:f4b9b85c7b62 388 write_command(0x20); // Horizontal DRAM Address (=y on pokitto screen)
Pokitto 31:f4b9b85c7b62 389 write_data(y0);
Pokitto 31:f4b9b85c7b62 390 write_command(0x21); // Vertical DRAM Address (=x on pokitto screen)
Pokitto 31:f4b9b85c7b62 391 write_data(x);
Pokitto 31:f4b9b85c7b62 392 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 393
Pokitto 31:f4b9b85c7b62 394 CLR_CS_SET_CD_RD_WR; // go to vram write mode
Pokitto 31:f4b9b85c7b62 395
Pokitto 31:f4b9b85c7b62 396
Pokitto 31:f4b9b85c7b62 397 for (y=y0; y<y1;y++) {
Pokitto 31:f4b9b85c7b62 398 setup_data_16(color); // setup the data (flat color = no change between pixels)
Pokitto 31:f4b9b85c7b62 399 CLR_WR;SET_WR; //CLR_WR;SET_WR;//toggle writeline, pokitto screen writes a column up to down
Pokitto 31:f4b9b85c7b62 400 }
Pokitto 31:f4b9b85c7b62 401 }
Pokitto 31:f4b9b85c7b62 402 }
Pokitto 31:f4b9b85c7b62 403
Pokitto 31:f4b9b85c7b62 404 /***
Pokitto 31:f4b9b85c7b62 405 * Update the screen buffer of 220x176 pixels, 4 colors to LCD.
Pokitto 31:f4b9b85c7b62 406 *
Pokitto 31:f4b9b85c7b62 407 * The update rect is used for drawing only part of the screen buffer to LCD. Because of speed optimizations, the
Pokitto 31:f4b9b85c7b62 408 * x, y, and width of the update rect must be dividable by 4 pixels, and the height must be dividable by 8 pixels.
Pokitto 31:f4b9b85c7b62 409 * Note: The update rect is currently used for 220x176, 4 colors, screen mode only.
Pokitto 31:f4b9b85c7b62 410 * @param scrbuf The screen buffer.
Pokitto 31:f4b9b85c7b62 411 * @param updRectX The update rect.
Pokitto 31:f4b9b85c7b62 412 * @param updRectY The update rect.
Pokitto 31:f4b9b85c7b62 413 * @param updRectW The update rect.
Pokitto 31:f4b9b85c7b62 414 * @param updRectH The update rect.
Pokitto 31:f4b9b85c7b62 415 * @param paletteptr The screen palette.
Pokitto 31:f4b9b85c7b62 416 */
Pokitto 31:f4b9b85c7b62 417 void Pokitto::lcdRefreshMode1(uint8_t * scrbuf, uint8_t updRectX, uint8_t updRectY, uint8_t updRectW, uint8_t updRectH, uint16_t* paletteptr) {
Pokitto 31:f4b9b85c7b62 418
Pokitto 31:f4b9b85c7b62 419 uint16_t x,y,xptr;
Pokitto 31:f4b9b85c7b62 420 uint16_t scanline[4][176]; // read 4 half-nibbles = 4 pixels at a time
Pokitto 31:f4b9b85c7b62 421 uint8_t *d, yoffset=0;
Pokitto 31:f4b9b85c7b62 422
Pokitto 31:f4b9b85c7b62 423 // If not the full screen is updated, check the validity of the update rect.
Pokitto 31:f4b9b85c7b62 424 if ( updRectX != 0 || updRectY != 0 ||updRectW != LCDWIDTH ||updRectH != LCDHEIGHT ) {
Pokitto 31:f4b9b85c7b62 425 uint8_t org_screenx = updRectX;
Pokitto 31:f4b9b85c7b62 426 updRectX &= 0xfc; // Make the value dividable by 4.
Pokitto 31:f4b9b85c7b62 427 updRectW += org_screenx - updRectX;
Pokitto 31:f4b9b85c7b62 428 updRectW = (updRectW + 3) & 0xfc; // Make the value dividable by 4, round up.
Pokitto 31:f4b9b85c7b62 429
Pokitto 31:f4b9b85c7b62 430 uint8_t org_screeny = updRectY;
Pokitto 31:f4b9b85c7b62 431 updRectY &= 0xfc; // Make the value dividable by 4.
Pokitto 31:f4b9b85c7b62 432 updRectH += org_screeny - updRectY;
Pokitto 31:f4b9b85c7b62 433 updRectH = (updRectH + 7) & 0xf8; // Make the value dividable by 8 (because of loop unroll optimization), round up.
Pokitto 31:f4b9b85c7b62 434 }
Pokitto 31:f4b9b85c7b62 435
Pokitto 31:f4b9b85c7b62 436
Pokitto 31:f4b9b85c7b62 437 #ifdef PROJ_USE_FPS_COUNTER
Pokitto 31:f4b9b85c7b62 438 xptr = 8;
Pokitto 31:f4b9b85c7b62 439 setDRAMptr(8, 0);
Pokitto 31:f4b9b85c7b62 440 #else
Pokitto 31:f4b9b85c7b62 441 xptr = 0;
Pokitto 31:f4b9b85c7b62 442 setDRAMptr(0, 0);
Pokitto 31:f4b9b85c7b62 443 #endif
Pokitto 31:f4b9b85c7b62 444
Pokitto 31:f4b9b85c7b62 445 for (x=updRectX; x<updRectX+updRectW; x+=4) {
Pokitto 31:f4b9b85c7b62 446 d = scrbuf+(x>>2);// point to beginning of line in data
Pokitto 31:f4b9b85c7b62 447
Pokitto 31:f4b9b85c7b62 448 /** find colours in one scanline **/
Pokitto 31:f4b9b85c7b62 449 uint8_t s=0;
Pokitto 31:f4b9b85c7b62 450 d += (updRectY * 220/4);
Pokitto 31:f4b9b85c7b62 451 for (y=updRectY; y<updRectY+updRectH; y++) {
Pokitto 31:f4b9b85c7b62 452 uint8_t tdata = *d;
Pokitto 31:f4b9b85c7b62 453 uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
Pokitto 31:f4b9b85c7b62 454 uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
Pokitto 31:f4b9b85c7b62 455 uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
Pokitto 31:f4b9b85c7b62 456 uint8_t t = tdata & 0x03;// highest half-nibble
Pokitto 31:f4b9b85c7b62 457
Pokitto 31:f4b9b85c7b62 458 /** put nibble values in the scanlines **/
Pokitto 31:f4b9b85c7b62 459 scanline[0][y] = paletteptr[t];
Pokitto 31:f4b9b85c7b62 460 scanline[1][y] = paletteptr[t2];
Pokitto 31:f4b9b85c7b62 461 scanline[2][y] = paletteptr[t3];
Pokitto 31:f4b9b85c7b62 462 scanline[3][y] = paletteptr[t4];
Pokitto 31:f4b9b85c7b62 463
Pokitto 31:f4b9b85c7b62 464 d += 220/4; // jump to read byte directly below in screenbuffer
Pokitto 31:f4b9b85c7b62 465 }
Pokitto 31:f4b9b85c7b62 466
Pokitto 31:f4b9b85c7b62 467 #ifdef PROJ_USE_FPS_COUNTER
Pokitto 31:f4b9b85c7b62 468 if (x>=8 ) {
Pokitto 31:f4b9b85c7b62 469 #else
Pokitto 31:f4b9b85c7b62 470 {
Pokitto 31:f4b9b85c7b62 471
Pokitto 31:f4b9b85c7b62 472 #endif
Pokitto 31:f4b9b85c7b62 473
Pokitto 31:f4b9b85c7b62 474 // Draw 8 vertical pixels at a time for performance reasons
Pokitto 31:f4b9b85c7b62 475 setDRAMptr(x, updRectY);
Pokitto 31:f4b9b85c7b62 476 for (uint8_t s=updRectY; s<updRectY+updRectH;) {
Pokitto 31:f4b9b85c7b62 477 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 478 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 479 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 480 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 481 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 482 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 483 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 484 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 485 }
Pokitto 31:f4b9b85c7b62 486 setDRAMptr(x+1, updRectY);
Pokitto 31:f4b9b85c7b62 487 for (uint8_t s=updRectY; s<updRectY+updRectH;) {
Pokitto 31:f4b9b85c7b62 488 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 489 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 490 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 491 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 492 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 493 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 494 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 495 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 496 }
Pokitto 31:f4b9b85c7b62 497 setDRAMptr(x+2, updRectY);
Pokitto 31:f4b9b85c7b62 498 for (uint8_t s=updRectY; s<updRectY+updRectH;) {
Pokitto 31:f4b9b85c7b62 499 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 500 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 501 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 502 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 503 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 504 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 505 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 506 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 507 }
Pokitto 31:f4b9b85c7b62 508 setDRAMptr(x+3, updRectY);
Pokitto 31:f4b9b85c7b62 509 for (uint8_t s=updRectY; s<updRectY+updRectH;) {
Pokitto 31:f4b9b85c7b62 510 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 511 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 512 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 513 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 514 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 515 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 516 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 517 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 518 }
Pokitto 31:f4b9b85c7b62 519 }
Pokitto 31:f4b9b85c7b62 520 }
Pokitto 31:f4b9b85c7b62 521
Pokitto 31:f4b9b85c7b62 522 #ifdef POK_SIM
Pokitto 31:f4b9b85c7b62 523 simulator.refreshDisplay();
Pokitto 31:f4b9b85c7b62 524 #endif
Pokitto 31:f4b9b85c7b62 525 }
Pokitto 31:f4b9b85c7b62 526
Pokitto 31:f4b9b85c7b62 527 // Copy sprite pixels to the scanline
Pokitto 31:f4b9b85c7b62 528 #define SPRITE_2BPP_INNER_LOOP(n)\
Pokitto 31:f4b9b85c7b62 529 \
Pokitto 31:f4b9b85c7b62 530 /* If the sprite is enabled and contained in this vertical scanline, copy 4 pixels. */\
Pokitto 31:f4b9b85c7b62 531 if (sprScanlineAddr[(n)] &&\
Pokitto 31:f4b9b85c7b62 532 y >= sprites[(n)].y && y < sprites[(n)].y + sprites[(n)].h ) {\
Pokitto 31:f4b9b85c7b62 533 \
Pokitto 31:f4b9b85c7b62 534 int16_t sprx = sprites[(n)].x;\
Pokitto 31:f4b9b85c7b62 535 uint16_t s_data16b = 0; /* sprite data, 2 bytes */\
Pokitto 31:f4b9b85c7b62 536 \
Pokitto 31:f4b9b85c7b62 537 /* Get pixel block, 4 or 8 pixels horizontally. Use the predefined bitshift mode. */\
Pokitto 31:f4b9b85c7b62 538 /* Note:it is cheapest to compare to 0 first. */\
Pokitto 31:f4b9b85c7b62 539 if (sprScanlineBitshiftMode[(n)] == BITSHIFT_MODE_MIDDLE_BYTE) {\
Pokitto 31:f4b9b85c7b62 540 s_data16b = *(sprScanlineAddr[(n)]);\
Pokitto 31:f4b9b85c7b62 541 uint16_t leftByte = *(sprScanlineAddr[(n)]-1);\
Pokitto 31:f4b9b85c7b62 542 s_data16b = (leftByte << 8) | s_data16b;\
Pokitto 31:f4b9b85c7b62 543 }\
Pokitto 31:f4b9b85c7b62 544 else if (sprScanlineBitshiftMode[(n)] == BITSHIFT_MODE_FIRST_BYTE) {\
Pokitto 31:f4b9b85c7b62 545 s_data16b = *(sprScanlineAddr[(n)]);\
Pokitto 31:f4b9b85c7b62 546 }\
Pokitto 31:f4b9b85c7b62 547 else { /* BITSHIFT_MODE_LAST_BYTE */\
Pokitto 31:f4b9b85c7b62 548 uint16_t leftByte = *(sprScanlineAddr[(n)]-1);\
Pokitto 31:f4b9b85c7b62 549 s_data16b = (leftByte << 8) | s_data16b;\
Pokitto 31:f4b9b85c7b62 550 }\
Pokitto 31:f4b9b85c7b62 551 \
Pokitto 31:f4b9b85c7b62 552 /* Shift sprite pixels according to sprite x. After shifting we have only 4 pixels. */\
Pokitto 31:f4b9b85c7b62 553 uint8_t shiftRight = (sprx&0x3) << 1;\
Pokitto 31:f4b9b85c7b62 554 s_data16b = (s_data16b >> shiftRight);\
Pokitto 31:f4b9b85c7b62 555 \
Pokitto 31:f4b9b85c7b62 556 /* Get individual pixels */\
Pokitto 31:f4b9b85c7b62 557 uint8_t s_t4 = s_data16b & 0x03; s_data16b >>= 2; /* lowest half-nibble */\
Pokitto 31:f4b9b85c7b62 558 uint8_t s_t3 = s_data16b & 0x03; s_data16b >>= 2; /* second lowest half-nibble */\
Pokitto 31:f4b9b85c7b62 559 uint8_t s_t2 = s_data16b & 0x03; s_data16b >>= 2; /* second highest half-nibble */\
Pokitto 31:f4b9b85c7b62 560 uint8_t s_t1 = s_data16b & 0x03; /* highest half-nibble */\
Pokitto 31:f4b9b85c7b62 561 \
Pokitto 31:f4b9b85c7b62 562 /* Store pixels as 16-bit colors from the palette */\
Pokitto 31:f4b9b85c7b62 563 if (s_t4 != transparentColor) p4 = sprites[(n)].palette[s_t4];\
Pokitto 31:f4b9b85c7b62 564 if (s_t3 != transparentColor) p3 = sprites[(n)].palette[s_t3];\
Pokitto 31:f4b9b85c7b62 565 if (s_t2 != transparentColor) p2 = sprites[(n)].palette[s_t2];\
Pokitto 31:f4b9b85c7b62 566 if (s_t1 != transparentColor) p = sprites[(n)].palette[s_t1];\
Pokitto 31:f4b9b85c7b62 567 \
Pokitto 31:f4b9b85c7b62 568 /* Advance scanline address */\
Pokitto 31:f4b9b85c7b62 569 sprScanlineAddr[(n)] += (sprites[(n)].w >> 2);\
Pokitto 31:f4b9b85c7b62 570 }
Pokitto 31:f4b9b85c7b62 571
Pokitto 31:f4b9b85c7b62 572 // Loop unrolling macros
Pokitto 31:f4b9b85c7b62 573 #define UNROLLED_LOOP_1() SPRITE_2BPP_INNER_LOOP(0)
Pokitto 31:f4b9b85c7b62 574 #define UNROLLED_LOOP_2() UNROLLED_LOOP_1() SPRITE_2BPP_INNER_LOOP(1)
Pokitto 31:f4b9b85c7b62 575 #define UNROLLED_LOOP_3() UNROLLED_LOOP_2() SPRITE_2BPP_INNER_LOOP(2)
Pokitto 31:f4b9b85c7b62 576 #define UNROLLED_LOOP_4() UNROLLED_LOOP_3() SPRITE_2BPP_INNER_LOOP(3)
Pokitto 31:f4b9b85c7b62 577 #define UNROLLED_LOOP_5() UNROLLED_LOOP_4() SPRITE_2BPP_INNER_LOOP(4)
Pokitto 31:f4b9b85c7b62 578 #define UNROLLED_LOOP_6() UNROLLED_LOOP_5() SPRITE_2BPP_INNER_LOOP(5)
Pokitto 31:f4b9b85c7b62 579 #define UNROLLED_LOOP_7() UNROLLED_LOOP_6() SPRITE_2BPP_INNER_LOOP(6)
Pokitto 31:f4b9b85c7b62 580 #define UNROLLED_LOOP_8() UNROLLED_LOOP_7() SPRITE_2BPP_INNER_LOOP(7)
Pokitto 31:f4b9b85c7b62 581 #define UNROLLED_LOOP_9() UNROLLED_LOOP_8() SPRITE_2BPP_INNER_LOOP(8)
Pokitto 31:f4b9b85c7b62 582 #define UNROLLED_LOOP_10() UNROLLED_LOOP_9() SPRITE_2BPP_INNER_LOOP(9)
Pokitto 31:f4b9b85c7b62 583 #define UNROLLED_LOOP_11() UNROLLED_LOOP_10() SPRITE_2BPP_INNER_LOOP(10)
Pokitto 31:f4b9b85c7b62 584 #define UNROLLED_LOOP_12() UNROLLED_LOOP_11() SPRITE_2BPP_INNER_LOOP(11)
Pokitto 31:f4b9b85c7b62 585 #define UNROLLED_LOOP_13() UNROLLED_LOOP_12() SPRITE_2BPP_INNER_LOOP(12)
Pokitto 31:f4b9b85c7b62 586 #define UNROLLED_LOOP_14() UNROLLED_LOOP_13() SPRITE_2BPP_INNER_LOOP(13)
Pokitto 31:f4b9b85c7b62 587 #define UNROLLED_LOOP_15() UNROLLED_LOOP_14() SPRITE_2BPP_INNER_LOOP(14)
Pokitto 31:f4b9b85c7b62 588 #define UNROLLED_LOOP_16() UNROLLED_LOOP_15() SPRITE_2BPP_INNER_LOOP(15)
Pokitto 31:f4b9b85c7b62 589 #define UNROLLED_LOOP_N_(n) UNROLLED_LOOP_##n()
Pokitto 31:f4b9b85c7b62 590 #define UNROLLED_LOOP_N(n) UNROLLED_LOOP_N_(n)
Pokitto 31:f4b9b85c7b62 591
Pokitto 31:f4b9b85c7b62 592 /***
Pokitto 31:f4b9b85c7b62 593 * Update the screen buffer of 220x176 pixels, 4 colors and free size 4 color sprites to LCD.
Pokitto 31:f4b9b85c7b62 594 *
Pokitto 31:f4b9b85c7b62 595 * The update rect is used for drawing only part of the screen buffer to LCD. Because of speed optimizations, the
Pokitto 31:f4b9b85c7b62 596 * x, y, and width of the update rect must be dividable by 4 pixels, and the height must be dividable by 8 pixels.
Pokitto 31:f4b9b85c7b62 597 * Note: The update rect is currently used for 220x176, 4 colors, screen mode only.
Pokitto 31:f4b9b85c7b62 598 * If drawSpritesOnly=true, only sprites are fully updated to LCD. However, the dirty rect of the screen buffer is
Pokitto 31:f4b9b85c7b62 599 * drawn behind the sprite current and previous location.
Pokitto 31:f4b9b85c7b62 600 * Note: Sprite is enabled if sprite.bitmapData is not NULL. Also all enabled sprites must be at the beginning of
Pokitto 31:f4b9b85c7b62 601 * the sprites array. No gaps are allowed in the array.
Pokitto 31:f4b9b85c7b62 602 * @param scrbuf The screen buffer.
Pokitto 31:f4b9b85c7b62 603 * @param updRectX The update rect.
Pokitto 31:f4b9b85c7b62 604 * @param updRectY The update rect.
Pokitto 31:f4b9b85c7b62 605 * @param updRectW The update rect.
Pokitto 31:f4b9b85c7b62 606 * @param updRectH The update rect.
Pokitto 31:f4b9b85c7b62 607 * @param paletteptr The screen palette.
Pokitto 31:f4b9b85c7b62 608 * @param sprites The sprite array.
Pokitto 31:f4b9b85c7b62 609 * @param drawSpritesOnly True, if only sprites are drawn. False, if both sprites and the screen buffer are drawn.
Pokitto 31:f4b9b85c7b62 610 */
Pokitto 31:f4b9b85c7b62 611 void Pokitto::lcdRefreshMode1Spr(
Pokitto 31:f4b9b85c7b62 612 uint8_t * scrbuf, uint8_t updRectX, uint8_t updRectY, uint8_t updRectW, uint8_t updRectH, uint16_t* paletteptr,
Pokitto 31:f4b9b85c7b62 613 SpriteInfo* sprites, bool drawSpritesOnly) {
Pokitto 31:f4b9b85c7b62 614
Pokitto 31:f4b9b85c7b62 615 // In direct mode draw only sprites and their dirty rects. Return now if there are no sprites
Pokitto 31:f4b9b85c7b62 616 if (drawSpritesOnly && (sprites == NULL || sprites[0].bitmapData == NULL))
Pokitto 31:f4b9b85c7b62 617 return;
Pokitto 31:f4b9b85c7b62 618
Pokitto 31:f4b9b85c7b62 619 uint16_t x,y;
Pokitto 31:f4b9b85c7b62 620 uint16_t scanline[4][176]; // read 4 half-nibbles (= 4 pixels) at a time
Pokitto 31:f4b9b85c7b62 621 const uint8_t transparentColor = 0; // fixed palette index 0 for transparency
Pokitto 31:f4b9b85c7b62 622
Pokitto 31:f4b9b85c7b62 623 // If not the full screen is updated, check the validity of the update rect.
Pokitto 31:f4b9b85c7b62 624 if ( updRectX != 0 || updRectY != 0 ||updRectW != LCDWIDTH ||updRectH != LCDHEIGHT ) {
Pokitto 31:f4b9b85c7b62 625 uint8_t org_screenx = updRectX;
Pokitto 31:f4b9b85c7b62 626 updRectX &= 0xfc; // Make the value dividable by 4.
Pokitto 31:f4b9b85c7b62 627 updRectW += org_screenx - updRectX;
Pokitto 31:f4b9b85c7b62 628 updRectW = (updRectW + 3) & 0xfc; // Make the value dividable by 4, round up.
Pokitto 31:f4b9b85c7b62 629
Pokitto 31:f4b9b85c7b62 630 uint8_t org_screeny = updRectY;
Pokitto 31:f4b9b85c7b62 631 updRectY &= 0xfc; // Make the value dividable by 4.
Pokitto 31:f4b9b85c7b62 632 updRectH += org_screeny - updRectY;
Pokitto 31:f4b9b85c7b62 633 updRectH = (updRectH + 7) & 0xf8; // Make the value dividable by 8 (because of loop unroll optimization), round up.
Pokitto 31:f4b9b85c7b62 634 }
Pokitto 31:f4b9b85c7b62 635
Pokitto 31:f4b9b85c7b62 636 // Calculate the current amount of sprites
Pokitto 31:f4b9b85c7b62 637 // 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 31:f4b9b85c7b62 638 uint8_t spriteCount = 0;
Pokitto 31:f4b9b85c7b62 639 if (sprites != NULL)
Pokitto 31:f4b9b85c7b62 640 for (;sprites[spriteCount].bitmapData != NULL && spriteCount < SPRITE_COUNT; spriteCount++);
Pokitto 31:f4b9b85c7b62 641
Pokitto 31:f4b9b85c7b62 642 // If drawing the screen buffer, set the start pos to LCD commands only here.
Pokitto 31:f4b9b85c7b62 643 #ifdef PROJ_USE_FPS_COUNTER
Pokitto 31:f4b9b85c7b62 644 if (!drawSpritesOnly) setDRAMptr(8, 0);
Pokitto 31:f4b9b85c7b62 645 #else
Pokitto 31:f4b9b85c7b62 646 if (!drawSpritesOnly) setDRAMptr(0, 0);
Pokitto 31:f4b9b85c7b62 647 #endif
Pokitto 31:f4b9b85c7b62 648
Pokitto 31:f4b9b85c7b62 649 //*** GO THROUGH EACH VERTICAL GROUP OF 4 SCANLINES.***
Pokitto 31:f4b9b85c7b62 650
Pokitto 31:f4b9b85c7b62 651 for (x=0; x<LCDWIDTH; x+=4) {
Pokitto 31:f4b9b85c7b62 652
Pokitto 31:f4b9b85c7b62 653 uint8_t *screenBufScanlineAddr = scrbuf + (x>>2);// point to beginning of line in data
Pokitto 31:f4b9b85c7b62 654
Pokitto 31:f4b9b85c7b62 655 /*Prepare scanline start address for sprites that are visible in this vertical scanline. Sprite width cannot exceed the screen width*/
Pokitto 31:f4b9b85c7b62 656 uint8_t *sprScanlineAddr[SPRITE_COUNT]; // Sprite start address for the scanline
Pokitto 31:f4b9b85c7b62 657 uint8_t sprScanlineBitshiftMode[SPRITE_COUNT]; // Sprite bitshift mode for the scanline
Pokitto 31:f4b9b85c7b62 658 const uint8_t BITSHIFT_MODE_MIDDLE_BYTE = 0;
Pokitto 31:f4b9b85c7b62 659 const uint8_t BITSHIFT_MODE_FIRST_BYTE = 1;
Pokitto 31:f4b9b85c7b62 660 const uint8_t BITSHIFT_MODE_LAST_BYTE = 2;
Pokitto 31:f4b9b85c7b62 661 uint8_t scanlineMinY = 255; // Init to uninitialized value. Do not draw by default.
Pokitto 31:f4b9b85c7b62 662 uint8_t scanlineMaxY = 0; // Init to uninitialized value. Do not draw by default.
Pokitto 31:f4b9b85c7b62 663
Pokitto 31:f4b9b85c7b62 664 //*** CALCULATE DIRTY RECTS AND RESOLVE WHICH SPRITES BELONG TO THIS SCANLINE GROUP ***
Pokitto 31:f4b9b85c7b62 665
Pokitto 31:f4b9b85c7b62 666 if (sprites != NULL) {
Pokitto 31:f4b9b85c7b62 667
Pokitto 31:f4b9b85c7b62 668 // Check all the sprites for this scanline. That is used for handling the given update rect
Pokitto 31:f4b9b85c7b62 669 // Note that the last round is when (sprindex == spriteCount). That is used to add the screen buffer
Pokitto 31:f4b9b85c7b62 670 // update rect to the dirty rect.
Pokitto 31:f4b9b85c7b62 671 for (int sprindex = 0; sprindex <= spriteCount; sprindex++) {
Pokitto 31:f4b9b85c7b62 672
Pokitto 31:f4b9b85c7b62 673 int16_t sprx, spry, sprOldX, sprOldY;
Pokitto 31:f4b9b85c7b62 674 uint8_t sprw, sprh;
Pokitto 31:f4b9b85c7b62 675 bool isCurrentSpriteOutOfScreen = false;
Pokitto 31:f4b9b85c7b62 676 bool isOldSpriteOutOfScreen = false;
Pokitto 31:f4b9b85c7b62 677
Pokitto 31:f4b9b85c7b62 678 if (sprindex < spriteCount) {
Pokitto 31:f4b9b85c7b62 679
Pokitto 31:f4b9b85c7b62 680 sprx = sprites[sprindex].x;
Pokitto 31:f4b9b85c7b62 681 spry = sprites[sprindex].y;
Pokitto 31:f4b9b85c7b62 682 sprw = sprites[sprindex].w;
Pokitto 31:f4b9b85c7b62 683 sprh = sprites[sprindex].h;
Pokitto 31:f4b9b85c7b62 684 sprOldX = sprites[sprindex].oldx;
Pokitto 31:f4b9b85c7b62 685 sprOldY = sprites[sprindex].oldy;
Pokitto 31:f4b9b85c7b62 686 }
Pokitto 31:f4b9b85c7b62 687
Pokitto 31:f4b9b85c7b62 688 // Handle the screen buffer update rect after all sprites
Pokitto 31:f4b9b85c7b62 689 else if(!drawSpritesOnly){
Pokitto 31:f4b9b85c7b62 690
Pokitto 31:f4b9b85c7b62 691 sprx = updRectX;
Pokitto 31:f4b9b85c7b62 692 spry = updRectY;
Pokitto 31:f4b9b85c7b62 693 sprw = updRectW;
Pokitto 31:f4b9b85c7b62 694 sprh = updRectH;
Pokitto 31:f4b9b85c7b62 695 sprOldX = updRectX;
Pokitto 31:f4b9b85c7b62 696 sprOldY = updRectY;
Pokitto 31:f4b9b85c7b62 697 isCurrentSpriteOutOfScreen = false;
Pokitto 31:f4b9b85c7b62 698 isOldSpriteOutOfScreen = false;
Pokitto 31:f4b9b85c7b62 699 }
Pokitto 31:f4b9b85c7b62 700
Pokitto 31:f4b9b85c7b62 701 // Check for out-of-screen
Pokitto 31:f4b9b85c7b62 702 if (sprx >= LCDWIDTH || spry >= LCDHEIGHT)
Pokitto 31:f4b9b85c7b62 703 isCurrentSpriteOutOfScreen = true;
Pokitto 31:f4b9b85c7b62 704 if (sprOldX >= LCDWIDTH || sprOldY >= LCDHEIGHT)
Pokitto 31:f4b9b85c7b62 705 isOldSpriteOutOfScreen = true;
Pokitto 31:f4b9b85c7b62 706
Pokitto 31:f4b9b85c7b62 707 // Skip if current and old sprites are out-of-screen
Pokitto 31:f4b9b85c7b62 708 if (isCurrentSpriteOutOfScreen && isOldSpriteOutOfScreen)
Pokitto 31:f4b9b85c7b62 709 continue;
Pokitto 31:f4b9b85c7b62 710
Pokitto 31:f4b9b85c7b62 711 // Detect the dirty rect x-span by combining the previous and current sprite position.
Pokitto 31:f4b9b85c7b62 712 int16_t sprDirtyXMin = min(sprx, sprOldX);
Pokitto 31:f4b9b85c7b62 713 int16_t sprDirtyXMax = max(sprx, sprOldX);
Pokitto 31:f4b9b85c7b62 714 if (isCurrentSpriteOutOfScreen)
Pokitto 31:f4b9b85c7b62 715 sprDirtyXMax = sprOldX;
Pokitto 31:f4b9b85c7b62 716 if (isOldSpriteOutOfScreen)
Pokitto 31:f4b9b85c7b62 717 sprDirtyXMax = sprx;
Pokitto 31:f4b9b85c7b62 718
Pokitto 31:f4b9b85c7b62 719 // Is current x inside the sprite combined dirty rect ?
Pokitto 31:f4b9b85c7b62 720 int16_t sprDirtyXMaxEnd = sprDirtyXMax + sprw - 1 + 4; // Add 4 pixels to dirty rect width (needed?)
Pokitto 31:f4b9b85c7b62 721 if (sprDirtyXMin <= x+3 && x <= sprDirtyXMaxEnd) {
Pokitto 31:f4b9b85c7b62 722
Pokitto 31:f4b9b85c7b62 723 // *** COMBINE DIRTY RECTS FOR THIS SCANLINE GROUP ***
Pokitto 31:f4b9b85c7b62 724
Pokitto 31:f4b9b85c7b62 725 // Dirty rect
Pokitto 31:f4b9b85c7b62 726 int16_t sprDirtyYMin = min(spry, sprOldY);
Pokitto 31:f4b9b85c7b62 727 sprDirtyYMin = max(sprDirtyYMin, 0);
Pokitto 31:f4b9b85c7b62 728 int16_t sprDirtyYMax = max(spry, sprOldY);
Pokitto 31:f4b9b85c7b62 729 if (isCurrentSpriteOutOfScreen)
Pokitto 31:f4b9b85c7b62 730 sprDirtyYMax = sprOldY;
Pokitto 31:f4b9b85c7b62 731 if (isOldSpriteOutOfScreen)
Pokitto 31:f4b9b85c7b62 732 sprDirtyYMax = spry;
Pokitto 31:f4b9b85c7b62 733 int16_t sprDirtyYMaxEnd = sprDirtyYMax + sprh - 1;
Pokitto 31:f4b9b85c7b62 734 sprDirtyYMaxEnd = min(sprDirtyYMaxEnd, LCDHEIGHT - 1); // Should use LCDHEIGHT instead of screenH? Same with other screen* ?
Pokitto 31:f4b9b85c7b62 735
Pokitto 31:f4b9b85c7b62 736 // Get the scanline min and max y values for drawing
Pokitto 31:f4b9b85c7b62 737 if (sprDirtyYMin < scanlineMinY)
Pokitto 31:f4b9b85c7b62 738 scanlineMinY = sprDirtyYMin;
Pokitto 31:f4b9b85c7b62 739 if (sprDirtyYMaxEnd > scanlineMaxY)
Pokitto 31:f4b9b85c7b62 740 scanlineMaxY = sprDirtyYMaxEnd;
Pokitto 31:f4b9b85c7b62 741
Pokitto 31:f4b9b85c7b62 742 // *** PREPARE SPRITE FOR DRAWING ***
Pokitto 31:f4b9b85c7b62 743
Pokitto 31:f4b9b85c7b62 744 // Check if the sprite should be active for this vertical scanline group.
Pokitto 31:f4b9b85c7b62 745 if (sprindex < spriteCount && // not for update rect
Pokitto 31:f4b9b85c7b62 746 !isCurrentSpriteOutOfScreen && //out-of-screen
Pokitto 31:f4b9b85c7b62 747 sprx <= x+3 && x < sprx + sprw) { // note: cover group of 4 pixels of the scanline (x+3)
Pokitto 31:f4b9b85c7b62 748
Pokitto 31:f4b9b85c7b62 749 // Find the byte number in the sprite data
Pokitto 31:f4b9b85c7b62 750 int16_t byteNum = ((x+3) - sprx)>>2;
Pokitto 31:f4b9b85c7b62 751
Pokitto 31:f4b9b85c7b62 752 // Get the start addres of the spite data in this scanline.
Pokitto 31:f4b9b85c7b62 753 sprScanlineAddr[sprindex] = const_cast<uint8_t*>(sprites[sprindex].bitmapData + byteNum);
Pokitto 31:f4b9b85c7b62 754
Pokitto 31:f4b9b85c7b62 755 // If the sprite goes over the top, it must be clipped from the top.
Pokitto 31:f4b9b85c7b62 756 if(spry < 0)
Pokitto 31:f4b9b85c7b62 757 sprScanlineAddr[sprindex] += (-spry) * (sprw >> 2);
Pokitto 31:f4b9b85c7b62 758
Pokitto 31:f4b9b85c7b62 759 // Select the bitshift mode for the blit algorithm
Pokitto 31:f4b9b85c7b62 760 if (byteNum == 0)
Pokitto 31:f4b9b85c7b62 761 sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_FIRST_BYTE;
Pokitto 31:f4b9b85c7b62 762 else if (byteNum >= (sprw >> 2))
Pokitto 31:f4b9b85c7b62 763 sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_LAST_BYTE;
Pokitto 31:f4b9b85c7b62 764 else
Pokitto 31:f4b9b85c7b62 765 sprScanlineBitshiftMode[sprindex] = BITSHIFT_MODE_MIDDLE_BYTE;
Pokitto 31:f4b9b85c7b62 766 }
Pokitto 31:f4b9b85c7b62 767 else
Pokitto 31:f4b9b85c7b62 768 sprScanlineAddr[sprindex] = NULL; // Deactive sprite for this scanline
Pokitto 31:f4b9b85c7b62 769 }
Pokitto 31:f4b9b85c7b62 770 else
Pokitto 31:f4b9b85c7b62 771 sprScanlineAddr[sprindex] = NULL; // Deactive sprite for this scanline
Pokitto 31:f4b9b85c7b62 772 }
Pokitto 31:f4b9b85c7b62 773 }
Pokitto 31:f4b9b85c7b62 774
Pokitto 31:f4b9b85c7b62 775 // *** ADJUST THE SCANLINE GROUP HEIGHT ***
Pokitto 31:f4b9b85c7b62 776
Pokitto 31:f4b9b85c7b62 777 // The height must dividable by 8. That is needed because later we copy 8 pixels at a time to the LCD.
Pokitto 31:f4b9b85c7b62 778 if (scanlineMaxY - scanlineMinY + 1 > 0) {
Pokitto 31:f4b9b85c7b62 779 uint8_t scanlineH = scanlineMaxY - scanlineMinY + 1;
Pokitto 31:f4b9b85c7b62 780 uint8_t addW = 8 - (scanlineH & 0x7);
Pokitto 31:f4b9b85c7b62 781
Pokitto 31:f4b9b85c7b62 782 // if height is not dividable by 8, make it be.
Pokitto 31:f4b9b85c7b62 783 if (addW != 0) {
Pokitto 31:f4b9b85c7b62 784 if (scanlineMinY > addW )
Pokitto 31:f4b9b85c7b62 785 scanlineMinY -= addW;
Pokitto 31:f4b9b85c7b62 786 else if( scanlineMaxY + addW < updRectY+updRectH)
Pokitto 31:f4b9b85c7b62 787 scanlineMaxY += addW;
Pokitto 31:f4b9b85c7b62 788 else {
Pokitto 31:f4b9b85c7b62 789 // Draw full height scanline
Pokitto 31:f4b9b85c7b62 790 scanlineMinY = updRectY;
Pokitto 31:f4b9b85c7b62 791 scanlineMaxY = updRectY+updRectH-1;
Pokitto 31:f4b9b85c7b62 792 }
Pokitto 31:f4b9b85c7b62 793 }
Pokitto 31:f4b9b85c7b62 794 }
Pokitto 31:f4b9b85c7b62 795
Pokitto 31:f4b9b85c7b62 796 // *** COMBINE THE SCANLINE GROUP OF THE SCREEN BUFFER AND ALL SPRITES ***
Pokitto 31:f4b9b85c7b62 797
Pokitto 31:f4b9b85c7b62 798 // Find colours in this group of 4 scanlines
Pokitto 31:f4b9b85c7b62 799 screenBufScanlineAddr += (scanlineMinY * 220/4);
Pokitto 31:f4b9b85c7b62 800 for (y=scanlineMinY; y<=scanlineMaxY; y++)
Pokitto 31:f4b9b85c7b62 801 {
Pokitto 31:f4b9b85c7b62 802 // get the screen buffer data first
Pokitto 31:f4b9b85c7b62 803 uint8_t tdata = *screenBufScanlineAddr;
Pokitto 31:f4b9b85c7b62 804 uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
Pokitto 31:f4b9b85c7b62 805 uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
Pokitto 31:f4b9b85c7b62 806 uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
Pokitto 31:f4b9b85c7b62 807 uint8_t t = tdata & 0x03;// highest half-nibble
Pokitto 31:f4b9b85c7b62 808
Pokitto 31:f4b9b85c7b62 809 // Convert to 16-bit colors in palette
Pokitto 31:f4b9b85c7b62 810 uint16_t p = paletteptr[t];
Pokitto 31:f4b9b85c7b62 811 uint16_t p2 = paletteptr[t2];
Pokitto 31:f4b9b85c7b62 812 uint16_t p3 = paletteptr[t3];
Pokitto 31:f4b9b85c7b62 813 uint16_t p4 = paletteptr[t4];
Pokitto 31:f4b9b85c7b62 814
Pokitto 31:f4b9b85c7b62 815 #if 0
Pokitto 31:f4b9b85c7b62 816 // Dirty rect visual test
Pokitto 31:f4b9b85c7b62 817 p = COLOR_BLUE >> (Core::frameCount % 5);
Pokitto 31:f4b9b85c7b62 818 p2 = COLOR_BLUE >> (Core::frameCount % 5);
Pokitto 31:f4b9b85c7b62 819 p3 = COLOR_BLUE >> (Core::frameCount % 5);
Pokitto 31:f4b9b85c7b62 820 p4 = COLOR_BLUE >> (Core::frameCount % 5);
Pokitto 31:f4b9b85c7b62 821 #endif
Pokitto 31:f4b9b85c7b62 822
Pokitto 31:f4b9b85c7b62 823 // Add active sprite pixels
Pokitto 31:f4b9b85c7b62 824 if (sprites != NULL) {
Pokitto 31:f4b9b85c7b62 825
Pokitto 31:f4b9b85c7b62 826 // Use loop unrolling for speed optimization
Pokitto 31:f4b9b85c7b62 827 UNROLLED_LOOP_N(SPRITE_COUNT)
Pokitto 31:f4b9b85c7b62 828 }
Pokitto 31:f4b9b85c7b62 829
Pokitto 31:f4b9b85c7b62 830 // put the result nibble values in the scanline
Pokitto 31:f4b9b85c7b62 831 scanline[0][y] = p;
Pokitto 31:f4b9b85c7b62 832 scanline[1][y] = p2;
Pokitto 31:f4b9b85c7b62 833 scanline[2][y] = p3;
Pokitto 31:f4b9b85c7b62 834 scanline[3][y] = p4;
Pokitto 31:f4b9b85c7b62 835
Pokitto 31:f4b9b85c7b62 836 screenBufScanlineAddr += 220>>2; // jump to read byte directly below in screenbuffer
Pokitto 31:f4b9b85c7b62 837 }
Pokitto 31:f4b9b85c7b62 838
Pokitto 31:f4b9b85c7b62 839 // *** DRAW THE SCANLINE GROUP TO LCD
Pokitto 31:f4b9b85c7b62 840
Pokitto 31:f4b9b85c7b62 841 #ifdef PROJ_USE_FPS_COUNTER
Pokitto 31:f4b9b85c7b62 842 if (x>=8 && scanlineMaxY - scanlineMinY +1 > 0) {
Pokitto 31:f4b9b85c7b62 843 #else
Pokitto 31:f4b9b85c7b62 844 if (scanlineMaxY - scanlineMinY +1 > 0) {
Pokitto 31:f4b9b85c7b62 845 #endif
Pokitto 31:f4b9b85c7b62 846 // Draw 8 vertical pixels at a time for performance reasons
Pokitto 31:f4b9b85c7b62 847
Pokitto 31:f4b9b85c7b62 848 setDRAMptr(x, scanlineMinY);
Pokitto 31:f4b9b85c7b62 849 for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
Pokitto 31:f4b9b85c7b62 850 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 851 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 852 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 853 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 854 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 855 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 856 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 857 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 858 }
Pokitto 31:f4b9b85c7b62 859
Pokitto 31:f4b9b85c7b62 860 setDRAMptr(x+1, scanlineMinY);
Pokitto 31:f4b9b85c7b62 861 for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
Pokitto 31:f4b9b85c7b62 862 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 863 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 864 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 865 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 866 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 867 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 868 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 869 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 870 }
Pokitto 31:f4b9b85c7b62 871
Pokitto 31:f4b9b85c7b62 872 setDRAMptr(x+2, scanlineMinY);
Pokitto 31:f4b9b85c7b62 873 for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
Pokitto 31:f4b9b85c7b62 874 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 875 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 876 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 877 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 878 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 879 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 880 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 881 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 882 }
Pokitto 31:f4b9b85c7b62 883
Pokitto 31:f4b9b85c7b62 884 setDRAMptr(x+3, scanlineMinY);
Pokitto 31:f4b9b85c7b62 885 for (uint8_t s=scanlineMinY;s<=scanlineMaxY;) {
Pokitto 31:f4b9b85c7b62 886 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 887 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 888 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 889 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 890 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 891 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 892 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 893 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 894 }
Pokitto 31:f4b9b85c7b62 895 }
Pokitto 31:f4b9b85c7b62 896 }
Pokitto 31:f4b9b85c7b62 897
Pokitto 31:f4b9b85c7b62 898 // Update old x and y for the sprites
Pokitto 31:f4b9b85c7b62 899 if (sprites != NULL) {
Pokitto 31:f4b9b85c7b62 900 for (int sprindex = 0; sprindex < spriteCount; sprindex++) {
Pokitto 31:f4b9b85c7b62 901 sprites[sprindex].oldx = sprites[sprindex].x;
Pokitto 31:f4b9b85c7b62 902 sprites[sprindex].oldy = sprites[sprindex].y;
Pokitto 31:f4b9b85c7b62 903 }
Pokitto 31:f4b9b85c7b62 904 }
Pokitto 31:f4b9b85c7b62 905
Pokitto 31:f4b9b85c7b62 906 #ifdef POK_SIM
Pokitto 31:f4b9b85c7b62 907 simulator.refreshDisplay();
Pokitto 31:f4b9b85c7b62 908 #endif
Pokitto 31:f4b9b85c7b62 909 }
Pokitto 31:f4b9b85c7b62 910
Pokitto 31:f4b9b85c7b62 911 void Pokitto::lcdRefreshMode2(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 31:f4b9b85c7b62 912 uint16_t x,y;
Pokitto 31:f4b9b85c7b62 913 uint16_t scanline[2][88]; // read two nibbles = pixels at a time
Pokitto 31:f4b9b85c7b62 914 uint8_t *d;
Pokitto 31:f4b9b85c7b62 915
Pokitto 31:f4b9b85c7b62 916 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 917 write_data(0); // 0
Pokitto 31:f4b9b85c7b62 918 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 919 write_data(0);
Pokitto 31:f4b9b85c7b62 920 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 921 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 922
Pokitto 31:f4b9b85c7b62 923 for(x=0;x<110;x+=2)
Pokitto 31:f4b9b85c7b62 924 {
Pokitto 31:f4b9b85c7b62 925 d = scrbuf+(x>>1);// point to beginning of line in data
Pokitto 31:f4b9b85c7b62 926 /** find colours in one scanline **/
Pokitto 31:f4b9b85c7b62 927 uint8_t s=0;
Pokitto 31:f4b9b85c7b62 928 for(y=0;y<88;y++)
Pokitto 31:f4b9b85c7b62 929 {
Pokitto 31:f4b9b85c7b62 930 uint8_t t = *d >> 4; // higher nibble
Pokitto 31:f4b9b85c7b62 931 uint8_t t2 = *d & 0xF; // lower nibble
Pokitto 31:f4b9b85c7b62 932 /** higher nibble = left pixel in pixel pair **/
Pokitto 31:f4b9b85c7b62 933 scanline[0][s] = paletteptr[t];
Pokitto 31:f4b9b85c7b62 934 scanline[1][s++] = paletteptr[t2];
Pokitto 31:f4b9b85c7b62 935 /** testing only **/
Pokitto 31:f4b9b85c7b62 936 //scanline[0][s] = 0xFFFF*(s&1);
Pokitto 31:f4b9b85c7b62 937 //scanline[1][s] = 0xFFFF*(!(s&1));
Pokitto 31:f4b9b85c7b62 938 //s++;
Pokitto 31:f4b9b85c7b62 939 /** until here **/
Pokitto 31:f4b9b85c7b62 940 d+=110/2; // jump to read byte directly below in screenbuffer
Pokitto 31:f4b9b85c7b62 941 }
Pokitto 31:f4b9b85c7b62 942 s=0;
Pokitto 31:f4b9b85c7b62 943 /** draw scanlines **/
Pokitto 31:f4b9b85c7b62 944 /** leftmost scanline twice**/
Pokitto 31:f4b9b85c7b62 945
Pokitto 31:f4b9b85c7b62 946 for (s=0;s<88;) {
Pokitto 31:f4b9b85c7b62 947 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 948 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 949 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 950 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 951 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 952 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 953 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 954 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 955 }
Pokitto 31:f4b9b85c7b62 956
Pokitto 31:f4b9b85c7b62 957 for (s=0;s<88;) {
Pokitto 31:f4b9b85c7b62 958 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 959 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 960 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 961 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 962 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 963 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 964 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 965 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 966 }
Pokitto 31:f4b9b85c7b62 967 /** rightmost scanline twice**/
Pokitto 31:f4b9b85c7b62 968 //setDRAMptr(xptr++,yoffset);
Pokitto 31:f4b9b85c7b62 969 for (s=0;s<88;) {
Pokitto 31:f4b9b85c7b62 970 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 971 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 972 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 973 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 974 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 975 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 976 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 977 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 978 }
Pokitto 31:f4b9b85c7b62 979
Pokitto 31:f4b9b85c7b62 980 for (s=0;s<88;) {
Pokitto 31:f4b9b85c7b62 981 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 982 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 983 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 984 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 985 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 986 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 987 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 988 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 989 }
Pokitto 31:f4b9b85c7b62 990 }
Pokitto 31:f4b9b85c7b62 991 }
Pokitto 31:f4b9b85c7b62 992
Pokitto 31:f4b9b85c7b62 993 void Pokitto::lcdRefreshMode3(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 31:f4b9b85c7b62 994 uint16_t x,y;
Pokitto 31:f4b9b85c7b62 995 uint16_t scanline[2][176]; // read two nibbles = pixels at a time
Pokitto 31:f4b9b85c7b62 996 uint8_t *d;
Pokitto 31:f4b9b85c7b62 997
Pokitto 31:f4b9b85c7b62 998 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 999 write_data(0); // 0
Pokitto 31:f4b9b85c7b62 1000 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 1001 write_data(0);
Pokitto 31:f4b9b85c7b62 1002 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 1003 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 1004
Pokitto 31:f4b9b85c7b62 1005 for(x=0;x<220;x+=2)
Pokitto 31:f4b9b85c7b62 1006 {
Pokitto 31:f4b9b85c7b62 1007 d = scrbuf+(x>>1);// point to beginning of line in data
Pokitto 31:f4b9b85c7b62 1008 /** find colours in one scanline **/
Pokitto 31:f4b9b85c7b62 1009 uint8_t s=0;
Pokitto 31:f4b9b85c7b62 1010 for(y=0;y<176;y++)
Pokitto 31:f4b9b85c7b62 1011 {
Pokitto 31:f4b9b85c7b62 1012 uint8_t t = *d >> 4; // higher nibble
Pokitto 31:f4b9b85c7b62 1013 uint8_t t2 = *d & 0xF; // lower nibble
Pokitto 31:f4b9b85c7b62 1014 /** higher nibble = left pixel in pixel pair **/
Pokitto 31:f4b9b85c7b62 1015 scanline[0][s] = paletteptr[t];
Pokitto 31:f4b9b85c7b62 1016 scanline[1][s++] = paletteptr[t2];
Pokitto 31:f4b9b85c7b62 1017 /** testing only **/
Pokitto 31:f4b9b85c7b62 1018 //scanline[0][s] = 0xFFFF*(s&1);
Pokitto 31:f4b9b85c7b62 1019 //scanline[1][s] = 0xFFFF*(!(s&1));
Pokitto 31:f4b9b85c7b62 1020 //s++;
Pokitto 31:f4b9b85c7b62 1021 /** until here **/
Pokitto 31:f4b9b85c7b62 1022 d+=220/2; // jump to read byte directly below in screenbuffer
Pokitto 31:f4b9b85c7b62 1023 }
Pokitto 31:f4b9b85c7b62 1024 s=0;
Pokitto 31:f4b9b85c7b62 1025 /** draw scanlines **/
Pokitto 31:f4b9b85c7b62 1026 /** leftmost scanline**/
Pokitto 31:f4b9b85c7b62 1027
Pokitto 31:f4b9b85c7b62 1028 for (s=0;s<176;) {
Pokitto 31:f4b9b85c7b62 1029 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1030 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1031 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1032 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1033 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1034 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1035 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1036 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1037 }
Pokitto 31:f4b9b85c7b62 1038
Pokitto 31:f4b9b85c7b62 1039 /** rightmost scanline**/
Pokitto 31:f4b9b85c7b62 1040 //setDRAMptr(xptr++,yoffset);
Pokitto 31:f4b9b85c7b62 1041 for (s=0;s<176;) {
Pokitto 31:f4b9b85c7b62 1042 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1043 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1044 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1045 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1046 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1047 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1048 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1049 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1050 }
Pokitto 31:f4b9b85c7b62 1051 }
Pokitto 31:f4b9b85c7b62 1052 }
Pokitto 31:f4b9b85c7b62 1053
Pokitto 31:f4b9b85c7b62 1054 void Pokitto::lcdRefreshGB(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 31:f4b9b85c7b62 1055 uint16_t x,y;
Pokitto 31:f4b9b85c7b62 1056 uint16_t scanline[48];
Pokitto 31:f4b9b85c7b62 1057 uint8_t * d;
Pokitto 31:f4b9b85c7b62 1058
Pokitto 31:f4b9b85c7b62 1059 #if POK_STRETCH
Pokitto 31:f4b9b85c7b62 1060 //uint16_t xptr = 8;
Pokitto 31:f4b9b85c7b62 1061 #else
Pokitto 31:f4b9b85c7b62 1062 //xptr = 26;
Pokitto 31:f4b9b85c7b62 1063 #endif
Pokitto 31:f4b9b85c7b62 1064
Pokitto 31:f4b9b85c7b62 1065 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 1066 write_data(0); // 0
Pokitto 31:f4b9b85c7b62 1067 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 1068 write_data(0);
Pokitto 31:f4b9b85c7b62 1069 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 1070 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 1071
Pokitto 31:f4b9b85c7b62 1072 /** draw border **/
Pokitto 31:f4b9b85c7b62 1073 for (int s=0;s<5*176;) {
Pokitto 31:f4b9b85c7b62 1074 setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;s++;
Pokitto 31:f4b9b85c7b62 1075 }
Pokitto 31:f4b9b85c7b62 1076
Pokitto 31:f4b9b85c7b62 1077 for(x=0;x<84;x++)
Pokitto 31:f4b9b85c7b62 1078 {
Pokitto 31:f4b9b85c7b62 1079
Pokitto 31:f4b9b85c7b62 1080 d = scrbuf + x;// point to beginning of line in data
Pokitto 31:f4b9b85c7b62 1081
Pokitto 31:f4b9b85c7b62 1082 /** find colours in one scanline **/
Pokitto 31:f4b9b85c7b62 1083 uint8_t s=0;
Pokitto 31:f4b9b85c7b62 1084 for(y=0;y<6;y++)
Pokitto 31:f4b9b85c7b62 1085 {
Pokitto 31:f4b9b85c7b62 1086 uint8_t t = *d;
Pokitto 31:f4b9b85c7b62 1087 #if POK_COLORDEPTH > 1
Pokitto 31:f4b9b85c7b62 1088 uint8_t t2 = *(d+504);
Pokitto 31:f4b9b85c7b62 1089 #endif
Pokitto 31:f4b9b85c7b62 1090 #if POK_COLORDEPTH > 2
Pokitto 31:f4b9b85c7b62 1091 uint8_t t3 = *(d+504+504);
Pokitto 31:f4b9b85c7b62 1092 #endif
Pokitto 31:f4b9b85c7b62 1093 #if POK_COLORDEPTH > 3
Pokitto 31:f4b9b85c7b62 1094 uint8_t t4 = *(d+504+504+504);
Pokitto 31:f4b9b85c7b62 1095 #endif
Pokitto 31:f4b9b85c7b62 1096 uint8_t paletteindex = 0;
Pokitto 31:f4b9b85c7b62 1097
Pokitto 31:f4b9b85c7b62 1098 /** bit 1 **/
Pokitto 31:f4b9b85c7b62 1099 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1100 paletteindex = (t & 0x1);
Pokitto 31:f4b9b85c7b62 1101 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1102 paletteindex = ((t & 0x1)) | ((t2 & 0x01)<<1);
Pokitto 31:f4b9b85c7b62 1103 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1104 paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2);
Pokitto 31:f4b9b85c7b62 1105 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1106 paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2) | ((t4 & 0x1)<<3);
Pokitto 31:f4b9b85c7b62 1107 #endif
Pokitto 31:f4b9b85c7b62 1108 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1109
Pokitto 31:f4b9b85c7b62 1110 /** bit 2 **/
Pokitto 31:f4b9b85c7b62 1111 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1112 paletteindex = (t & 0x2)>>1;
Pokitto 31:f4b9b85c7b62 1113 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1114 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x02));
Pokitto 31:f4b9b85c7b62 1115 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1116 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1);
Pokitto 31:f4b9b85c7b62 1117 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1118 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1) | ((t4 & 0x2)<<2);
Pokitto 31:f4b9b85c7b62 1119 #endif
Pokitto 31:f4b9b85c7b62 1120 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1121
Pokitto 31:f4b9b85c7b62 1122 /** bit 3 **/
Pokitto 31:f4b9b85c7b62 1123 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1124 paletteindex = (t & 0x4)>>2;
Pokitto 31:f4b9b85c7b62 1125 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1126 paletteindex = ((t & 4)>>2) | ((t2 & 0x04)>>1);
Pokitto 31:f4b9b85c7b62 1127 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1128 paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4);
Pokitto 31:f4b9b85c7b62 1129 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1130 paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4) | ((t4 & 0x4)<<1);
Pokitto 31:f4b9b85c7b62 1131 #endif
Pokitto 31:f4b9b85c7b62 1132 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1133
Pokitto 31:f4b9b85c7b62 1134 /** bit 4 **/
Pokitto 31:f4b9b85c7b62 1135 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1136 paletteindex = (t & 0x8)>>3;
Pokitto 31:f4b9b85c7b62 1137 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1138 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x08)>>2);
Pokitto 31:f4b9b85c7b62 1139 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1140 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1);
Pokitto 31:f4b9b85c7b62 1141 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1142 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1) | (t4 & 0x8);
Pokitto 31:f4b9b85c7b62 1143 #endif
Pokitto 31:f4b9b85c7b62 1144 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1145
Pokitto 31:f4b9b85c7b62 1146 /** bit 5 **/
Pokitto 31:f4b9b85c7b62 1147 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1148 paletteindex = (t & 0x10)>>4;
Pokitto 31:f4b9b85c7b62 1149 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1150 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3);
Pokitto 31:f4b9b85c7b62 1151 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1152 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2);
Pokitto 31:f4b9b85c7b62 1153 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1154 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2) | ((t4 & 0x10)>>1);
Pokitto 31:f4b9b85c7b62 1155 #endif
Pokitto 31:f4b9b85c7b62 1156 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1157
Pokitto 31:f4b9b85c7b62 1158 /** bit 6 **/
Pokitto 31:f4b9b85c7b62 1159 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1160 paletteindex = (t & 0x20)>>5;
Pokitto 31:f4b9b85c7b62 1161 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1162 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4);
Pokitto 31:f4b9b85c7b62 1163 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1164 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3);
Pokitto 31:f4b9b85c7b62 1165 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1166 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3) | ((t4 & 0x20)>>2);
Pokitto 31:f4b9b85c7b62 1167 #endif
Pokitto 31:f4b9b85c7b62 1168 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1169
Pokitto 31:f4b9b85c7b62 1170 /** bit 7 **/
Pokitto 31:f4b9b85c7b62 1171 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1172 paletteindex = (t & 0x40)>>6;
Pokitto 31:f4b9b85c7b62 1173 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1174 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5);
Pokitto 31:f4b9b85c7b62 1175 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1176 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) ;
Pokitto 31:f4b9b85c7b62 1177 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1178 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) | ((t4 & 0x40)>>3);
Pokitto 31:f4b9b85c7b62 1179 #endif
Pokitto 31:f4b9b85c7b62 1180 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1181
Pokitto 31:f4b9b85c7b62 1182 /** bit 8 **/
Pokitto 31:f4b9b85c7b62 1183 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1184 paletteindex = (t & 0x80)>>7;
Pokitto 31:f4b9b85c7b62 1185 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1186 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6);
Pokitto 31:f4b9b85c7b62 1187 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1188 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5);
Pokitto 31:f4b9b85c7b62 1189 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1190 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5) | ((t4 & 0x80)>>4);
Pokitto 31:f4b9b85c7b62 1191 #endif
Pokitto 31:f4b9b85c7b62 1192 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1193
Pokitto 31:f4b9b85c7b62 1194 d+=84; // jump to byte directly below
Pokitto 31:f4b9b85c7b62 1195 }
Pokitto 31:f4b9b85c7b62 1196
Pokitto 31:f4b9b85c7b62 1197
Pokitto 31:f4b9b85c7b62 1198 /*write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 1199 write_data(0x10); // 0
Pokitto 31:f4b9b85c7b62 1200 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 1201 write_data(xptr++);
Pokitto 31:f4b9b85c7b62 1202 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 1203 CLR_CS_SET_CD_RD_WR;*/
Pokitto 31:f4b9b85c7b62 1204 /** draw border **/
Pokitto 31:f4b9b85c7b62 1205 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 31:f4b9b85c7b62 1206
Pokitto 31:f4b9b85c7b62 1207 s=0;
Pokitto 31:f4b9b85c7b62 1208
Pokitto 31:f4b9b85c7b62 1209 /** draw scanlines **/
Pokitto 31:f4b9b85c7b62 1210 for (s=0;s<48;) {
Pokitto 31:f4b9b85c7b62 1211 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1212 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1213 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1214 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1215 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1216 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1217 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1218 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1219 }
Pokitto 31:f4b9b85c7b62 1220 /** draw border **/
Pokitto 31:f4b9b85c7b62 1221 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 31:f4b9b85c7b62 1222
Pokitto 31:f4b9b85c7b62 1223
Pokitto 31:f4b9b85c7b62 1224 /*write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 1225 write_data(0x10); // 0
Pokitto 31:f4b9b85c7b62 1226 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 1227 write_data(xptr++);
Pokitto 31:f4b9b85c7b62 1228 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 1229 CLR_CS_SET_CD_RD_WR;*/
Pokitto 31:f4b9b85c7b62 1230 /** draw border **/
Pokitto 31:f4b9b85c7b62 1231 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 31:f4b9b85c7b62 1232
Pokitto 31:f4b9b85c7b62 1233 for (s=0;s<48;) {
Pokitto 31:f4b9b85c7b62 1234 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1235 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1236 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1237 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1238 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1239 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1240 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1241 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1242 }
Pokitto 31:f4b9b85c7b62 1243
Pokitto 31:f4b9b85c7b62 1244 /** draw border **/
Pokitto 31:f4b9b85c7b62 1245 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 31:f4b9b85c7b62 1246
Pokitto 31:f4b9b85c7b62 1247
Pokitto 31:f4b9b85c7b62 1248 #if POK_STRETCH
Pokitto 31:f4b9b85c7b62 1249 //if (x>16 && x<68)
Pokitto 31:f4b9b85c7b62 1250 if (x&2)// && x&2)
Pokitto 31:f4b9b85c7b62 1251 {
Pokitto 31:f4b9b85c7b62 1252 /*write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 1253 write_data(0x10); // 0
Pokitto 31:f4b9b85c7b62 1254 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 1255 write_data(xptr++);
Pokitto 31:f4b9b85c7b62 1256 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 1257 CLR_CS_SET_CD_RD_WR;*/
Pokitto 31:f4b9b85c7b62 1258 /** draw border **/
Pokitto 31:f4b9b85c7b62 1259 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 31:f4b9b85c7b62 1260
Pokitto 31:f4b9b85c7b62 1261
Pokitto 31:f4b9b85c7b62 1262 for (s=0;s<48;) {
Pokitto 31:f4b9b85c7b62 1263 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1264 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1265 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1266 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1267 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1268 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1269 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1270 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1271 }
Pokitto 31:f4b9b85c7b62 1272
Pokitto 31:f4b9b85c7b62 1273 /** draw border **/
Pokitto 31:f4b9b85c7b62 1274 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 31:f4b9b85c7b62 1275
Pokitto 31:f4b9b85c7b62 1276 }
Pokitto 31:f4b9b85c7b62 1277 #endif
Pokitto 31:f4b9b85c7b62 1278 }
Pokitto 31:f4b9b85c7b62 1279 /** draw border **/
Pokitto 31:f4b9b85c7b62 1280 for (int s=0;s<5*176;) {
Pokitto 31:f4b9b85c7b62 1281 setup_data_16(COLOR_BLACK);CLR_WR;SET_WR;s++;
Pokitto 31:f4b9b85c7b62 1282 }
Pokitto 31:f4b9b85c7b62 1283 }
Pokitto 31:f4b9b85c7b62 1284
Pokitto 31:f4b9b85c7b62 1285
Pokitto 31:f4b9b85c7b62 1286 void Pokitto::lcdRefreshAB(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 31:f4b9b85c7b62 1287 uint16_t x,y;
Pokitto 31:f4b9b85c7b62 1288 uint16_t scanline[64];
Pokitto 31:f4b9b85c7b62 1289 uint8_t *d;
Pokitto 31:f4b9b85c7b62 1290 //lcdClear();
Pokitto 31:f4b9b85c7b62 1291 #if POK_STRETCH
Pokitto 31:f4b9b85c7b62 1292 uint16_t xptr = 14;
Pokitto 31:f4b9b85c7b62 1293 uint8_t yoffset = 24;
Pokitto 31:f4b9b85c7b62 1294 #else
Pokitto 31:f4b9b85c7b62 1295 xptr = 0; //was 26
Pokitto 31:f4b9b85c7b62 1296 #endif
Pokitto 31:f4b9b85c7b62 1297
Pokitto 31:f4b9b85c7b62 1298 for(x=0;x<128;x++)
Pokitto 31:f4b9b85c7b62 1299 {
Pokitto 31:f4b9b85c7b62 1300 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 1301 write_data(yoffset); // 0
Pokitto 31:f4b9b85c7b62 1302 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 1303 write_data(xptr++);
Pokitto 31:f4b9b85c7b62 1304 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 1305 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 1306 //setDRAMptr(xptr++,yoffset);
Pokitto 31:f4b9b85c7b62 1307
Pokitto 31:f4b9b85c7b62 1308 d = scrbuf + x;// point to beginning of line in data
Pokitto 31:f4b9b85c7b62 1309
Pokitto 31:f4b9b85c7b62 1310 /** find colours in one scanline **/
Pokitto 31:f4b9b85c7b62 1311 uint8_t s=0;
Pokitto 31:f4b9b85c7b62 1312 for(y=0;y<8;y++)
Pokitto 31:f4b9b85c7b62 1313 {
Pokitto 31:f4b9b85c7b62 1314 uint8_t t = *d;
Pokitto 31:f4b9b85c7b62 1315 #if POK_COLORDEPTH > 1
Pokitto 31:f4b9b85c7b62 1316 uint8_t t2 = *(d+AB_JUMP);
Pokitto 31:f4b9b85c7b62 1317 #endif // POK_COLORDEPTH
Pokitto 31:f4b9b85c7b62 1318 #if POK_COLORDEPTH > 2
Pokitto 31:f4b9b85c7b62 1319 uint8_t t3 = *(d+AB_JUMP+AB_JUMP);
Pokitto 31:f4b9b85c7b62 1320 #endif // POK_COLORDEPTH
Pokitto 31:f4b9b85c7b62 1321 #if POK_COLORDEPTH > 3
Pokitto 31:f4b9b85c7b62 1322 uint8_t t4 = *(d+AB_JUMP+AB_JUMP+AB_JUMP);
Pokitto 31:f4b9b85c7b62 1323 #endif // POK_COLORDEPTH
Pokitto 31:f4b9b85c7b62 1324 uint8_t paletteindex = 0;
Pokitto 31:f4b9b85c7b62 1325
Pokitto 31:f4b9b85c7b62 1326 /** bit 1 **/
Pokitto 31:f4b9b85c7b62 1327 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1328 paletteindex = (t & 0x1);
Pokitto 31:f4b9b85c7b62 1329 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1330 paletteindex = ((t & 0x1)) | ((t2 & 0x01)<<1);
Pokitto 31:f4b9b85c7b62 1331 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1332 paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2);
Pokitto 31:f4b9b85c7b62 1333 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1334 paletteindex = (t & 0x1) | ((t2 & 0x1)<<1) | ((t3 & 0x1)<<2) | ((t4 & 0x1)<<3);
Pokitto 31:f4b9b85c7b62 1335 #endif
Pokitto 31:f4b9b85c7b62 1336 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1337
Pokitto 31:f4b9b85c7b62 1338 /** bit 2 **/
Pokitto 31:f4b9b85c7b62 1339 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1340 paletteindex = (t & 0x2)>>1;
Pokitto 31:f4b9b85c7b62 1341 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1342 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x02));
Pokitto 31:f4b9b85c7b62 1343 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1344 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1);
Pokitto 31:f4b9b85c7b62 1345 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1346 paletteindex = ((t & 0x2)>>1) | ((t2 & 0x2)) | ((t3 & 0x2)<<1) | ((t4 & 0x2)<<2);
Pokitto 31:f4b9b85c7b62 1347 #endif
Pokitto 31:f4b9b85c7b62 1348 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1349
Pokitto 31:f4b9b85c7b62 1350 /** bit 3 **/
Pokitto 31:f4b9b85c7b62 1351 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1352 paletteindex = (t & 0x4)>>2;
Pokitto 31:f4b9b85c7b62 1353 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1354 paletteindex = ((t & 4)>>2) | ((t2 & 0x04)>>1);
Pokitto 31:f4b9b85c7b62 1355 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1356 paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4);
Pokitto 31:f4b9b85c7b62 1357 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1358 paletteindex = ((t & 0x4)>>2) | ((t2 & 0x4)>>1) | (t3 & 0x4) | ((t4 & 0x4)<<1);
Pokitto 31:f4b9b85c7b62 1359 #endif
Pokitto 31:f4b9b85c7b62 1360 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1361
Pokitto 31:f4b9b85c7b62 1362 /** bit 4 **/
Pokitto 31:f4b9b85c7b62 1363 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1364 paletteindex = (t & 0x8)>>3;
Pokitto 31:f4b9b85c7b62 1365 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1366 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x08)>>2);
Pokitto 31:f4b9b85c7b62 1367 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1368 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1);
Pokitto 31:f4b9b85c7b62 1369 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1370 paletteindex = ((t & 0x8)>>3) | ((t2 & 0x8)>>2) | ((t3 & 0x8)>>1) | (t4 & 0x8);
Pokitto 31:f4b9b85c7b62 1371 #endif
Pokitto 31:f4b9b85c7b62 1372 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1373
Pokitto 31:f4b9b85c7b62 1374 /** bit 5 **/
Pokitto 31:f4b9b85c7b62 1375 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1376 paletteindex = (t & 0x10)>>4;
Pokitto 31:f4b9b85c7b62 1377 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1378 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3);
Pokitto 31:f4b9b85c7b62 1379 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1380 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2);
Pokitto 31:f4b9b85c7b62 1381 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1382 paletteindex = ((t & 0x10)>>4) | ((t2 & 0x10)>>3) | ((t3 & 0x10)>>2) | ((t4 & 0x10)>>1);
Pokitto 31:f4b9b85c7b62 1383 #endif
Pokitto 31:f4b9b85c7b62 1384 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1385
Pokitto 31:f4b9b85c7b62 1386 /** bit 6 **/
Pokitto 31:f4b9b85c7b62 1387 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1388 paletteindex = (t & 0x20)>>5;
Pokitto 31:f4b9b85c7b62 1389 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1390 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4);
Pokitto 31:f4b9b85c7b62 1391 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1392 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3);
Pokitto 31:f4b9b85c7b62 1393 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1394 paletteindex = ((t & 0x20)>>5) | ((t2 & 0x20)>>4) | ((t3 & 0x20)>>3) | ((t4 & 0x20)>>2);
Pokitto 31:f4b9b85c7b62 1395 #endif
Pokitto 31:f4b9b85c7b62 1396 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1397
Pokitto 31:f4b9b85c7b62 1398 /** bit 7 **/
Pokitto 31:f4b9b85c7b62 1399 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1400 paletteindex = (t & 0x40)>>6;
Pokitto 31:f4b9b85c7b62 1401 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1402 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5);
Pokitto 31:f4b9b85c7b62 1403 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1404 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) ;
Pokitto 31:f4b9b85c7b62 1405 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1406 paletteindex = ((t & 0x40)>>6) | ((t2 & 0x40)>>5) | ((t3 & 0x40)>>4) | ((t4 & 0x40)>>3);
Pokitto 31:f4b9b85c7b62 1407 #endif
Pokitto 31:f4b9b85c7b62 1408 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1409
Pokitto 31:f4b9b85c7b62 1410 /** bit 8 **/
Pokitto 31:f4b9b85c7b62 1411 #if POK_COLORDEPTH == 1
Pokitto 31:f4b9b85c7b62 1412 paletteindex = (t & 0x80)>>7;
Pokitto 31:f4b9b85c7b62 1413 #elif POK_COLORDEPTH == 2
Pokitto 31:f4b9b85c7b62 1414 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6);
Pokitto 31:f4b9b85c7b62 1415 #elif POK_COLORDEPTH == 3
Pokitto 31:f4b9b85c7b62 1416 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5);
Pokitto 31:f4b9b85c7b62 1417 #elif POK_COLORDEPTH == 4
Pokitto 31:f4b9b85c7b62 1418 paletteindex = ((t & 0x80)>>7) | ((t2 & 0x80)>>6) | ((t3 & 0x80)>>5) | ((t4 & 0x80)>>4);
Pokitto 31:f4b9b85c7b62 1419 #endif
Pokitto 31:f4b9b85c7b62 1420 scanline[s++] = paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1421
Pokitto 31:f4b9b85c7b62 1422 d+=128; // jump to byte directly below
Pokitto 31:f4b9b85c7b62 1423 }
Pokitto 31:f4b9b85c7b62 1424
Pokitto 31:f4b9b85c7b62 1425 s=0;
Pokitto 31:f4b9b85c7b62 1426
Pokitto 31:f4b9b85c7b62 1427 /** draw scanlines **/
Pokitto 31:f4b9b85c7b62 1428 for (s=0;s<64;) {
Pokitto 31:f4b9b85c7b62 1429 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1430 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1431 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1432 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1433 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1434 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1435 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1436 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1437 }
Pokitto 31:f4b9b85c7b62 1438
Pokitto 31:f4b9b85c7b62 1439 #if POK_STRETCH
Pokitto 31:f4b9b85c7b62 1440 if (x&1) {
Pokitto 31:f4b9b85c7b62 1441 write_command(0x20); // Horizontal DRAM Address
Pokitto 31:f4b9b85c7b62 1442 write_data(yoffset); // 0
Pokitto 31:f4b9b85c7b62 1443 write_command(0x21); // Vertical DRAM Address
Pokitto 31:f4b9b85c7b62 1444 write_data(xptr++);
Pokitto 31:f4b9b85c7b62 1445 write_command(0x22); // write data to DRAM
Pokitto 31:f4b9b85c7b62 1446 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 1447 //setDRAMptr(xptr++,yoffset);
Pokitto 31:f4b9b85c7b62 1448
Pokitto 31:f4b9b85c7b62 1449 for (s=0;s<64;) {
Pokitto 31:f4b9b85c7b62 1450 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1451 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1452 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1453 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1454 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1455 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1456 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1457 setup_data_16(scanline[s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1458 }
Pokitto 31:f4b9b85c7b62 1459 }
Pokitto 31:f4b9b85c7b62 1460 #endif
Pokitto 31:f4b9b85c7b62 1461 }
Pokitto 31:f4b9b85c7b62 1462 }
Pokitto 31:f4b9b85c7b62 1463
Pokitto 31:f4b9b85c7b62 1464 void Pokitto::lcdRefreshModeGBC(uint8_t * scrbuf, uint16_t* paletteptr) {
Pokitto 31:f4b9b85c7b62 1465 uint16_t x,y,xptr;
Pokitto 31:f4b9b85c7b62 1466 uint16_t scanline[4][144]; // read 4 half-nibbles = 4 pixels at a time
Pokitto 31:f4b9b85c7b62 1467 uint8_t *d, yoffset=0;
Pokitto 31:f4b9b85c7b62 1468
Pokitto 31:f4b9b85c7b62 1469 xptr = 0;
Pokitto 31:f4b9b85c7b62 1470 setDRAMptr(xptr,yoffset);
Pokitto 31:f4b9b85c7b62 1471
Pokitto 31:f4b9b85c7b62 1472
Pokitto 31:f4b9b85c7b62 1473 for(x=0;x<160;x+=4)
Pokitto 31:f4b9b85c7b62 1474 {
Pokitto 31:f4b9b85c7b62 1475 d = scrbuf+(x>>2);// point to beginning of line in data
Pokitto 31:f4b9b85c7b62 1476 /** find colours in one scanline **/
Pokitto 31:f4b9b85c7b62 1477 uint8_t s=0;
Pokitto 31:f4b9b85c7b62 1478 for(y=0;y<144;y++)
Pokitto 31:f4b9b85c7b62 1479 {
Pokitto 31:f4b9b85c7b62 1480 uint8_t tdata = *d;
Pokitto 31:f4b9b85c7b62 1481 uint8_t t4 = tdata & 0x03; tdata >>= 2;// lowest half-nibble
Pokitto 31:f4b9b85c7b62 1482 uint8_t t3 = tdata & 0x03; tdata >>= 2;// second lowest half-nibble
Pokitto 31:f4b9b85c7b62 1483 uint8_t t2 = tdata & 0x03; tdata >>= 2;// second highest half-nibble
Pokitto 31:f4b9b85c7b62 1484 uint8_t t = tdata & 0x03;// highest half-nibble
Pokitto 31:f4b9b85c7b62 1485
Pokitto 31:f4b9b85c7b62 1486 /** put nibble values in the scanlines **/
Pokitto 31:f4b9b85c7b62 1487
Pokitto 31:f4b9b85c7b62 1488 scanline[0][s] = paletteptr[t];
Pokitto 31:f4b9b85c7b62 1489 scanline[1][s] = paletteptr[t2];
Pokitto 31:f4b9b85c7b62 1490 scanline[2][s] = paletteptr[t3];
Pokitto 31:f4b9b85c7b62 1491 scanline[3][s++] = paletteptr[t4];
Pokitto 31:f4b9b85c7b62 1492
Pokitto 31:f4b9b85c7b62 1493 d+=160/4; // jump to read byte directly below in screenbuffer
Pokitto 31:f4b9b85c7b62 1494 }
Pokitto 31:f4b9b85c7b62 1495
Pokitto 31:f4b9b85c7b62 1496 s=0;
Pokitto 31:f4b9b85c7b62 1497 /** draw scanlines **/
Pokitto 31:f4b9b85c7b62 1498 for (s=0;s<144;) {
Pokitto 31:f4b9b85c7b62 1499 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1500 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1501 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1502 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1503 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1504 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1505 }
Pokitto 31:f4b9b85c7b62 1506 setDRAMptr(++xptr,yoffset);
Pokitto 31:f4b9b85c7b62 1507 for (s=0;s<144;) {
Pokitto 31:f4b9b85c7b62 1508 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1509 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1510 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1511 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1512 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1513 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1514 }
Pokitto 31:f4b9b85c7b62 1515 setDRAMptr(++xptr,yoffset);
Pokitto 31:f4b9b85c7b62 1516 for (s=0;s<144;) {
Pokitto 31:f4b9b85c7b62 1517 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1518 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1519 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1520 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1521 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1522 setup_data_16(scanline[2][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1523 }
Pokitto 31:f4b9b85c7b62 1524 setDRAMptr(++xptr,yoffset);
Pokitto 31:f4b9b85c7b62 1525 for (s=0;s<144;) {
Pokitto 31:f4b9b85c7b62 1526 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1527 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1528 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1529 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1530 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1531 setup_data_16(scanline[3][s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1532 }
Pokitto 31:f4b9b85c7b62 1533 setDRAMptr(++xptr,yoffset);
Pokitto 31:f4b9b85c7b62 1534 }
Pokitto 31:f4b9b85c7b62 1535 }
Pokitto 31:f4b9b85c7b62 1536
Pokitto 31:f4b9b85c7b62 1537
Pokitto 31:f4b9b85c7b62 1538 void Pokitto::lcdRefreshT1(uint8_t* tilebuf, uint8_t* tilecolorbuf, uint8_t* tileset, uint16_t* paletteptr) {
Pokitto 31:f4b9b85c7b62 1539 #ifdef POK_TILEMODE
Pokitto 31:f4b9b85c7b62 1540 uint16_t x,y,data,xptr;
Pokitto 31:f4b9b85c7b62 1541 uint16_t scanline[176];
Pokitto 31:f4b9b85c7b62 1542 uint8_t yoffset=0, tilebyte, tileindex, tilex=0, tiley=0,xcount;
Pokitto 31:f4b9b85c7b62 1543
Pokitto 31:f4b9b85c7b62 1544
Pokitto 31:f4b9b85c7b62 1545 if (!tileset) return;
Pokitto 31:f4b9b85c7b62 1546
Pokitto 31:f4b9b85c7b62 1547 #if LCDWIDTH < POK_LCD_W
Pokitto 31:f4b9b85c7b62 1548 xptr = (POK_LCD_W-LCDWIDTH)/2;
Pokitto 31:f4b9b85c7b62 1549 #else
Pokitto 31:f4b9b85c7b62 1550 xptr = 0;
Pokitto 31:f4b9b85c7b62 1551 #endif
Pokitto 31:f4b9b85c7b62 1552 #if LCDHEIGHT < POK_LCD_H
Pokitto 31:f4b9b85c7b62 1553 yoffset = (POK_LCD_H-LCDHEIGHT)/2;
Pokitto 31:f4b9b85c7b62 1554 #else
Pokitto 31:f4b9b85c7b62 1555 yoffset = 0;
Pokitto 31:f4b9b85c7b62 1556 #endif
Pokitto 31:f4b9b85c7b62 1557
Pokitto 31:f4b9b85c7b62 1558 for(x=0, xcount=0 ;x<LCDWIDTH;x++,xcount++) // loop through vertical columns
Pokitto 31:f4b9b85c7b62 1559 {
Pokitto 31:f4b9b85c7b62 1560 setDRAMptr(xptr++,yoffset); //point to VRAM
Pokitto 31:f4b9b85c7b62 1561
Pokitto 31:f4b9b85c7b62 1562 /** find colours in one scanline **/
Pokitto 31:f4b9b85c7b62 1563 uint8_t s=0, tiley=0;
Pokitto 31:f4b9b85c7b62 1564 //tileindex = tilebuf[tilex*POK_TILES_Y];
Pokitto 31:f4b9b85c7b62 1565 if (xcount==POK_TILE_W) {
Pokitto 31:f4b9b85c7b62 1566 tilex++;
Pokitto 31:f4b9b85c7b62 1567 xcount=0;
Pokitto 31:f4b9b85c7b62 1568 }
Pokitto 31:f4b9b85c7b62 1569
Pokitto 31:f4b9b85c7b62 1570 for(y=0;y<LCDHEIGHT;)
Pokitto 31:f4b9b85c7b62 1571 {
Pokitto 31:f4b9b85c7b62 1572 uint8_t tileval = tilebuf[tilex+tiley*POK_TILES_X]; //get tile number
Pokitto 31:f4b9b85c7b62 1573 uint16_t index = tileval*POK_TILE_W+xcount;
Pokitto 31:f4b9b85c7b62 1574 uint8_t tilebyte = tileset[index]; //get bitmap data
Pokitto 31:f4b9b85c7b62 1575 for (uint8_t ycount=0, bitcount=0; ycount<POK_TILE_H; ycount++, y++, bitcount++) {
Pokitto 31:f4b9b85c7b62 1576 if (bitcount==8) {
Pokitto 31:f4b9b85c7b62 1577 bitcount=0;
Pokitto 31:f4b9b85c7b62 1578 index += 176; //jump to byte below in the tileset bitmap
Pokitto 31:f4b9b85c7b62 1579 tilebyte = tileset[index]; //get bitmap data
Pokitto 31:f4b9b85c7b62 1580 }
Pokitto 31:f4b9b85c7b62 1581 //tilebyte = tile[(tileindex>>4)+*POK_TILE_W]; //tilemaps are 16x16
Pokitto 31:f4b9b85c7b62 1582 //uint8_t paletteindex = ((tilebyte>>(bitcount&0x7)) & 0x1);
Pokitto 31:f4b9b85c7b62 1583 if (!tileval) scanline[s++] = COLOR_MAGENTA*((tilebyte>>bitcount)&0x1);//paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1584 else scanline[s++] = paletteptr[((tilebyte>>bitcount)&0x1)*tileval];//paletteptr[paletteindex];
Pokitto 31:f4b9b85c7b62 1585 }
Pokitto 31:f4b9b85c7b62 1586 tiley++; //move to next tile
Pokitto 31:f4b9b85c7b62 1587 }
Pokitto 31:f4b9b85c7b62 1588 s=0;
Pokitto 31:f4b9b85c7b62 1589
Pokitto 31:f4b9b85c7b62 1590 /** draw scanlines **/
Pokitto 31:f4b9b85c7b62 1591 for (s=0;s<LCDHEIGHT;) {
Pokitto 31:f4b9b85c7b62 1592 setup_data_16(scanline[s++]);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1593 }
Pokitto 31:f4b9b85c7b62 1594 }
Pokitto 31:f4b9b85c7b62 1595 #endif
Pokitto 31:f4b9b85c7b62 1596 }
Pokitto 31:f4b9b85c7b62 1597
Pokitto 31:f4b9b85c7b62 1598
Pokitto 31:f4b9b85c7b62 1599 void Pokitto::lcdRefreshMode13(uint8_t * scrbuf, uint16_t* paletteptr, uint8_t offset){
Pokitto 31:f4b9b85c7b62 1600 uint16_t x,y;
Pokitto 31:f4b9b85c7b62 1601 uint16_t scanline[2][110]; // read two nibbles = pixels at a time
Pokitto 31:f4b9b85c7b62 1602 uint8_t *d;
Pokitto 31:f4b9b85c7b62 1603
Pokitto 31:f4b9b85c7b62 1604 write_command(0x20); write_data(0);
Pokitto 31:f4b9b85c7b62 1605 write_command(0x21); write_data(0);
Pokitto 31:f4b9b85c7b62 1606 write_command(0x22);
Pokitto 31:f4b9b85c7b62 1607 CLR_CS_SET_CD_RD_WR;
Pokitto 31:f4b9b85c7b62 1608
Pokitto 31:f4b9b85c7b62 1609 for(x=0;x<110;x+=2)
Pokitto 31:f4b9b85c7b62 1610 {
Pokitto 31:f4b9b85c7b62 1611 d = scrbuf+x;// point to beginning of line in data
Pokitto 31:f4b9b85c7b62 1612 uint8_t s=0;
Pokitto 31:f4b9b85c7b62 1613 for(y=0;y<88;y++)
Pokitto 31:f4b9b85c7b62 1614 {
Pokitto 31:f4b9b85c7b62 1615 uint8_t t = *d;
Pokitto 31:f4b9b85c7b62 1616 uint8_t t1 = *(d+1);
Pokitto 31:f4b9b85c7b62 1617 scanline[0][s] = paletteptr[(t+offset)&255];
Pokitto 31:f4b9b85c7b62 1618 scanline[1][s++] = paletteptr[(t1+offset)&255];
Pokitto 31:f4b9b85c7b62 1619 d+=110; // jump to read byte directly below in screenbuffer
Pokitto 31:f4b9b85c7b62 1620 }
Pokitto 31:f4b9b85c7b62 1621 s=0;
Pokitto 31:f4b9b85c7b62 1622 for (s=0;s<88;) {
Pokitto 31:f4b9b85c7b62 1623 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1624 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1625 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1626 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1627 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1628 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1629 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1630 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1631 }
Pokitto 31:f4b9b85c7b62 1632 for (s=0;s<88;) {
Pokitto 31:f4b9b85c7b62 1633 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1634 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1635 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1636 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1637 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1638 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1639 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1640 setup_data_16(scanline[0][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1641 }
Pokitto 31:f4b9b85c7b62 1642 for (s=0;s<88;) {
Pokitto 31:f4b9b85c7b62 1643 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1644 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1645 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1646 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1647 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1648 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1649 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1650 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1651 }
Pokitto 31:f4b9b85c7b62 1652 for (s=0;s<88;) {
Pokitto 31:f4b9b85c7b62 1653 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1654 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1655 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1656 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1657 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1658 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1659 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1660 setup_data_16(scanline[1][s++]);CLR_WR;SET_WR;CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1661 }
Pokitto 31:f4b9b85c7b62 1662 }
Pokitto 31:f4b9b85c7b62 1663
Pokitto 31:f4b9b85c7b62 1664 }
Pokitto 31:f4b9b85c7b62 1665
Pokitto 31:f4b9b85c7b62 1666
Pokitto 31:f4b9b85c7b62 1667
Pokitto 31:f4b9b85c7b62 1668
Pokitto 31:f4b9b85c7b62 1669 void Pokitto::blitWord(uint16_t c) {
Pokitto 31:f4b9b85c7b62 1670 setup_data_16(c);CLR_WR;SET_WR;
Pokitto 31:f4b9b85c7b62 1671 }
Pokitto 31:f4b9b85c7b62 1672
Pokitto 31:f4b9b85c7b62 1673