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

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Revision:
64:1d52d8287c39
Parent:
60:8b6a110feeea
--- a/POKITTO_CORE/PokittoDisplay.cpp	Sun Oct 07 10:19:52 2018 +0000
+++ b/POKITTO_CORE/PokittoDisplay.cpp	Sat Mar 23 19:19:23 2019 +0000
@@ -71,6 +71,7 @@
 #include "PokittoSound.h"
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 #ifdef DISABLEAVRMIN
 #include <algorithm>
 using std::min;
@@ -92,8 +93,6 @@
 
 using namespace Pokitto;
 
-
-
 uint8_t* Display::m_scrbuf;
 uint8_t* Display::m_tileset;
 uint8_t* Display::m_tilebuf;
@@ -124,7 +123,7 @@
 const unsigned char* Display::font;
 int8_t Display::adjustCharStep = 1;
 int8_t Display::adjustLineStep = 1;
-bool Display::fixedWidthFont = false;
+bool Display::fixedWidthFont = false, Display::flipFontVertical = false;
 
 /** drawing canvas **/
 //uint8_t* Display::canvas; // points to the active buffer. if null, draw direct to screen
@@ -139,7 +138,7 @@
 #elif (POK_SCREENMODE == MODE_HI_4COLOR)
     uint8_t Display::width = POK_LCD_W;
     uint8_t Display::height = POK_LCD_H;
-    uint8_t __attribute__((section (".bss"))) Display::screenbuffer[((POK_LCD_H)*POK_LCD_W)/4]; // maximum resolution
+    uint8_t __attribute__((section (".bss"))) __attribute__ ((aligned)) Display::screenbuffer[((POK_LCD_H)*POK_LCD_W)/4]; // maximum resolution
 #elif (POK_SCREENMODE == MODE_FAST_16COLOR)
     uint8_t Display::width = POK_LCD_W/2;
     uint8_t Display::height = POK_LCD_H/2;
@@ -164,10 +163,19 @@
     uint8_t Display::width = 110;
     uint8_t Display::height = 88;
     uint8_t Display::screenbuffer[110*88]; // 8bit 110x88
+#elif (POK_SCREENMODE == MIXMODE)
+    uint8_t Display::width = 110;
+    uint8_t Display::height = 88;
+    uint8_t Display::screenbuffer[110*88]; // 8bit 110x88 or 4bit 110x176
+    uint8_t Display::scanType[88]; // scanline bit depth indicator
+#elif (POK_SCREENMODE == MODE64)
+    uint8_t Display::width = 110;
+    uint8_t Display::height = 176;
+    uint8_t __attribute__ ((aligned)) Display::screenbuffer[110*176]; // 8bit 110x176
 #elif (POK_SCREENMODE == MODE15)
     uint8_t Display::width = 220;
     uint8_t Display::height = 176;
-    uint8_t Display::screenbuffer[0x4BA0];
+    uint8_t __attribute__ ((aligned)) Display::screenbuffer[0x4BA0];
 #else
     uint8_t Display::width = 84;
     uint8_t Display::height = 48;
@@ -206,7 +214,7 @@
     #endif // POK_GAMEBUINO_SUPPORT
 
     // Reset sprites
-    m_tilecolorbuf = NULL; //!!HV
+    m_tilecolorbuf = NULL;
     for (uint8_t s = 0; s < SPRITE_COUNT; s++) m_sprites[s].bitmapData = NULL;
 }
 
@@ -289,6 +297,14 @@
 		lcdRefreshMode13(m_scrbuf, paletteptr, palOffset);
 		#endif
 
+		#if POK_SCREENMODE == MIXMODE
+		lcdRefreshMixMode(m_scrbuf, paletteptr, scanType);
+		#endif
+
+		#if POK_SCREENMODE == MODE64
+		lcdRefreshMode64(m_scrbuf, paletteptr);
+		#endif
+
         #if POK_SCREENMODE == MODE_GAMEBOY
         lcdRefreshModeGBC(m_scrbuf, paletteptr);
         #endif
@@ -352,7 +368,9 @@
         directcolor = COLOR_WHITE;
         invisiblecolor = COLOR_BLACK;
         directbgcolor = 0x0001; // Cannot be black as that is transparent color
-        if (POK_SCREENMODE == MODE_FAST_16COLOR )
+        if (POK_SCREENMODE == MODE_FAST_16COLOR ||
+            POK_SCREENMODE == MODE13
+        )
             directtextrotated = false;
         else
             directtextrotated = true;
@@ -484,39 +502,92 @@
     // GLCD fonts are arranged LSB = topmost pixel of char, so its easy to just shift through the column
     uint16_t bitcolumn; //16 bits for 2x8 bit high characters
 
+    if( fontSize != 2 ) fontSize = 1;
+
+    void (*drawPixelFG)(int16_t,int16_t, uint8_t) = &Display::drawPixelNOP;
+    void (*drawPixelBG)(int16_t,int16_t, uint8_t) = &Display::drawPixelNOP;
+    if( x>=0 && y >= 0 && x+w*fontSize<width && y+(h+1)*fontSize<height ){
+	if( color != invisiblecolor )
+	    drawPixelFG = &Display::drawPixelRaw;
+	if( bgcolor != invisiblecolor )
+	    drawPixelBG = &Display::drawPixelRaw;
+    }else{
+	if( color != invisiblecolor )
+	    drawPixelFG = &Display::drawPixel;
+	if( bgcolor != invisiblecolor )
+	    drawPixelBG = &Display::drawPixel;
+    }
+
+    void (*drawPixel[])(int16_t,int16_t, uint8_t) = {drawPixelBG, drawPixelFG};
+    uint8_t colors[] = {bgcolor, color};
+
+#if PROJ_ARDUBOY > 0
+#else
+    if( fontSize != 2 ){
+#endif
+
+    for (i = 0; i < numBytes; i++) {
+	bitcolumn = *bitmap++;
+	if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts
+	for (j = 0; j <= h; j++) { // was j<=h
+	    uint8_t c = colors[ bitcolumn & 1 ];
+
+#if PROJ_ARDUBOY > 0
+	    drawPixel[ bitcolumn&1 ](x, y + 7 - j,c);
+#elif PROJ_SUPPORT_FONTROTATION > 0
+       // if font flipping & rotation is allowed - do not slow down old programs!
+       if (flipFontVertical) {
+           drawPixel[ bitcolumn&1 ](x, y + h - j,c);
+       } else {
+           drawPixel[ bitcolumn&1 ](x, y + j,c);
+       }
+#else
+	   // "Normal" case
+	    drawPixel[ bitcolumn&1 ](x, y + j,c);
+#endif // PROJ_ARDUBOY
+	    bitcolumn>>=1;
+
+	}
+#if PROJ_SUPPORT_FONTROTATION > 0
+	if (flipFontVertical) x--;
+	else x++;
+#else
+    x++;
+#endif
+    }
+
+#if PROJ_SUPPORT_FONTROTATION > 0
+    if (flipFontVertical) return -numBytes-adjustCharStep;
+    else return numBytes+adjustCharStep; // for character stepping
+#else
+    return numBytes+adjustCharStep;
+#endif
+
+
+#if PROJ_ARDUBOY > 0
+#else
+    }else{
+
 	for (i = 0; i < numBytes; i++) {
-            bitcolumn = *bitmap++;
-            if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts
-            for (j = 0; j <= h; j++) { // was j<=h
-                #if PROJ_ARDUBOY > 0
-                if (bitcolumn&0x1) {
-                    drawPixel(x + i, y + 7 - j,color);
-                } else drawPixel(x + i, y + 7 - j,bgcolor);
-                bitcolumn>>=1;
-                #else
-                if (fontSize==2) {
-                  if (bitcolumn&0x1) {
-                            drawPixel(x + (i<<1)  , y + (j<<1),color);
-                            drawPixel(x + (i<<1)+1, y + (j<<1),color);
-                            drawPixel(x + (i<<1)  , y + (j<<1)+1,color);
-                            drawPixel(x + (i<<1)+1, y + (j<<1)+1,color);
-                        } else {
-                            drawPixel(x + (i<<1)  , y + (j<<1),bgcolor);
-                            drawPixel(x + (i<<1)+1, y + (j<<1),bgcolor);
-                            drawPixel(x + (i<<1)  , y + (j<<1)+1,bgcolor);
-                            drawPixel(x + (i<<1)+1, y + (j<<1)+1,bgcolor);
-                        }
-                } else {
-                    if (bitcolumn&0x1) drawPixel(x + i, y + j,color);
-                    else drawPixel(x + i, y + j,bgcolor);
-                }
-                bitcolumn>>=1;
-                #endif // PROJ_ARDUBOY
+	    bitcolumn = *bitmap++;
+	    if (hbytes == 2) bitcolumn |= (*bitmap++)<<8; // add second byte for 16 bit high fonts
+	    for (j = 0; j <= h; j++) { // was j<=h
+		uint8_t c = colors[ bitcolumn & 1 ];
 
-            }
+		drawPixel[ bitcolumn&1 ](x + (i<<1)  , y + (j<<1), c);
+		drawPixel[ bitcolumn&1 ](x + (i<<1)+1, y + (j<<1), c);
+		drawPixel[ bitcolumn&1 ](x + (i<<1)  , y + (j<<1)+1, c);
+		drawPixel[ bitcolumn&1 ](x + (i<<1)+1, y + (j<<1)+1, c);
+		bitcolumn>>=1;
+
+	    }
+	}
+
+	return (numBytes+adjustCharStep)<<1;
+
     }
-    if (fontSize==2) return (numBytes+adjustCharStep)<<1;
-    return numBytes+adjustCharStep; // for character stepping
+#endif // PROJ_ARDUBOY
+
 }
 
 void Display::clear() {
@@ -532,13 +603,13 @@
         uint16_t j = POK_BITFRAME;
         if (bgcolor & 0x1) memset((void*)m_scrbuf,0xFF,j);// R
         else memset((void*)m_scrbuf,0x00,j);// R
-        if ((bgcolor>>1) & 0x1) memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME),0xFF,j);// G
-        else memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME),0x00,j);// G
-        if ((bgcolor>>2) & 0x1) memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME*2),0xFF,j);// B
-        else memset((void*)((uint8_t*)m_scrbuf+POK_BITFRAME*2),0x00,j);// B
+        if ((bgcolor>>1) & 0x1) memset((char*)m_scrbuf+POK_BITFRAME,0xFF,j);// G
+        else memset((char*)m_scrbuf+POK_BITFRAME,0x00,j);// G
+        if ((bgcolor>>2) & 0x1) memset((char*)m_scrbuf+POK_BITFRAME*2,0xFF,j);// B
+        else memset((char*)m_scrbuf+POK_BITFRAME*2,0x00,j);// B
         setCursor(0,0);
         return;
-    } else {
+    } else if (bpp==4) {
         c = (c & 0x0F) | (c << 4);
     }
     uint16_t j = sizeof(screenbuffer);
@@ -621,12 +692,10 @@
     clipX = x; clipY = y; clipW = w; clipH = h;
 }
 
+void Display::drawPixelNOP(int16_t x,int16_t y, uint8_t col) {
+}
 
-void Display::drawPixel(int16_t x,int16_t y, uint8_t col) {
-    if (col==invisiblecolor) return; // do not draw transparent pixels
-    if ((uint16_t)x >= width || (uint16_t)y >= height) return;
-    col &= (PALETTE_SIZE-1);
-
+void Display::drawPixelRaw(int16_t x,int16_t y, uint8_t col) {
     #if POK_COLORDEPTH == 8
         m_scrbuf[x+width*y] = col;
     #endif
@@ -689,75 +758,16 @@
     #endif // POK_GAMEBUINO_SUPPORT
 }
 
+void Display::drawPixel(int16_t x,int16_t y, uint8_t col) {
+    if (col==invisiblecolor) return; // do not draw transparent pixels
+    if ((uint16_t)x >= width || (uint16_t)y >= height) return;
+    col &= (PALETTE_SIZE-1);
+    drawPixelRaw( x, y, col );
+}
+
 void Display::drawPixel(int16_t x,int16_t y) {
     if ((uint16_t)x >= width || (uint16_t)y >= height) return;
-
-    #if POK_COLORDEPTH == 8
-        m_scrbuf[x+width*y] = color;
-    #endif
-
-    #if POK_GAMEBUINO_SUPPORT > 0
-
-	uint8_t c = color;
-	uint8_t ct = color;
-	if(ct == INVERT){
-	 ct = !getPixel(x, y); //jonne - was c = !getP...
-	}
-
-    uint16_t bitptr=0;
-    for (uint8_t cbit=0;cbit<POK_COLORDEPTH;cbit++) {
-	c = ct & 1; // take the lowest bit of the color index number
-	if(c == 0){ //white - or actually "Clear bit"
-    #if DISPLAY_ROT == NOROT
-		m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] &= ~_BV(y % 8);
-    #elif DISPLAY_ROT == ROTCCW
-		m_scrbuf[LCDHEIGHT - y - 1 + (x / 8) * LCDWIDTH_NOROT + bitptr] &= ~_BV(x % 8);
-    #elif DISPLAY_ROT == ROT180
-		m_scrbuf[LCDWIDTH - x - 1 + ((LCDHEIGHT - y - 1) / 8) * LCDWIDTH_NOROT + bitptr] &= ~_BV((LCDHEIGHT - y - 1) % 8);
-    #elif DISPLAY_ROT == ROTCW
-		m_scrbuf[y + ((LCDWIDTH - x - 1) / 8) * LCDWIDTH_NOROT + bitbtr] &= ~_BV((LCDWIDTH - x - 1) % 8);
-    #endif
-		//return; //jonne
-	} else { //black - or actually "Set bit"
-    #if DISPLAY_ROT == NOROT
-		m_scrbuf[x + (y / 8) * LCDWIDTH + bitptr] |= _BV(y % 8);
-    #elif DISPLAY_ROT == ROTCCW
-		m_scrbuf[LCDHEIGHT - y - 1 + (x / 8) * LCDWIDTH_NOROT + bitptr] |= _BV(x % 8);
-    #elif DISPLAY_ROT == ROT180
-		m_scrbuf[LCDWIDTH - x - 1 + ((LCDHEIGHT - y - 1) / 8) * LCDWIDTH_NOROT + bitptr] |= _BV((LCDHEIGHT - y - 1) % 8);
-    #elif DISPLAY_ROT == ROTCW
-		m_scrbuf[y + ((LCDWIDTH - x - 1) / 8) * LCDWIDTH_NOROT + bitptr] |= _BV((LCDWIDTH - x -1) % 8);
-    #endif
-		//return; //jonne
-	}
-	ct >>=1; // shift to get next bit
-	bitptr += POK_BITFRAME; // move one screen worth of buffer forward to get to the next color bit
-    } // POK_COLOURDEPTH
-
-    #else
-
-    /** NOT Gamebuino */
-    #if POK_COLORDEPTH == 1
-        if (color) {m_scrbuf[(y >> 3) * width + x] |= (0x80 >> (y & 7)); return;}
-        m_scrbuf[(y >> 3) * width + x] &= ~(0x80 >> (y & 7));
-    #elif POK_COLORDEPTH == 2
-        uint16_t i = y*(width>>2) + (x>>2);
-        uint8_t pixel = m_scrbuf[i];
-        uint8_t column = x&0x03;
-        if (column==3) pixel = (pixel&0xFC)|(color); // bits 0-1
-        else if (column==2) pixel = (pixel&0xF3)|(color<<2); // bits 2-3
-        else if (column==1) pixel = (pixel&0xCF)|(color<<4); // bits 4-5
-        else pixel = (pixel&0x3F)|(color<<6); // bits 6-7
-        m_scrbuf[i] = pixel;
-    #elif POK_COLORDEPTH == 3
-    #elif POK_COLORDEPTH == 4
-            uint16_t i = y*(width>>1) + (x>>1);
-            uint8_t pixel = m_scrbuf[i];
-            if (x&1) pixel = (pixel&0xF0)|(color);
-            else pixel = (pixel&0x0F) | (color<<4);
-            m_scrbuf[i] = pixel;
-    #endif // POK_COLORDEPTH
-    #endif // POK_GAMEBUINO_SUPPORT
+    drawPixelRaw( x, y, color );
 }
 
 uint8_t Display::getPixel(int16_t x,int16_t y) {
@@ -1496,6 +1506,7 @@
         int16_t bitFrame = w * h / 8;
         for (i = 0; i < w; i++) {
         byteNum = i / 8;
+        //bitNum = i % 8;
 
         uint8_t bitcount=0;
         for (j = 0; j <= h/8; j++) {
@@ -1518,7 +1529,8 @@
     else if (m_colordepth==4) {
 
     /** 4bpp fast version */
-	int16_t scrx,scry,xclip,xjump,scrxjump;
+	int16_t scrx,scry,xjump,scrxjump;
+	int16_t xclip;
     xclip=xjump=scrxjump=0;
     /** y clipping */
     if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;}
@@ -1555,8 +1567,9 @@
                         uint8_t sourcepixel = *bitmap;
                         if ((sourcepixel&0x0F) != invisiblecolor) {
                             sourcepixel <<=4;
-                            uint8_t targetpixel = *scrptr;// & 0x0F;
-                            targetpixel |= sourcepixel;
+                            volatile uint8_t targetpixel = *scrptr;// & 0x0F;
+                            targetpixel &= 0xF; //clear upper nibble
+                            targetpixel |= sourcepixel; //now OR it
                             *scrptr = targetpixel;
                         }
                         //scrptr++;
@@ -1566,9 +1579,11 @@
                 }
                 bitmap += xjump; // needed if x<0 clipping occurs
             } else { /** ODD pixel starting line **/
+                uint8_t sourcepixel;
+                uint8_t targetpixel;
                 for (scrx = x; scrx < w+x-xclip; scrx+=2) {
-                    uint8_t sourcepixel = *bitmap;
-                    uint8_t targetpixel = *scrptr;
+                    sourcepixel = *bitmap;
+                    targetpixel = *scrptr;
                     // store higher nibble of source pixel in lower nibble of target
                     if((sourcepixel>>4)!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | (sourcepixel >> 4 );
                     *scrptr = targetpixel;
@@ -1579,6 +1594,12 @@
                     *scrptr = targetpixel;
                     bitmap++;
                 }
+                if (xclip) {
+                    // last line, store higher nibble of last source pixel in lower nibble of last address
+                    sourcepixel = *bitmap >> 4;
+                    if(sourcepixel!=invisiblecolor) targetpixel = (targetpixel & 0xF0) | sourcepixel;
+                    *scrptr = targetpixel;
+                }
                 bitmap+=xjump;
             }
             // increment the y jump in the scrptr
@@ -1591,16 +1612,15 @@
     /** 4bpp fast version */
 
     if (m_colordepth==8) {
-	int16_t scrx,scry,xjump,scrxjump;
-    xjump=scrxjump=0;
+    int16_t scrx,scry;//,scrxjump;
+    int16_t xjump=0;
     /** y clipping */
     if (y<0) { h+=y; bitmap -= y*w; y=0;}
     else if (y+h>height) { h -=(y-height);}
     /** x clipping */
     if (x<0) { w+=x; xjump = (-x); bitmap += xjump; x=0;}
     else if (x+w>width) {
-            scrxjump = x;
-            xjump=(x+w-width)+scrxjump;
+            xjump=(x+w-width);
             w = width-x;}
 
     uint8_t* scrptr = m_scrbuf + (y*width + x);
@@ -1614,8 +1634,8 @@
                     bitmap++;
                     scrptr++;
                 }
-            bitmap += xjump; // needed if x<0 clipping occurs
-        scrptr = scrptr + (width - w)+scrxjump;
+            bitmap += xjump; // needed if horizontal clipping occurs
+            scrptr = scrptr + (width - w);
     }
     return;
     }
@@ -1779,83 +1799,105 @@
     } // end for scry
 }
 
-void Display::drawBitmapXFlipped(int16_t x, int16_t y, const uint8_t* bitmap)
+void Display::drawBitmapDataXFlipped(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t* bitmap)
 {
-    int16_t w = *bitmap;
-	int16_t h = *(bitmap + 1);
-    bitmap = bitmap + 2; //add an offset to the pointer to start after the width and height
     /** visibility check */
     if (y<-h || y>height) return; //invisible
     if (x<-w || x>width) return;  //invisible
     /** 1 bpp mode */
-    if (m_colordepth<2) {
-    int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
-    for (i = 0; i < w; i++) {
-        byteNum = i / 8;
-        bitNum = i % 8;
-        for (j = 0; j < h; j++) {
-            uint8_t source = *(bitmap + j * byteWidth + byteNum);
-            if (source & (0x80 >> bitNum)) {
-                drawPixel(x + w - i, y + j);
+    if (m_colordepth<2)
+    {
+        int16_t i, j, byteNum, bitNum, byteWidth = (w + 7) >> 3;
+        for (i = 0; i < w; i++)
+        {
+            byteNum = i / 8;
+            bitNum = i % 8;
+            for (j = 0; j < h; j++)
+            {
+                uint8_t source = *(bitmap + j * byteWidth + byteNum);
+                if (source & (0x80 >> bitNum))
+                {
+                    drawPixel(x + w - i, y + j);
+                }
             }
         }
-    }
 
-    return;
+        return;
     }
     /** 2 bpp mode */
-    if (m_colordepth<4) {
-    int16_t i, j, byteNum, bitNum, byteWidth = w >> 2;
-    for (i = 0; i < w; i++) {
-        byteNum = i / 4;
-        bitNum = (i % 4)<<1;
-        for (j = 0; j < h; j++) {
-            uint8_t source = *(bitmap + j * byteWidth + byteNum);
-            uint8_t output = (source & (0xC0 >> bitNum));
-            output >>= (6-bitNum);
-            if (output != invisiblecolor) {
-                setColor(output);
-                drawPixel(x + i, y + j);
+    else if (m_colordepth==2)
+    {
+        int16_t i, j, byteNum, bitNum, byteWidth = w >> 2;
+        for (i = 0; i < w; i++)
+        {
+            byteNum = i / 4;
+            bitNum = (i % 4)<<1;
+            for (j = 0; j < h; j++)
+            {
+                uint8_t source = *(bitmap + j * byteWidth + byteNum);
+                uint8_t output = (source & (0xC0 >> bitNum));
+                output >>= (6-bitNum);
+                if (output != invisiblecolor)
+                {
+                    setColor(output);
+                    drawPixel(x + i, y + j);
+                }
             }
         }
-    }
 
-    return;
+        return;
     }
-    /** 4bpp fast version */
-	int16_t scrx,scry,xclip,xjump,scrxjump;
-    xclip=xjump=scrxjump=0;
-    /** y clipping */
-    if (y<0) { h+=y; bitmap -= y*(w>>1); y=0;}
-    else if (y+h>height) { h -=(y-height);}
-    /** x clipping */
-    bitmap += ((w>>1)-1); //inverted!
-    if (x<0) {
+    else if (m_colordepth==4)
+    {
+        /** 4bpp fast version */
+        int16_t scrx,scry,xclip,xjump,scrxjump;
+        xclip=xjump=scrxjump=0;
+        /** y clipping */
+        if (y<0)
+        {
+            h+=y;
+            bitmap -= y*(w>>1);
+            y=0;
+        }
+        else if (y+h>height)
+        {
+            h -=(y-height);
+        }
+        /** x clipping */
+        bitmap += ((w>>1)-1); //inverted!
+        if (x<0)
+        {
             xclip=(x&1)<<1;
             w+=x;
             xjump = ((-x)>>1);
             //bitmap += xjump; // do not clip left edge of source, as bitmap is inverted !
             x=0;
-            }
-    else if (x+w>width) {
+        }
+        else if (x+w>width)
+        {
             xclip = (x&1)<<1;
             scrxjump = x&1;
             xjump=((x+w-width)>>1)+scrxjump;
-            w = width-x;}
+            w = width-x;
+        }
 
-    //uint8_t* scrptr = m_scrbuf + (y*(width>>1) + ((x+width)>>1));
-    uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
-    /** ONLY 4-bit mode for time being **/
-    for (scry = y; scry < y+h; scry+=1) {
-    //    for (scry = y; scry < y+2; scry+=1) {
+        //uint8_t* scrptr = m_scrbuf + (y*(width>>1) + ((x+width)>>1));
+        uint8_t* scrptr = m_scrbuf + (y*(width>>1) + (x>>1));
+        /** ONLY 4-bit mode for time being **/
+        for (scry = y; scry < y+h; scry+=1)
+        {
+            //    for (scry = y; scry < y+2; scry+=1) {
             if (scry>=height) return;
-            if ((x&1)==0) { /** EVEN pixel starting line, very simple, just copypaste **/
+            if ((x&1)==0)   /** EVEN pixel starting line, very simple, just copypaste **/
+            {
                 //for (scrx = w+x-xclip-1; scrx >= x; scrx-=2) {
-                for (scrx = x; scrx < w+x-xclip; scrx+=2) {
+                for (scrx = x; scrx < w+x-xclip; scrx+=2)
+                {
                     uint8_t sourcepixel = *(bitmap);
-                    if (xclip) {
-                            sourcepixel <<=4;
-                            sourcepixel |= ((*(bitmap-1))>>4);//inverted!
+                    if (xclip)
+                    {
+                        sourcepixel <<=4;
+                        sourcepixel |= ((*(bitmap-1))>>4);//inverted!
                     }
                     uint8_t targetpixel = *scrptr;
                     // NIBBLES ARE INVERTED BECAUSE PICTURE IS FLIPPED !!!
@@ -1866,11 +1908,14 @@
                     scrptr++;
                 }
                 bitmap += w; // w*2 >> 1 because inverted and because 2 pixels per byte!!
-                if (xclip){
-                    if (w&1) {
+                if (xclip)
+                {
+                    if (w&1)
+                    {
                         /**last pixel is odd pixel due to clipping & odd width*/
                         uint8_t sourcepixel = *bitmap;
-                        if ((sourcepixel&0x0F) != invisiblecolor) {
+                        if ((sourcepixel&0x0F) != invisiblecolor)
+                        {
                             sourcepixel <<=4;
                             uint8_t targetpixel = *scrptr;// & 0x0F;
                             targetpixel |= sourcepixel;
@@ -1882,8 +1927,11 @@
                     scrptr++;
                 }
                 bitmap += xjump; // needed if x<0 clipping occurs
-            } else { /** ODD pixel starting line **/
-                for (scrx = x; scrx < w+x-xclip; scrx+=2 ) {
+            }
+            else     /** ODD pixel starting line **/
+            {
+                for (scrx = x; scrx < w+x-xclip; scrx+=2 )
+                {
                     uint8_t sourcepixel = *bitmap;
                     uint8_t targetpixel = *scrptr;
                     // inverted !!! store lower nibble of source pixel in lower nibble of target
@@ -1901,7 +1949,62 @@
             }
             // increment the y jump in the scrptr
             scrptr = scrptr + ((width - w)>>1)+scrxjump;
+        }
     }
+    /** 8 bpp mode */
+    else if (m_colordepth==8)
+    {
+        int16_t scrx,scry;//,scrxjump;
+        int16_t xjump=0;
+        /** y clipping */
+        if (y<0)
+        {
+            h+=y;
+            bitmap -= y*w;
+            y=0;
+        }
+        else if (y+h>height)
+        {
+            h -=(y-height);
+        }
+        /** x clipping */
+        if (x<0)
+        {
+            w+=x;
+            xjump = (-x);
+            bitmap += xjump;
+            x=0;
+        }
+        else if (x+w>width)
+        {
+            xjump=(x+w-width);
+            w = width-x;
+        }
+
+        uint8_t* scrptr = m_scrbuf + (y*width + x) + w;
+        for (scry = y; scry < y+h; scry+=1)
+        {
+            if (scry>=height) return;
+            for (scrx = x; scrx < w+x; scrx++)
+            {
+                uint8_t sourcepixel = *bitmap;
+                uint8_t targetpixel = *scrptr;
+                if (sourcepixel != invisiblecolor )
+                    targetpixel = sourcepixel;
+                *scrptr = targetpixel;
+                bitmap++;
+                scrptr--;
+            }
+            bitmap += xjump; // needed if horizontal clipping occurs
+            scrptr = scrptr + (width + w);
+        }
+        return;
+    }
+}
+
+void Display::drawBitmapXFlipped(int16_t x, int16_t y, const uint8_t* bitmap)
+{
+    drawBitmapDataXFlipped(x, y, bitmap[0], bitmap[1], bitmap + 2);
 }
 
 void Display::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t rotation, uint8_t flip) {
@@ -2338,6 +2441,7 @@
   }
 }
 
+
 void Display::draw4BitColumn(int16_t x, int16_t y, uint8_t h, uint8_t* bitmap)
 {
     int8_t scry;
@@ -2441,6 +2545,14 @@
     lcdRefreshMode13(m_scrbuf, paletteptr, palOffset);
 #endif
 
+#if POK_SCREENMODE == MIXMODE
+    lcdRefreshMixMode(m_scrbuf, paletteptr, scanType);
+#endif
+
+#if POK_SCREENMODE == MODE64
+    lcdRefreshMode64(m_scrbuf, paletteptr);
+#endif
+
 #if POK_SCREENMODE == MODE_GAMEBOY
     lcdRefreshModeGBC(scr, paletteptr);
 #endif
@@ -2476,6 +2588,8 @@
     m_tilebuf[i]=t;
 };
 
+
+
 // Convert an integer to a hexadecimal string
 char* itoa_hex(int num, char* dest, int destLen) {
     int i = destLen-1;
@@ -2489,6 +2603,7 @@
 }
 
 // Draw the crash screen and wait forever
+#define STR_TO_UPPER(str_from, str_to) for( int32_t i=0; i <= strlen(str_from); i++ ) str_to[i] = toupper(str_from[i]);
 void ShowCrashScreenAndWait( const char* texLine1, const char* texLine2, const char* texLine3, const char* texLine4, const char* texLine5 ) {
 
     // draw screen red
@@ -2505,15 +2620,17 @@
     Display::fixedWidthFont = true; // Needed for the non-proportional C64 font (default value=false)
     Display::enableDirectPrinting(true);
 
+    char convertedStr[128] = {0};
+
     // Draw texts
     int  yOffsetInPixels = 5;
     Display::set_cursor(0, 9 + yOffsetInPixels);
-    Display::print("  ");    Display::println(texLine1);
-    Display::print("  ");    Display::println(texLine2);
-    Display::print("  ");    Display::println(texLine3);
+    Display::print("  ");    STR_TO_UPPER(texLine1, convertedStr); Display::println(convertedStr);
+    Display::print("  ");    STR_TO_UPPER(texLine2, convertedStr); Display::println(convertedStr);
+    Display::print("  ");    STR_TO_UPPER(texLine3, convertedStr); Display::println(convertedStr);
     Display::println();
-    Display::print("  *");   Display::println(texLine4);
-    Display::print("  *");   Display::println(texLine5);
+    Display::print("  *");   STR_TO_UPPER(texLine4, convertedStr); Display::println(convertedStr);
+    Display::print("  *");   STR_TO_UPPER(texLine5, convertedStr); Display::println(convertedStr);
 
     Display::set_cursor(0, 0 + yOffsetInPixels);