Jonne Valola / PokittoLib Featured

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!

Files at this revision

API Documentation at this revision

Comitter:
Pokitto
Date:
Sat Mar 23 20:03:34 2019 +0000
Parent:
65:deed4aa606fb
Child:
67:068fa6345036
Child:
69:f9f49ff29720
Commit message:
Updated pokittolib to current embitz dev branch

Changed in this revision

POKITTO_CORE/GBcompatibility.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/Localization.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoButtons.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoConsole.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoCookie.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoCookie.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoCore.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoCore.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoDisk.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoDisk.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoGlobs.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoItoa.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoPalette.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoSound.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_CORE/PokittoSound.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/Synth/Synth.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/Synth/Synth.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/Synth/Synth_helpers.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/Synth/Synth_mixfuncs.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/Synth/Synth_osc.h Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/Synth/Synth_oscfuncs.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/Synth/Synth_songfuncs.cpp Show annotated file Show diff for this revision Revisions of this file
POKITTO_LIBS/Synth/Synth_wavefuncs.cpp Show annotated file Show diff for this revision Revisions of this file
Pokitto_settings.h Show annotated file Show diff for this revision Revisions of this file
--- a/POKITTO_CORE/GBcompatibility.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/GBcompatibility.h	Sat Mar 23 20:03:34 2019 +0000
@@ -55,7 +55,7 @@
 
 //SETTINGS YOU CAN EDIT
 
-#define NUM_CHANNELS 1 //number of sound channels, between 0 and 4
+#define NUM_CHANNELS 3 //number of sound channels, between 0 and 4
 #define DISPLAY_ROT NOROT //set to NOROT, ROTCCW, ROT180 or ROTCW. Can be used to play in portrait mode.
 #define ENABLE_GUI 1 //enable menu, keyboard, pop-up, volume adjust functions
 #define ENABLE_BITMAPS 1 //will replace bitmaps with rectangles if disabled
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/POKITTO_CORE/Localization.h	Sat Mar 23 20:03:34 2019 +0000
@@ -0,0 +1,48 @@
+/**************************************************************************/
+/*!
+    @file     Localization.h
+    @author   Hannu Viitala
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2017, Jonne Valola
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#ifndef LOCALIZATION_H
+#define LOCALIZATION_H
+
+//** Localized strings of the Pokitto SW  */
+
+// Texts
+#define STR_OK "OK"
+#define STR_CANCEL "CANCEL"
+
+#endif
+
+
--- a/POKITTO_CORE/PokittoButtons.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoButtons.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -126,8 +126,10 @@
  * return true if 'button' is released
  */
 bool Buttons::released(uint8_t button) {
-    if (states[button] == 0xFF)
+    if (states[button] == 0xFF) {
+        states[button] = 0; // prevent continuous released state!
         return true;
+    }
     else
         return false;
 }
--- a/POKITTO_CORE/PokittoConsole.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoConsole.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -180,6 +180,7 @@
         _display->print("Hit:");break;
     default:
         return;
+        break;
     }
 
     switch (c.msgtype) {
--- a/POKITTO_CORE/PokittoCookie.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoCookie.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -117,13 +117,15 @@
 }
 
 bool Cookie::saveCookie() {
-    if (!_status || !_pointer) initialize(); //reinitialize if needed
-    if (!_status || !_pointer) return false; //return if initialize still failed
+    if (!_status || !_pointer) return false; //return if not initialized
     char* p = _pointer;
     _head=0;
     _block=0;
     _block=findMyNextBlock();
     for (int i=0; i<_datasize; i++) writeQueue(*p++);
+    #if POK_ENABLE_SOUND
+    Pokitto::soundInit(true); //re-init sound
+    #endif
     return true;
 }
 
@@ -151,7 +153,7 @@
 
 int Cookie::exists(const char* idkey) {
     for (int i=0; i< SBMAXKEYS; i++) {
-        #ifndef POK_SIM
+
             if(eeprom_read_byte((uint16_t*)(i*SBKEYSIZE))==idkey[0]) {
                     int total=0;
                     for (int j=0; j<SBKEYSIZE;j++) {
@@ -159,7 +161,7 @@
                     }
                     if (total==SBKEYSIZE) return i; // return the keyslot number where key exists
             }
-        #endif
+
     }
     return SBINVALIDSLOT; //not found
 }
@@ -167,9 +169,9 @@
 int Cookie::getFreeKeytableSlot() {
     int freeslot=SBINVALIDSLOT;
     for (int i=0; i<SBMAXKEYS; i++) {
-    #ifndef POK_SIM
+
     if (eeprom_read_byte((uint16_t*)(i*SBKEYSIZE))==0) {freeslot=i; break;}
-    #endif
+
     }
     return freeslot;
 }
@@ -192,21 +194,21 @@
 
 bool Cookie::isFreeBlock(int n) {
     if (n>=SBMAXBLOCKS) return false;
-    #ifndef POK_SIM
+
     if (!(eeprom_read_byte((uint16_t*)(SBMAXKEYS*SBKEYSIZE+n))&0x80)) return true; //highest bit 0, its free
-    #endif
+
     return false; //its not free
 }
 
 bool Cookie::isMyBlock(int n) {
     if (n>=SBMAXBLOCKS) return false;
     if (isFreeBlock(n)) return false; //"free" blocks can not be "reserved" at the same time!
-    #ifndef POK_SIM
+
     char temp; int address;
     address = (SBMAXKEYS*SBKEYSIZE+n);
     temp = eeprom_read_byte((uint16_t*)address);
     if ((temp&0x7F) ==_keyorder) return true;
-    #endif
+
     return false; //its not your block
 }
 
@@ -214,21 +216,21 @@
     if (n>=SBMAXBLOCKS) return false;
     if (k>=SBMAXKEYS) return false;
     if (isFreeBlock(n)) return false; //"free" blocks can not be "owned" by anyone
-    #ifndef POK_SIM
+
     char temp; int address;
     address = (SBMAXKEYS*SBKEYSIZE+n);
     temp = eeprom_read_byte((uint16_t*)address);
     if ((temp&0x7F) == k) return true;
-    #endif
+
     return false; //its not your block
 }
 
 void Cookie::writeKeyToKeytable(const char* key, int slot) {
     for (int i=0; i<SBKEYSIZE; i++) {
-    #ifndef POK_SIM
+
     if (key[i]) eeprom_write_byte((uint16_t*)(slot*SBKEYSIZE+i),key[i]);
     else eeprom_write_byte((uint16_t*)(slot*SBKEYSIZE+i),0);
-    #endif
+
     }
 }
 
@@ -236,63 +238,63 @@
     answer[8]=0;
     if (n >= SBMAXKEYS) n=SBMAXKEYS-1;
     for (int i=0; i<SBKEYSIZE; i++) {
-        #ifndef POK_SIM
+
         answer[i] = eeprom_read_byte((uint16_t*)(n*SBKEYSIZE+i));
-        #endif
+
     }
 }
 
 char Cookie::getBlockTableEntry(int n) {
     if (n>=SBMAXBLOCKS) return 0x80; // out of bounds will return a reserved block marker
-    #ifndef POK_SIM
+
         return eeprom_read_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+n));
-    #endif
-    //return 0x80;
+
+    return 0x80;
 }
 
 void Cookie::readBlock(int n, char* data) {
     for (int i=0; i<SBBLOCKSIZE; i++) {
     data[i]=0;
-    #ifndef POK_SIM
+
         if (n < SBMAXBLOCKS) data[i] = eeprom_read_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+SBMAXBLOCKS+n*SBBLOCKSIZE+i));
-    #endif
+
     }
 }
 
 void Cookie::formatKeytable() {
     for (int j=0; j<SBMAXKEYS; j++) {
     for (int i=0; i<SBKEYSIZE; i++) {
-        #ifndef POK_SIM
+
         eeprom_write_byte((uint16_t*)(j*SBKEYSIZE+i),0);
-        #endif
+
     }
     }
 }
 
 void Cookie::freeBlock(int n) {
     if (n >= SBMAXBLOCKS) return; //out of bounds
-    #ifndef POK_SIM
+
         // delete entry from blocktable
         eeprom_write_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+n),0);
-    #endif
+
     for (int i=0; i<SBBLOCKSIZE;i++) {
-    #ifndef POK_SIM
+
         // wipe data in the block
         eeprom_write_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+SBMAXBLOCKS+n*SBBLOCKSIZE+i),0);
-    #endif
+
     }
 }
 
 bool Cookie::reserveBlock() {
     for (int i=0; i<SBMAXBLOCKS;i++) {
-    #ifndef POK_SIM
+
         // reserve block from blocktable
         if (isFreeBlock(i)) {
                 //free block found, mark it for us in the blocktable
                 eeprom_write_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+i),_keyorder | 0x80);
                 return true;
         }
-    #endif
+
     }
     return false; // no free block found
 }
@@ -300,9 +302,9 @@
 void Cookie::eraseKeytableEntry(int n) {
     if (n >= SBMAXKEYS) n=SBMAXKEYS-1;
     for (int i=0; i<SBKEYSIZE; i++) {
-        #ifndef POK_SIM
+
         eeprom_write_byte((uint16_t*)(n*SBKEYSIZE+i),0);
-        #endif
+
     }
 }
 
@@ -331,11 +333,11 @@
 
 char Cookie::readQueue() {
     char data=0;
-    #ifndef POK_SIM
+
     int address;
     address = SBMAXKEYS*SBKEYSIZE+SBMAXBLOCKS+SBBLOCKSIZE*_block+_head%SBBLOCKSIZE;
     data=eeprom_read_byte((uint16_t*)address);
-    #endif
+
     _head++;
     if (_head%SBBLOCKSIZE==0 && _head) {
             _block++;
@@ -345,9 +347,9 @@
 }
 
 void Cookie::writeQueue(char data) {
-    #ifndef POK_SIM
+
     eeprom_write_byte((uint16_t*)(SBMAXKEYS*SBKEYSIZE+SBMAXBLOCKS+SBBLOCKSIZE*_block+_head%SBBLOCKSIZE),data);
-    #endif
+
     _head++;
     if (_head%SBBLOCKSIZE==0 && _head) {
             _block++;
--- a/POKITTO_CORE/PokittoCookie.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoCookie.h	Sat Mar 23 20:03:34 2019 +0000
@@ -307,7 +307,7 @@
     /** Keyorder
     * order number of key in key table
     */
-     char _keyorder;
+     unsigned char _keyorder;
 
     /** Status
     * false = uninitialized
--- a/POKITTO_CORE/PokittoCore.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoCore.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -179,8 +179,8 @@
     uint32_t counter=0;
     uint8_t data[256];
     /** prepare the flash writing **/
-    //float progress=0;
-    //int opg=-1;
+    float progress=0;
+    int opg=-1;
     uint32_t fsize=0;
     fileEnd(); //
     fsize = fileGetPosition();
@@ -194,7 +194,7 @@
         if (counter >= fsize) {
                 break;
         }
-        //opg=progress;
+        opg=progress;
         if (fileReadBytes(&data[0],0x100)<0x100) {
                 if (fsize-counter>0x100) {
                         display.println("ERROR READING LOA.DER FILE");
@@ -271,7 +271,7 @@
     display.println("LOADER IS NOT AVAILABLE ON THE SIMULATOR. PRESS A TO RETURN.");
     #else
     uint32_t* bootinfo;
-    uint32_t sdversion=0, sdjump=0;
+    uint32_t bootversion=0, sdversion=0, sdjump=0;
     bool flashloader=false, checkforboot=true;
     //check for loa.der on SD card
     #if POK_ENABLE_LOADER_UPDATES > 0
@@ -381,17 +381,17 @@
     display.directcolor=COLOR_WHITE;
     display.fontSize=2;
     int countd = 0;
-    #ifndef POK_SIM
+    //#ifndef POK_SIM
     //read countdown time from settings
     countd = eeprom_read_byte((uint16_t*)EESETTINGS_LOADERWAIT);
-    #endif
+    //#endif
     if (countd<=0 || countd > 5) countd=3;
     uint16_t c2 = getTime();
     while (countd) {
         buttons.pollButtons();
         display.set_cursor(13*8,15*8);
         display.print(countd);
-        if (getTime()>c2+1000) {
+        if (getTime()>uint32_t(c2+1000)) {
             c2=getTime();
             countd--;
         }
@@ -465,42 +465,42 @@
 #define VINCMULT 50
 #endif //POK_SIM
 void Core::setVolLimit() {
-    
     display.enableDirectPrinting(true);
     display.adjustCharStep = 0;
     //sound.setMaxVol(VOLUME_HEADPHONE_MAX);
     int dstate=1;
     bool wipe = true;
-    float vol = sound.getVolume(); 
-    #ifndef POK_SIM
+    float vol = sound.getVolume();
+    //#ifndef POK_SIM
     vol=eeprom_read_byte((uint16_t*)EESETTINGS_VOL);
     Pokitto::Sound::globalVolume=vol;
-    #endif
+    //#endif
     if (vol>VOLUME_HEADPHONE_MAX) sound.setMaxVol(VOLUME_SPEAKER_MAX);
     else sound.setMaxVol(VOLUME_HEADPHONE_MAX);
     #ifdef PRODUCTIONTESTING
     vol=170;
     sound.setMaxVol(VOLUME_SPEAKER_MAX);
     #endif
-    //sound.setVolume(0);
-    //if (vol) {
-    //for (uint8_t t=0;t<=vol;t++) sound.setVolume(t);
+    //for (uint8_t t=0;t<=vol;t++) {
+    //        sound.setVolume(t);
     //}
-    discrete_vol = ((int)vol>>5); //get rid of 0 vol number
-    sound.setVolume(vol);
+	sound.setVolume(vol/4);
+	sound.setVolume(vol/2);
+	sound.setVolume(vol); //prevent "crack" by gradually increasing volume
+	discrete_vol = ((int)vol>>5); // fix "shows zero" in volume slider bug
     volbar_visible=0;
     int countd=0;
-    #ifndef POK_SIM
+    //#ifndef POK_SIM
     //read countdown time from settings
-    //countd = eeprom_read_byte((uint16_t*)EESETTINGS_VOLWAIT);
-    #endif
+    countd = eeprom_read_byte((uint16_t*)EESETTINGS_VOLWAIT);
+    //#endif
     if (countd<=0 || countd > 10) countd=0xFFFF;
     #ifdef PRODUCTIONTESTING
     countd=2;
     #endif
     uint16_t c2 = getTime();
     while (core.isRunning() && dstate && countd){
-        if (getTime()>c2+1000) {
+        if (getTime()>uint32_t(c2+1000)) {
             c2=getTime();
             if (countd<0xFFFF) countd--;
         }
@@ -592,9 +592,9 @@
         }
     }
     vol = sound.getVolume();
-    #ifndef POK_SIM
+    //#ifndef POK_SIM
     if (vol != eeprom_read_byte((uint16_t*)EESETTINGS_VOL)) eeprom_write_byte((uint16_t*)EESETTINGS_VOL,(uint8_t)vol);
-    #endif
+    //#endif
     sound.setVolume(vol);
     //sound.volumeUp();
     display.setCursor(0,0);
@@ -617,12 +617,22 @@
 	buttons.update();
 	battery.begin();
 	display.begin();
+
+	char logoFlag = eeprom_read_byte((uint16_t*)EESETTINGS_SKIPINTRO);
+	if( logoFlag&2 ){ // toggle flag set, change value for next boot
+	    eeprom_write_byte((uint16_t*)EESETTINGS_SKIPINTRO, !(logoFlag&1));
+	}
+	logoFlag &= 1;
+	
 	#if POK_DISPLAYLOGO
         #if PROJ_DEVELOPER_MODE != 1
-        showLogo();
+	if( logoFlag == 0 ){	
+	    showLogo();
+	}
         #endif // PROJ_DEVELOPER_MODE
 	#endif // POK_DISPLAYLOGO
 
+	
 	display.enableDirectPrinting(true);
     display.directbgcolor = COLOR_BLACK;
     display.clearLCD();
@@ -631,7 +641,6 @@
     display.enableDirectPrinting(true);
     display.directbgcolor = COLOR_BLACK;
     display.directcolor = COLOR_GREEN;
-    display.clearLCD();
     display.setFont(fntC64UIGfx);
     display.adjustCharStep=0;
     display.adjustLineStep=1;
@@ -641,7 +650,9 @@
 
     #ifndef DISABLE_LOADER
     #if PROJ_DEVELOPER_MODE != 1
-    askLoader();
+	if( logoFlag == 0 ){
+	    askLoader();
+	}
     #endif // PROJ_DEVELOPER_MODE
     #endif
 
@@ -649,18 +660,22 @@
 	sound.setMaxVol(VOLUME_SPEAKER_MAX);
 	sound.setVolume(VOLUME_SPEAKER_MAX);
 	#else
-	//showWarning();
-	setVolLimit();
-	display.clear();
-	display.update();
+	if( logoFlag == 0 ){
+	    //showWarning();
+	    setVolLimit();
+	    display.clear();
+	    display.update();
 
-	while(buttons.states[BTN_A])
-    {
-        buttons.update();
-    }
+	    while(buttons.states[BTN_A])
+	    {
+		buttons.update();
+	    }
+	}else{
+	    sound.setVolume(sound.getVolume());//make sure we're at set volume before continue
+	}
 
-	//sound.setVolume(sound.getVolume());//make sure we're at set volume before continue
 	#endif
+	
 	display.enableDirectPrinting(false);
 	display.adjustCharStep=1;
 	display.adjustLineStep=1;
@@ -670,7 +685,7 @@
 	display.setFont(font5x7);
 	#else
 	display.setFont(fontC64);
-    #endif
+    	#endif
 	#if POK_ENABLE_SOUND > 0
         sound.begin();
 
@@ -1042,9 +1057,6 @@
 
 			//draw a fancy menu
 			display.textWrap = false;
-			//uint16_t fc,bc;
-			//fc = display.color;
-            //bc = display.bgcolor;
             if( updated ) { // update screen?
                 #if POK_SIM
                 getFirstFile(ext);
@@ -1103,11 +1115,12 @@
 
         display.setColor(1,0);
 	}
+
 	return 0;
 }
 
 char* Core::filemenu() {
-    return filemenu("");
+    return filemenu((char*)"");
 }
 
 int8_t Core::menu(const char* const* items, uint8_t length) {
@@ -1345,6 +1358,10 @@
 	sound.prescaler = __avrmax(1, sound.prescaler);
 }
 
+uint8_t Core::getFrameRate() {
+	return 1000 / timePerFrame;
+}
+
 void Core::pickRandomSeed(){
         initRandom();
 }
--- a/POKITTO_CORE/PokittoCore.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoCore.h	Sat Mar 23 20:03:34 2019 +0000
@@ -62,7 +62,6 @@
 #include "PokittoFakeavr.h"
 
 #define PALETTE_SIZE 256
-#undef PI
 #define PI 3.141592741f
 
 // For GB compatibility
@@ -226,6 +225,7 @@
     static void keyboard(char* text, uint8_t length);
     static void popup(const char* text, uint8_t duration);
     static void setFrameRate(uint8_t fps);
+    static uint8_t getFrameRate();	
 	static void pickRandomSeed();
 
 	static uint8_t getCpuLoad();
--- a/POKITTO_CORE/PokittoDisk.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoDisk.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -56,14 +56,16 @@
     return dot + 1;
 }
 
-__attribute__((section(".SD_Code"))) void initSDGPIO() {
+//__attribute__((section(".SD_Code")))
+void initSDGPIO() {
     LPC_GPIO_PORT->DIR[SD_MOSI_PORT] |= (1  << SD_MOSI_PIN );
     LPC_GPIO_PORT->DIR[SD_MISO_PORT] |= (1  << SD_MISO_PIN );
     LPC_GPIO_PORT->DIR[SD_SCK_PORT]  |= (1  << SD_SCK_PIN );
     LPC_GPIO_PORT->DIR[SD_CS_PORT]   |= (1  << SD_CS_PIN );
 }
 
-__attribute__((section(".SD_Code"))) int pokInitSD() {
+//__attribute__((section(".SD_Code")))
+int pokInitSD() {
     initSDGPIO();
     res = PFFS::disk_initialize();
     //res = disk_initialize(0);
@@ -81,12 +83,12 @@
 
 /** PUBLIC FUNCTIONS **/
 
-char* getFirstDirEntry() {
+char* getFirstDirEntry(char* path) {
     res=0;
     if (!diropened) {
             pokInitSD();
     }
-    res = pf_opendir(&dir,"");
+    res = pf_opendir(&dir,path);
     emptyFname();
     res = pf_readdir(&dir,&fno); //returns 0 if everything is OK
     if (res) return 0;
@@ -108,6 +110,10 @@
     return 0;
 }
 
+char* getFirstDirEntry() {
+    return getFirstDirEntry("");
+}
+
 char* getNextDirEntry() {
     if (!diropened) pokInitSD();
     emptyFname();
@@ -162,12 +168,12 @@
     return getNextFile("");
 }
 
-char* getFirstFile(char* ext) {
+char* getFirstFile(char* ext, char* path) {
     res=0;
     if (!diropened) {
             pokInitSD();
     }
-    res = pf_opendir(&dir,"");
+    res = pf_opendir(&dir,path);
     emptyFname();
     res = pf_readdir(&dir,&fno); //returns 0 if everything is OK
     if (res) return 0;
@@ -184,6 +190,10 @@
     return 0;
 }
 
+char* getFirstFile(char* ext) {
+    return getFirstFile(ext, "");
+}
+
 char* getFirstFile() {
     return getFirstFile("");
 }
--- a/POKITTO_CORE/PokittoDisk.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoDisk.h	Sat Mar 23 20:03:34 2019 +0000
@@ -64,7 +64,7 @@
 // CS ... #define CONNECT_CS      P0_7 //p13
 #define CLR_SD_CS LPC_GPIO_PORT->CLR[0] = (1 << 7)
 #define SET_SD_CS LPC_GPIO_PORT->SET[0] = (1 << 7)
-#define GET_SD_CS LPC_GPIO_PORT->PIN[0] & (1 << 7)
+#define GET_SD_CS ((LPC_GPIO_PORT->PIN[0]) & (1 << 7))
 
 #else
 // simulated disk driver
@@ -104,9 +104,11 @@
 extern char* getCurrentFileName ();
 extern char* getNextFile (char*);
 extern char* getNextFile ();
-extern char* getFirstFile(char*);
+extern char* getFirstFile(char* ext);
+extern char* getFirstFile(char* ext, char* path);
 extern char* getFirstFile();
 extern char* getFirstDirEntry();
+extern char* getFirstDirEntry(char* path);
 extern char* getNextDirEntry();
 extern int isThisFileOpen(char*);
 extern int fileOK();
--- a/POKITTO_CORE/PokittoGlobs.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoGlobs.h	Sat Mar 23 20:03:34 2019 +0000
@@ -52,8 +52,6 @@
 extern int random(int);
 extern int random(int,int);
 
-#undef HIGH
-#undef LOW
 #define HIGH    1
 #define LOW     0
 
@@ -78,7 +76,11 @@
 #if POK_STREAMING_MUSIC
     #define SPEAKER 3
    // #define BUFFER_SIZE 512 //5120 // was 256
+#if POK_HIGH_RAM == HIGH_RAM_MUSIC
+    extern unsigned char *buffers[];
+#else
     extern unsigned char buffers[][BUFFER_SIZE];
+#endif
     extern volatile int currentBuffer, oldBuffer;
     extern volatile int bufindex, vol;
     extern volatile unsigned char * currentPtr;
--- a/POKITTO_CORE/PokittoItoa.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoItoa.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -38,6 +38,21 @@
 #include <string.h>
 #include <stdint.h>
 
+/* A utility function to reverse a string  */
+void reverse(char str[], int length)
+{
+    int start = 0;
+    int end = length -1;
+    while (start < end)
+    {
+        char t = *(str+end);
+        *(str+end) = *(str+start);
+        *(str+start) = t;
+        //std::swap(*(str+start), *(str+end));
+        start++;
+        end--;
+    }
+}
 
 void pokItoa(uint16_t value, char *str, int base)
 {
@@ -134,8 +149,44 @@
     pokItoa(value,str,base);
 }
 
-void pokLtoa(long value, char *str, int base) {
-    pokItoa(value,str,base);
+void pokLtoa(long num, char *str, int base) {
+    int i = 0;
+    bool isNegative = false;
+
+    /* Handle 0 explicitely, otherwise empty string is printed for 0 */
+    if (num == 0)
+    {
+        str[i++] = '0';
+        str[i] = '\0';
+        return;// str;
+    }
+
+    // In standard itoa(), negative numbers are handled only with
+    // base 10. Otherwise numbers are considered unsigned.
+    if (num < 0 && base == 10)
+    {
+        isNegative = true;
+        num = -num;
+    }
+
+    // Process individual digits
+    while (num != 0)
+    {
+        int rem = num % base;
+        str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
+        num = num/base;
+    }
+
+    // If number is negative, append '-'
+    if (isNegative)
+        str[i++] = '-';
+
+    str[i] = '\0'; // Append string terminator
+
+    // Reverse the string
+    reverse(str, i);
+
+    return;// str;
 }
 
 
--- a/POKITTO_CORE/PokittoPalette.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoPalette.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -46,7 +46,7 @@
 #include "SimLCD.h"
 #endif
 
-#ifndef PROJ_MODE13
+#if PROJ_SCREENMODE != 13 && PROJ_SCREENMODE != 64 && !defined(PROJ_MODE13) && !defined(PROJ_MODE64)
 #define PALSIZE 16
 #else
 #define PALSIZE 256
--- a/POKITTO_CORE/PokittoSound.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoSound.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -43,7 +43,7 @@
  *
  * License for Gamebuino-identical code:
  *
- * (C) Copyright 2014 Aur�lien Rodot. All rights reserved.
+ * (C) Copyright 2014 Aurélien Rodot. All rights reserved.
  *
  * This file is part of the Gamebuino Library (http://gamebuino.com)
  *
@@ -68,6 +68,11 @@
 
 #ifndef POK_SIM
 #include "HWSound.h"
+
+#ifdef PROJ_SDFS_STREAMING
+#include "SDFSDisk.h"
+#endif
+
 #else
 #include "SimSound.h"
 #include "PokittoSimulator.h"
@@ -77,15 +82,22 @@
 
 using namespace Pokitto;
 
+#ifdef PROJ_SND_DEBUG
+int __sx=0;
+#endif
+
 /** discrete hardware volume control **/
 
 uint8_t Pokitto::discrete_vol = 0;
-uint8_t const Pokitto::discrete_vol_levels[]      = {0,32,64,96,128,160,192,224};
-uint8_t const Pokitto::discrete_vol_hw_levels[]   = {0,27,64,96,36,117,127,127};
-uint8_t const Pokitto::discrete_vol_multipliers[] = {0,127,127,127,192,192,255,255};
+uint8_t const Pokitto::discrete_vol_levels[8]      {0,32,64,96,128,160,192,224};
+uint8_t const Pokitto::discrete_vol_hw_levels[8]   {0,27,64,96,36,117,127,127};
+uint8_t const Pokitto::discrete_vol_multipliers[8] {0,127,127,127,192,192,255,255};
 
 Pokitto::Core _soundc;
 
+const uint8_t *Sound::sfxDataPtr = 0;
+const uint8_t *Sound::sfxEndPtr = 0;
+
 uint8_t Sound::prescaler;
 uint16_t Sound::globalVolume;
 uint16_t Sound::volumeMax = VOLUME_HEADPHONE_MAX;
@@ -135,8 +147,10 @@
 uint8_t Sound::chanVolumes[NUM_CHANNELS];
 
 #if (POK_ENABLE_SOUND < 1)
+ #ifdef NUM_CHANNELS
  #undef NUM_CHANNELS
  #define NUM_CHANNELS 0
+ #endif // NUM_CHANNELS
 #endif
 
 #if(NUM_CHANNELS > 0)
@@ -609,6 +623,7 @@
 		// jonnehw noInterrupts();
 		_chanHalfPeriod[i] = pgm_read_byte(_halfPeriods + outputPitch[i]);
 		_chanOutput[i] = _chanOutputVolume[i] = outputVolume[i] * (globalVolume>>GLOBVOL_SHIFT) * chanVolumes[i] * stepVolume[i];
+		//_chanOutput[i] = _chanOutputVolume[i] = outputVolume[i] * (globalVolume) * chanVolumes[i] * stepVolume[i];
 		//Serial.println(outputVolume[i]);
 		// jonnehw interrupts();
 	}
@@ -752,6 +767,7 @@
             output >>= 8;
             dac_write((uint8_t)output); //direct hardware mixing baby !
     soundbyte = output;
+
     #endif //POK_ENABLE_SOUND
     #else
     /** SIMULATOR **/
@@ -763,6 +779,7 @@
         #endif
         soundbyte = output;//<<headPhoneLevel;
     #endif // POK_SIM
+
 #endif
 }
 
@@ -803,12 +820,14 @@
 	if (volume<0) volume = 0;
 	//if (volume>volumeMax) volume = volumeMax;
 	globalVolume = volume;
-	#if POK_ENABLE_SOUND > 0
+	//#if POK_ENABLE_SOUND > 0
 	discrete_vol = (volume>>5);
 	#ifndef POK_SIM
+	#if POK_ENABLE_SOUND > 0
 	setHWvolume(discrete_vol_hw_levels[discrete_vol]); //boost volume if headphonelevel
 	#endif
 	#endif
+	//#endif
 	#if POK_SHOW_VOLUME > 0
 	_soundc.volbar_visible = VOLUMEBAR_TIMEOUT;
 	#endif
@@ -845,7 +864,7 @@
 
 void Sound::playTone(uint8_t os, int frq, uint8_t amp, uint8_t wav,uint8_t arpmode)
 {
-    if (wav>5) wav=0;
+    if (wav>MAX_WAVETYPES) wav=0;
     if (arpmode>MAX_ARPMODE) arpmode=MAX_ARPMODE;
     if (os==1) setOSC(&osc1,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
     else if (os==2) setOSC(&osc2,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
@@ -893,9 +912,9 @@
     if (currentPtr) {
             pokPlayStream();
             return 1;
-    } else return 0; //no stream
+    }
     #endif // POK_STREAMING_MUSIC
-    return 0;
+    return 0; //no stream
 }
 
 void Sound::pauseMusicStream() {
@@ -907,12 +926,16 @@
 int Sound::playMusicStream(char* filename, uint8_t options)
 {
     #if POK_STREAMING_MUSIC
+
         uint8_t result;
         result = pokInitSD();
         if (!isThisFileOpen(filename)) {
             fileClose(); // close any open files
             result = fileOpen(filename,FILE_MODE_READONLY | FILE_MODE_BINARY);
-        }
+        }else{
+	    fileRewind();
+	    result = 0;
+	}
 
         if (result) {
                 currentPtr = 0; // mark that no stream is available
@@ -948,3 +971,13 @@
     return 0;
 }
 
+void Sound::loadSampleToOsc(uint8_t os, uint8_t* data, uint32_t datasize) {
+    OSC* o;
+    if (os==3) o = &osc3;
+    else if (os==2) o = &osc2;
+    else o = &osc1;
+    o->sample = data;
+    o->samplelength = datasize;
+    o->samplepos = 0;
+}
+
--- a/POKITTO_CORE/PokittoSound.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_CORE/PokittoSound.h	Sat Mar 23 20:03:34 2019 +0000
@@ -104,6 +104,13 @@
     static uint16_t volumeMax;
 
 public:
+    static const uint8_t *sfxDataPtr;
+    static const uint8_t *sfxEndPtr;
+    static void playSFX( const uint8_t *sfx, uint32_t length ){
+	sfxDataPtr = sfx;
+	sfxEndPtr = sfx + length;
+    };
+    
 	static void begin();
 
 	// Headphonemode
@@ -113,6 +120,9 @@
     static void volumeUp();
     static void volumeDown();
 
+    // Synth using samples support
+    static void loadSampleToOsc(uint8_t os, uint8_t* sampdata, uint32_t sampsize);
+
 	// Original functions
 	static void updateStream();
     static void playTone(uint8_t os, int frq, uint8_t amp, uint8_t wav,uint8_t arpmode);
--- a/POKITTO_LIBS/Synth/Synth.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_LIBS/Synth/Synth.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -36,17 +36,19 @@
 
 #include "Pokitto.h"
 #include "Synth.h"
+#include "stdint.h"
+#include "My_settings.h"
 
 /** COMMON TO BOTH HW AND SIMULATED SOUND **/
 
-boolean playing=false; //external to share between player and synth
-boolean track1on = true, track2on = true, track3on = true, tableRefresh = false;
+bool playing=false; //external to share between player and synth
+bool track1on = true, track2on = true, track3on = true, tableRefresh = false;
 
 uint8_t sequencepos=0, tempo = 120;
 long writeindex=0, readindex=0;
 uint16_t playerpos=0;
-long per = 1000*60/tempo/4; // ms per minute was 1000*60
-uint16_t samplespertick = (uint16_t)per*57, notetick; // samplespertick is a calculated value based on song speed. notetick is a counter
+uint16_t samplespertick = (float)((60.0f/(float)tempo)*POK_AUD_FREQ)/16;
+uint16_t notetick=0; // samplespertick is a calculated value based on song speed. notetick is a counter
 long samplesperpattern=0;
 
 uint8_t tick=3; // loops between 3 channels. Tick 3 is used to calculate volume envelopes
@@ -54,8 +56,8 @@
 
 SONG song;
 OSC osc1,osc2,osc3;
-OSC patch[15];
-BLOCK block[1]; //30 blocks maximum
+OSC patch[MAXPATCHES];
+BLOCK block[MAXBLOCKS];
 
 
 
--- a/POKITTO_LIBS/Synth/Synth.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_LIBS/Synth/Synth.h	Sat Mar 23 20:03:34 2019 +0000
@@ -36,15 +36,20 @@
 }
 */
 
-#ifndef boolean
-typedef bool boolean;
-#endif
+#define OPT_ADSR 1
+#define OPT_LOOP 2
+#define OPT_ECHO 4
+#define OPT_OVERDRIVE 8
+#define OPT_NORMALIZE 0x10
+
+#define OVERDRIVE 4
 
 //extern void fakeISR(); // was defined in Rboy_soundsim.h
 
 typedef void (*waveFunction)(OSC*);
 typedef void (*envFunction)(OSC*);
 typedef void (*mixFunction)();
+typedef void (*streamsFunction)();
 
 extern waveFunction Farr [];
 extern envFunction Earr [];
@@ -67,10 +72,21 @@
 #define ARPSTEPMAX 4 // was 5
 #define PATTERNLENGTH 64
 #define MAXPATTERNS 10
+
+#ifdef PROJ_SYNTH_MAXBLOCKS
+#define MAXBLOCKS PROJ_SYNTH_MAXBLOCKS
+#else
 #define MAXBLOCKS 30 // 10 *3
+#endif
 
-#define VOLTICK 5
-#define ARPTICK 50 // 150 // was 200
+#ifdef PROJ_SYNTH_MAXPATCHES
+#define MAXPATCHES PROJ_SYNTH_MAXPATCHES
+#else
+#define MAXPATCHES 15
+#endif
+
+#define VOLTICK POK_AUD_FREQ/8820 //was 5
+#define ARPTICK POK_AUD_FREQ/441 // 150 // was 200
 
 #define NUMWAVES 5
 #define NUMENVELOPES 3
@@ -100,9 +116,10 @@
 extern int openSongFromSD(char *);
 extern void writeChunkToSD(uint8_t *);
 extern void readChunkFromSD(uint8_t *);
-
+extern void registerStreamsCallback(streamsFunction);
+extern streamsFunction streamCallbackPtr;
 
-extern boolean playing, track1on, track2on, track3on, tableRefresh;
+extern bool playing, track1on, track2on, track3on, tableRefresh;
 extern uint16_t playerpos;
 extern uint16_t samplespertick, notetick;
 extern long samplesperpattern;
@@ -116,6 +133,7 @@
 extern BLOCK block[]; // array of blocks
 
 #define MAX_ARPMODE 16
+#define MAX_WAVETYPES 6
 
 extern int8_t arptable[][5];
 
@@ -129,7 +147,7 @@
 extern uint16_t noiseval;
 
 extern void setOSC(OSC*,byte, byte, byte, byte, byte,
-            uint8_t, uint8_t,
+            uint8_t, uint16_t,
             uint16_t, uint16_t, uint16_t, uint16_t,
             int16_t, int16_t, uint8_t, uint8_t, uint8_t);
 
--- a/POKITTO_LIBS/Synth/Synth_helpers.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_LIBS/Synth/Synth_helpers.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -639,97 +639,97 @@
 
 /** NOTE TO TEXT TABLES **/
 
-const char note_0[] PROGMEM = "B-0";  // 0 - NOTE_B0
-const char note_1[] PROGMEM = "C-1";  // 1 - NOTE_C1
-const char note_2[] PROGMEM = "C#1";  // 2 - NOTE_CS1
-const char note_3[] PROGMEM = "D-1";  // 3 - NOTE_D1
-const char note_4[] PROGMEM = "D#1";  // 4 - NOTE_DS1
-const char note_5[] PROGMEM = "E-1";  // 5 - NOTE_E1
-const char note_6[] PROGMEM = "F-1";  // 6 - NOTE_F1
-const char note_7[] PROGMEM = "F#1";  // 7 - NOTE_FS1
-const char note_8[] PROGMEM = "G-1";  // 8 - NOTE_G1
-const char note_9[] PROGMEM = "G#1";  // 9 - NOTE_GS1
-const char note_10[] PROGMEM = "A-1";  // 10 - NOTE_A1
-const char note_11[] PROGMEM = "A#1";  // 11 - NOTE_AS1
-const char note_12[] PROGMEM = "B-1";  // 12 - NOTE_B1
-const char note_13[] PROGMEM = "C-2";  // 2 - NOTE_C2
-const char note_14[] PROGMEM = "C#2";  // 2 - NOTE_CS2
-const char note_15[] PROGMEM = "D-2";  // 3 - NOTE_D2
-const char note_16[] PROGMEM = "D#2";  // 4 - NOTE_DS2
-const char note_17[] PROGMEM = "E-2";  // 5 - NOTE_E2
-const char note_18[] PROGMEM = "F-2";  // 6 - NOTE_F2
-const char note_19[] PROGMEM = "F#2";  // 7 - NOTE_FS2
-const char note_20[] PROGMEM = "G-2";  // 8 - NOTE_G2
-const char note_21[] PROGMEM = "G#2";  // 9 - NOTE_GS2
-const char note_22[] PROGMEM = "A-2";  // 20 - NOTE_A2
-const char note_23[] PROGMEM = "A#2";  // 22 - NOTE_AS2
-const char note_24[] PROGMEM = "B-2";  // 22 - NOTE_B2
-const char note_25[] PROGMEM = "C-3";  // 3 - NOTE_C3
-const char note_26[] PROGMEM = "C#3";  // 3 - NOTE_CS3
-const char note_27[] PROGMEM = "D-3";  // 3 - NOTE_D3
-const char note_28[] PROGMEM = "D#3";  // 4 - NOTE_DS3
-const char note_29[] PROGMEM = "E-3";  // 5 - NOTE_E3
-const char note_30[] PROGMEM = "F-3";  // 6 - NOTE_F3
-const char note_31[] PROGMEM = "F#3";  // 7 - NOTE_FS3
-const char note_32[] PROGMEM = "G-3";  // 8 - NOTE_G3
-const char note_33[] PROGMEM = "G#3";  // 9 - NOTE_GS3
-const char note_34[] PROGMEM = "A-3";  // 30 - NOTE_A3
-const char note_35[] PROGMEM = "A#3";  // 33 - NOTE_AS3
-const char note_36[] PROGMEM = "B-3";  // 33 - NOTE_B3
-const char note_37[] PROGMEM = "C-4";  // 4 - NOTE_C4
-const char note_38[] PROGMEM = "C#4";  // 4 - NOTE_CS4
-const char note_39[] PROGMEM = "D-4";  // 3 - NOTE_D4
-const char note_40[] PROGMEM = "D#4";  // 4 - NOTE_DS4
-const char note_41[] PROGMEM = "E-4";  // 5 - NOTE_E4
-const char note_42[] PROGMEM = "F-4";  // 6 - NOTE_F4
-const char note_43[] PROGMEM = "F#4";  // 7 - NOTE_FS4
-const char note_44[] PROGMEM = "G-4";  // 8 - NOTE_G4
-const char note_45[] PROGMEM = "G#4";  // 9 - NOTE_GS4
-const char note_46[] PROGMEM = "A-4";  // 40 - NOTE_A4
-const char note_47[] PROGMEM = "A#4";  // 44 - NOTE_AS4
-const char note_48[] PROGMEM = "B-4";  // 44 - NOTE_B4
-const char note_49[] PROGMEM = "C-5";  // 5 - NOTE_C5
-const char note_50[] PROGMEM = "C#5";  // 5 - NOTE_CS5
-const char note_51[] PROGMEM = "D-5";  // 3 - NOTE_D5
-const char note_52[] PROGMEM = "D#5";  // 4 - NOTE_DS5
-const char note_53[] PROGMEM = "E-5";  // 5 - NOTE_E5
-const char note_54[] PROGMEM = "F-5";  // 6 - NOTE_F5
-const char note_55[] PROGMEM = "F#5";  // 7 - NOTE_FS5
-const char note_56[] PROGMEM = "G-5";  // 8 - NOTE_G5
-const char note_57[] PROGMEM = "G#5";  // 9 - NOTE_GS5
-const char note_58[] PROGMEM = "A-5";  // 50 - NOTE_A5
-const char note_59[] PROGMEM = "A#5";  // 55 - NOTE_AS5
-const char note_60[] PROGMEM = "B-5";  // 55 - NOTE_B5
-const char note_61[] PROGMEM = "C-6";  // 6 - NOTE_C6
-const char note_62[] PROGMEM = "C#6";  // 6 - NOTE_CS6
-const char note_63[] PROGMEM = "D-6";  // 3 - NOTE_D6
-const char note_64[] PROGMEM = "D#6";  // 4 - NOTE_DS6
-const char note_65[] PROGMEM = "E-6";  // 5 - NOTE_E6
-const char note_66[] PROGMEM = "F-6";  // 6 - NOTE_F6
-const char note_67[] PROGMEM = "F#6";  // 7 - NOTE_FS6
-const char note_68[] PROGMEM = "G-6";  // 8 - NOTE_G6
-const char note_69[] PROGMEM = "G#6";  // 9 - NOTE_GS6
-const char note_70[] PROGMEM = "A-6";  // 60 - NOTE_A6
-const char note_71[] PROGMEM = "A#6";  // 66 - NOTE_AS6
-const char note_72[] PROGMEM = "B-6";  // 66 - NOTE_B6
-const char note_73[] PROGMEM = "C-7";  // 7 - NOTE_C7
-const char note_74[] PROGMEM = "C#7";  // 7 - NOTE_CS7
-const char note_75[] PROGMEM = "D-7";  // 3 - NOTE_D7
-const char note_76[] PROGMEM = "D#7";  // 4 - NOTE_DS7
-const char note_77[] PROGMEM = "E-7";  // 5 - NOTE_E7
-const char note_78[] PROGMEM = "F-7";  // 6 - NOTE_F7
-const char note_79[] PROGMEM = "F#7";  // 7 - NOTE_FS7
-const char note_80[] PROGMEM = "G-7";  // 8 - NOTE_G7
-const char note_81[] PROGMEM = "G#7";  // 9 - NOTE_GS7
-const char note_82[] PROGMEM = "A-7";  // 70 - NOTE_A7
-const char note_83[] PROGMEM = "A#7";  // 77 - NOTE_AS7
-const char note_84[] PROGMEM = "B-7";  // 77 - NOTE_B7
-const char note_85[] PROGMEM = "C-8";  // 8 - NOTE_C8
-const char note_86[] PROGMEM = "C#8";  // 8 - NOTE_CS8
-const char note_87[] PROGMEM = "D-8";  // 3 - NOTE_D8
-const char note_88[] PROGMEM = "D#8";  // 4 - NOTE_DS8
+const char note_0[]  = "B-0";  // 0 - NOTE_B0
+const char note_1[]  = "C-1";  // 1 - NOTE_C1
+const char note_2[]  = "C#1";  // 2 - NOTE_CS1
+const char note_3[]  = "D-1";  // 3 - NOTE_D1
+const char note_4[]  = "D#1";  // 4 - NOTE_DS1
+const char note_5[]  = "E-1";  // 5 - NOTE_E1
+const char note_6[]  = "F-1";  // 6 - NOTE_F1
+const char note_7[]  = "F#1";  // 7 - NOTE_FS1
+const char note_8[]  = "G-1";  // 8 - NOTE_G1
+const char note_9[]  = "G#1";  // 9 - NOTE_GS1
+const char note_10[]  = "A-1";  // 10 - NOTE_A1
+const char note_11[]  = "A#1";  // 11 - NOTE_AS1
+const char note_12[]  = "B-1";  // 12 - NOTE_B1
+const char note_13[]  = "C-2";  // 2 - NOTE_C2
+const char note_14[]  = "C#2";  // 2 - NOTE_CS2
+const char note_15[]  = "D-2";  // 3 - NOTE_D2
+const char note_16[]  = "D#2";  // 4 - NOTE_DS2
+const char note_17[]  = "E-2";  // 5 - NOTE_E2
+const char note_18[]  = "F-2";  // 6 - NOTE_F2
+const char note_19[]  = "F#2";  // 7 - NOTE_FS2
+const char note_20[]  = "G-2";  // 8 - NOTE_G2
+const char note_21[]  = "G#2";  // 9 - NOTE_GS2
+const char note_22[]  = "A-2";  // 20 - NOTE_A2
+const char note_23[]  = "A#2";  // 22 - NOTE_AS2
+const char note_24[]  = "B-2";  // 22 - NOTE_B2
+const char note_25[]  = "C-3";  // 3 - NOTE_C3
+const char note_26[]  = "C#3";  // 3 - NOTE_CS3
+const char note_27[]  = "D-3";  // 3 - NOTE_D3
+const char note_28[]  = "D#3";  // 4 - NOTE_DS3
+const char note_29[]  = "E-3";  // 5 - NOTE_E3
+const char note_30[]  = "F-3";  // 6 - NOTE_F3
+const char note_31[]  = "F#3";  // 7 - NOTE_FS3
+const char note_32[]  = "G-3";  // 8 - NOTE_G3
+const char note_33[]  = "G#3";  // 9 - NOTE_GS3
+const char note_34[]  = "A-3";  // 30 - NOTE_A3
+const char note_35[]  = "A#3";  // 33 - NOTE_AS3
+const char note_36[]  = "B-3";  // 33 - NOTE_B3
+const char note_37[]  = "C-4";  // 4 - NOTE_C4
+const char note_38[]  = "C#4";  // 4 - NOTE_CS4
+const char note_39[]  = "D-4";  // 3 - NOTE_D4
+const char note_40[]  = "D#4";  // 4 - NOTE_DS4
+const char note_41[]  = "E-4";  // 5 - NOTE_E4
+const char note_42[]  = "F-4";  // 6 - NOTE_F4
+const char note_43[]  = "F#4";  // 7 - NOTE_FS4
+const char note_44[]  = "G-4";  // 8 - NOTE_G4
+const char note_45[]  = "G#4";  // 9 - NOTE_GS4
+const char note_46[]  = "A-4";  // 40 - NOTE_A4
+const char note_47[]  = "A#4";  // 44 - NOTE_AS4
+const char note_48[]  = "B-4";  // 44 - NOTE_B4
+const char note_49[]  = "C-5";  // 5 - NOTE_C5
+const char note_50[]  = "C#5";  // 5 - NOTE_CS5
+const char note_51[]  = "D-5";  // 3 - NOTE_D5
+const char note_52[]  = "D#5";  // 4 - NOTE_DS5
+const char note_53[]  = "E-5";  // 5 - NOTE_E5
+const char note_54[]  = "F-5";  // 6 - NOTE_F5
+const char note_55[]  = "F#5";  // 7 - NOTE_FS5
+const char note_56[]  = "G-5";  // 8 - NOTE_G5
+const char note_57[]  = "G#5";  // 9 - NOTE_GS5
+const char note_58[]  = "A-5";  // 50 - NOTE_A5
+const char note_59[]  = "A#5";  // 55 - NOTE_AS5
+const char note_60[]  = "B-5";  // 55 - NOTE_B5
+const char note_61[]  = "C-6";  // 6 - NOTE_C6
+const char note_62[]  = "C#6";  // 6 - NOTE_CS6
+const char note_63[]  = "D-6";  // 3 - NOTE_D6
+const char note_64[]  = "D#6";  // 4 - NOTE_DS6
+const char note_65[]  = "E-6";  // 5 - NOTE_E6
+const char note_66[]  = "F-6";  // 6 - NOTE_F6
+const char note_67[]  = "F#6";  // 7 - NOTE_FS6
+const char note_68[]  = "G-6";  // 8 - NOTE_G6
+const char note_69[]  = "G#6";  // 9 - NOTE_GS6
+const char note_70[]  = "A-6";  // 60 - NOTE_A6
+const char note_71[]  = "A#6";  // 66 - NOTE_AS6
+const char note_72[]  = "B-6";  // 66 - NOTE_B6
+const char note_73[]  = "C-7";  // 7 - NOTE_C7
+const char note_74[]  = "C#7";  // 7 - NOTE_CS7
+const char note_75[]  = "D-7";  // 3 - NOTE_D7
+const char note_76[]  = "D#7";  // 4 - NOTE_DS7
+const char note_77[]  = "E-7";  // 5 - NOTE_E7
+const char note_78[]  = "F-7";  // 6 - NOTE_F7
+const char note_79[]  = "F#7";  // 7 - NOTE_FS7
+const char note_80[]  = "G-7";  // 8 - NOTE_G7
+const char note_81[]  = "G#7";  // 9 - NOTE_GS7
+const char note_82[]  = "A-7";  // 70 - NOTE_A7
+const char note_83[]  = "A#7";  // 77 - NOTE_AS7
+const char note_84[]  = "B-7";  // 77 - NOTE_B7
+const char note_85[]  = "C-8";  // 8 - NOTE_C8
+const char note_86[]  = "C#8";  // 8 - NOTE_CS8
+const char note_87[]  = "D-8";  // 3 - NOTE_D8
+const char note_88[]  = "D#8";  // 4 - NOTE_DS8
 
-const char* note_table[] PROGMEM = {
+const char* note_table[]  = {
  note_0,
  note_1,
  note_2,
--- a/POKITTO_LIBS/Synth/Synth_mixfuncs.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_LIBS/Synth/Synth_mixfuncs.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -48,12 +48,12 @@
     // Track 1
     if (osc1.on) {
     Farr[osc1.wave](&osc1);
-    #if PROJ_ARDUBOY > 0
+    //#if PROJ_ARDUBOY > 0
     if (osc1.duration) {
         /**this is special for osc1 and is only used to emulate arduino Tone(); */
         osc1.duration--;
     } else osc1.on = 0;
-    #endif
+    //#endif
 
     #ifdef POK_SIM
     soundbyte = (((osc1.output>>8) * (osc1.adsrvol >>8 )) >> 8) >> osc1.echodiv; // To output, shift back to 8-bit
@@ -76,6 +76,10 @@
     // Track 2
     if (osc2.on) {
     Farr[osc2.wave](&osc2);
+    if (osc2.duration) {
+        osc2.duration--;
+    } else osc2.on = 0;
+
     #ifdef POK_SIM
     soundbyte = (((osc2.output>>8) * (osc2.adsrvol >>8 )) >> 8) >> osc2.echodiv;
     if (osc2.overdrive) soundbyte *= OVERDRIVE;
@@ -97,6 +101,9 @@
     // Track 3
     if (osc3.on) {
     Farr[osc3.wave](&osc3);
+    if (osc3.duration) {
+        osc3.duration--;
+    } else osc3.on = 0;
     #ifdef POK_SIM
     soundbyte = (((osc3.output>>8) * (osc3.adsrvol >>8 )) >> 8) >> osc3.echodiv;
     if (osc3.overdrive) soundbyte *= OVERDRIVE;
@@ -116,7 +123,11 @@
 
 void updateEnvelopes(){
     //calculate volume envelopes, I do this to save cpu power
+    #if POK_ALT_MIXING > 0
     if (arptick) --arptick;
+    #else
+    if (arptick) --arptick;
+    #endif
     else {
             if (osc1.arpmode && osc1.on) {
                 osc1.cinc = cincs[osc1.tonic+arptable[osc1.arpmode][osc1.arpstep]];
@@ -139,11 +150,25 @@
 
     }
 
+    #if POK_ALT_MIXING > 0
     if (voltick) --voltick;
+    #else
+    if (voltick) --voltick;
+    #endif
     else {
             bendtick = !bendtick;
             if (osc1.on) Earr[osc1.adsrphase](&osc1);
-            if (bendtick) osc1.pitchbend += osc1.bendrate; //slow bend to every second beat
+            if (bendtick) {
+                    osc1.pitchbend += osc1.bendrate; //slow bend to every second beat
+                    /*if (osc1.wave == 6 && osc1.bendrate) {
+                        if (osc1.samplebendtick > osc1.samplebendcount) {
+                            if (osc1.bendrate>0) osc1.samplestep++;
+                            else if (osc1.bendrate<0) osc1.samplestep--;
+                            osc1.samplebendtick=0;
+                        } else osc1.samplebendtick++;
+
+                    }*/
+            }
             if (osc1.bendrate > 0 && osc1.pitchbend > osc1.maxbend) {
                     osc1.pitchbend = osc1.maxbend;
                     osc1.bendrate = 0; // STOP BENDING !
--- a/POKITTO_LIBS/Synth/Synth_osc.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_LIBS/Synth/Synth_osc.h	Sat Mar 23 20:03:34 2019 +0000
@@ -49,9 +49,9 @@
   uint16_t sustain; // Attack change
   uint16_t release; // Attack change
 
-  int16_t pitchbend;   // bends cycle counter (more is higher pitch)
-  int16_t maxbend; // maximum bend before stopping
-  int16_t bendrate; // how much to bend by every cycle
+  int32_t pitchbend;   // bends cycle counter (more is higher pitch)
+  int32_t maxbend; // maximum bend before stopping
+  int32_t bendrate; // how much to bend by every cycle
 
   uint8_t vibrate;
   uint8_t arpmode;
@@ -61,6 +61,14 @@
   uint8_t kick;
 
   uint32_t duration;
+
+  uint32_t samplepos;
+  uint32_t samplestep;
+  uint32_t samplelength;
+  uint8_t* sample;
+  //uint32_t samplebendcount;
+  //uint32_t samplebendtick;
+
 };
 
 
--- a/POKITTO_LIBS/Synth/Synth_oscfuncs.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_LIBS/Synth/Synth_oscfuncs.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -39,11 +39,12 @@
 /** OSCILLATOR FUNCTIONS **/
 
 void setOSC(OSC* o,byte on=1, byte wave=1, byte loop=0, byte echo=0, byte adsr=0,
-            uint8_t notenumber=25, uint8_t volume=127,
+            uint8_t notenumber=25, uint16_t volume=127,
             uint16_t attack=0, uint16_t decay=0, uint16_t sustain=0, uint16_t release=0,
             int16_t maxbend=0, int16_t bendrate=0, uint8_t arpmode = 0, uint8_t overdrive=0, uint8_t kick=0){
   //Serial.println("SetOsc "); osc1
   o->on = on;
+  o->duration = -1; //max this out for the time being
   o->overdrive = overdrive;
   o->kick = kick;
   o->wave = wave;
@@ -66,12 +67,13 @@
   o->tonic = notenumber; // save tonic for arpeggio use
   if (wave == 2) o->cinc >>= 1; // correct pitch for saw wave
   if (wave == 4) o->cinc <<= 1; // enable higher pitch for pure noise
+  if (wave == 6) o->samplestep = (o->cinc/(cincs[37]>>8));
   o->vol = volume << 8;//volume;
 
   if (adsr) {
     o->attack = attack;
     o->decay = decay;
-    o->sustain = sustain;
+    o->sustain = sustain<<8; //sustain needs to be multiplied by 256 also
     o->release = release;
     o->adsrphase = 1;
     if (!o->attack) o->adsrvol = o->vol; // start directly, no attack ramp
@@ -85,10 +87,15 @@
     o->adsrvol = o->vol; // will stay same all the time
   }
 
+  o->pitchbend = 0; //this has to be zeroed always!
   if (bendrate != 0) {
-        o->bendrate = bendrate; // test value
-        o->pitchbend = 0;
-        o->maxbend = maxbend;
+        o->bendrate = (int32_t)bendrate*(o->cinc/10000); // test value
+        o->maxbend = (int32_t)maxbend*(o->cinc/100);
+        //o->samplebendcount = o->maxbend>>24;
+        //o->samplebendtick = 0;
+  } else {
+        o->bendrate = 0;
+        o->maxbend = 0;
   }
 }
 
--- a/POKITTO_LIBS/Synth/Synth_songfuncs.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_LIBS/Synth/Synth_songfuncs.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -36,6 +36,9 @@
 
 #include "PokittoDisk.h"
 #include "Synth.h"
+#ifdef TRACKER_EXAMPLE
+#include "Tracker.h"
+#endif // TRACKER
 #ifdef POK_SIM
 #include "FileIO.h"
 #endif
@@ -46,9 +49,10 @@
 uint8_t chunk[2][CHUNKSIZE]; // 8 rows, 3 channels (columns), 2 bytes per entry
 uint8_t cc = 0;
 
+streamsFunction streamCallbackPtr;
 
 #if POK_ENABLE_SOUND > 0
-#if POK_ENABLE_SD > 0
+
 void updatePlaybackSD(uint8_t row) {
     // samplespertick determines how long the oscillators are active before they are recalculated (i.e. the next tick
     uint8_t i=0;
@@ -157,7 +161,12 @@
                         }
                     }
                     playerpos = 0;
+                    #ifdef TRACKER_EXAMPLE
+                    tracker.initStreams();
+                    #else
                     initStreams(sequencepos);
+                    #endif // TRACKER_EXAMPLE
+                    //(*streamCallbackPtr)();
                     tableRefresh=true;
             }
             notetick =0;
@@ -222,6 +231,8 @@
     sequencepos = 0;
 }
 
+#if POK_ENABLE_SD > 0
+
 int openSongFromSD(char* buffer) {
     if (!isThisFileOpen(buffer)) {
         fileClose(); // close any open files
@@ -241,7 +252,13 @@
         fileReadBytes(buffer, CHUNKSIZE);
     }
 }
-#endif
+
+#endif // POK_ENABLE_SD
+
+void registerStreamsCallback(streamsFunction ptr) {
+    streamCallbackPtr = ptr;
+}
+
 #endif // POK_ENABLE_SOUND
 
 
--- a/POKITTO_LIBS/Synth/Synth_wavefuncs.cpp	Sat Mar 23 19:22:35 2019 +0000
+++ b/POKITTO_LIBS/Synth/Synth_wavefuncs.cpp	Sat Mar 23 20:03:34 2019 +0000
@@ -42,7 +42,7 @@
 void noADSR(OSC* o); void attackFunc(OSC* o); void decayFunc(OSC* o); void releaseFunc(OSC* o);
 void mix1(); void mix2(); void mix3(); void updateEnvelopes();
 
-waveFunction Farr []  = {waveoff, sqwave, sawwave, triwave, noise, tonenoise};
+waveFunction Farr []  = {waveoff, sqwave, sawwave, triwave, noise, tonenoise, sample};
 envFunction Earr [] = {noADSR, attackFunc, decayFunc, releaseFunc};
 mixFunction Marr [] = {updateEnvelopes,mix3,mix2,mix1}; // counts down
 mixFunction HWMarr [] = {updateEnvelopes,mix3,mix2,mix1}; // counts down
@@ -97,14 +97,15 @@
 }
 
 void sample(OSC* o) {
-
-    /*if (o->samplepos > o->samplelength ) o->samplepos = 0;
-
-    if (o->count > o->wcycle) {
-        o->count=0;
-        if (o->output) o->output = 0;
-        //else o->output = o->output=pgm_read_byte((uint32_t)(sfxBike) + o->inccount);
-    }*/
+    if (sample==NULL) o->output = 0;
+    else {
+          o->samplepos+=o->samplestep;
+          if ((o->samplepos>>8) > o->samplelength ) {
+                o->samplepos = 0;
+                if (o->loop == 0) o->duration=0;
+          }
+          o->output = *(o->sample + (o->samplepos>>8))<<8;
+    }
 }
 
 
--- a/Pokitto_settings.h	Sat Mar 23 19:22:35 2019 +0000
+++ b/Pokitto_settings.h	Sat Mar 23 20:03:34 2019 +0000
@@ -38,7 +38,7 @@
 #ifndef POKITTO_SETTINGS_H
 #define POKITTO_SETTINGS_H
 
-#include "../My_settings.h"
+#include "My_settings.h"
 
 #ifdef PROJ_BOARDREV
  #define POK_BOARDREV PROJ_BOARDREV // which revision of Pokitto board
@@ -76,6 +76,7 @@
     #endif
 #else
     #define POK_GBSOUND PROJ_GBSOUND
+    //#define NUM_CHANNELS 2
 #endif
 
 
@@ -91,6 +92,15 @@
     #define POK_ENABLE_SYNTH PROJ_ENABLE_SYNTH
 #endif // PROJ_ENABLE_SYNTH
 
+#define HIGH_RAM_OFF 0 // SRAM1/SRAM2 are at the default setting
+#define HIGH_RAM_ON  1 // SRAM1/SRAM2 are enabled and free for use
+#define HIGH_RAM_MUSIC 2 // SRAM1/SRAM2 are enabled and used by music
+
+#ifndef PROJ_HIGH_RAM
+#define POK_HIGH_RAM HIGH_RAM_OFF
+#else
+#define POK_HIGH_RAM PROJ_HIGH_RAM
+#endif
 
 /** CONSOLE **/
 #define POK_USE_CONSOLE 0 //if debugging console is available or not
@@ -209,8 +219,6 @@
 #define BUFSIZE_HI_4                9680
 #define MODE_FAST_16COLOR           2   //Size: 4840
 #define BUFSIZE_FAST_16             4840
-#define MODE_HI_16COLOR             3
-#define BUFSIZE_HI_16               19360
 #define MODE_GAMEBUINO_16COLOR      4   //Size: 2016
 #define BUFSIZE_GAMEBUINO_16        2016
 #define MODE_ARDUBOY_16COLOR        5   //Size: 4096
@@ -229,8 +237,14 @@
 #define BUFSIZE_MODE_12              4176 // 72 x 58
 #define MODE13                      13
 #define BUFSIZE_MODE13              9680 // 110*88
+#define MIXMODE                     32
+#define BUFSIZE_MIXMODE             9680 // 110*88
+#define MODE64                      64
+#define BUFSIZE_MODE64              19360 // 110*176
 #define MODE14                      14
 #define BUFSIZE_MODE14              14520
+#define MODE15                      15
+#define BUFSIZE_MODE15              19360
 // Tiled modes
 #define MODE_TILED_1BIT             1001
 #define MODE_TILED_8BIT             1002
@@ -279,7 +293,7 @@
 #endif
 #endif // POK_TILEDMODE
 
-#if PROJ_MODE13 > 0
+#if PROJ_MODE13 > 0 || PROJ_SCREENMODE == 13
     #undef POK_SCREENMODE //get rid of warnings
     #undef POK_COLORDEPTH
     #undef POK_FPS
@@ -289,7 +303,28 @@
     #define POK_FPS 30
 #endif
 
-#if PROJ_MODE14 > 0
+#if PROJ_MIXMODE > 0
+    #undef POK_SCREENMODE //get rid of warnings
+    #undef POK_COLORDEPTH
+    #undef POK_FPS
+    #define POK_SCREENMODE MIXMODE
+    #define POK_COLORDEPTH 8
+    #define POK_STRETCH 0
+    #define POK_FPS 30
+#endif
+
+
+#if PROJ_MODE64 > 0 || PROJ_SCREENMODE == 64
+    #undef POK_SCREENMODE //get rid of warnings
+    #undef POK_COLORDEPTH
+    #undef POK_FPS
+    #define POK_SCREENMODE MODE64
+    #define POK_COLORDEPTH 8
+    #define POK_STRETCH 0
+    #define POK_FPS 30
+#endif
+
+#if PROJ_MODE14 > 0 || PROJ_SCREENMODE == 14
     #undef POK_SCREENMODE //get rid of warnings
     #undef POK_COLORDEPTH
     #undef POK_FPS
@@ -298,7 +333,7 @@
     #define POK_STRETCH 0
     #define POK_FPS 30
 #endif
-#if PROJ_MODE15 > 0
+#if PROJ_MODE15 > 0 || PROJ_SCREENMODE == 15
     #undef POK_SCREENMODE //get rid of warnings
     #undef POK_COLORDEPTH
     #undef POK_FPS
@@ -306,6 +341,7 @@
     #define POK_COLORDEPTH 4
     #define POK_STRETCH 0
     #define POK_FPS 30
+    #define POK_BITFRAME 4840
 #endif
 /* DEFINE SCREENMODE AS THE MAXIMUM SCREEN SIZE NEEDED BY YOUR APP ... SEE SIZES LISTED ABOVE */
 
@@ -325,13 +361,8 @@
     #define LCDWIDTH POK_LCD_W
     #define LCDHEIGHT POK_LCD_H
     #define POK_BITFRAME 4840
-#elif POK_SCREENMODE == MODE_HI_16COLOR
-    #define POK_SCREENBUFFERSIZE POK_LCD_W*POK_LCD_H/2
-    #define LCDWIDTH 220
-    #define LCDHEIGHT 176
-    #define POK_BITFRAME 4840
 #elif POK_SCREENMODE == MODE_HI_4COLOR || POK_SCREENMODE == MODE_HI_GRAYSCALE
-    #define POK_SCREENBUFFERSIZE POK_LCD_W*POK_LCD_H*POK_COLORDEPTH/4
+    #define POK_SCREENBUFFERSIZE (POK_LCD_W*POK_LCD_H*POK_COLORDEPTH/4)
     #define LCDWIDTH POK_LCD_W
     #define LCDHEIGHT POK_LCD_H
     #define POK_BITFRAME 4840
@@ -374,6 +405,16 @@
     #define LCDWIDTH 110
     #define LCDHEIGHT 88
     #define POK_BITFRAME 110*88
+#elif POK_SCREENMODE == MIXMODE
+    #define POK_SCREENBUFFERSIZE 110*88
+    #define LCDWIDTH 110
+    #define LCDHEIGHT 88
+    #define POK_BITFRAME 110*88
+#elif POK_SCREENMODE == MODE64
+    #define POK_SCREENBUFFERSIZE 110*176
+    #define LCDWIDTH 110
+    #define LCDHEIGHT 176
+    #define POK_BITFRAME 110*176
 #elif POK_SCREENMODE == MODE14
     #define POK_SCREENBUFFERSIZE 14520
     #define LCDWIDTH 220
@@ -401,9 +442,16 @@
 #define POK_FRAMEDURATION 1000/POK_FPS
 
 /** SCROLL TEXT VS. WRAP AROUND WHEN PRINTING **/
+#if PROJ_NO_AUTO_SCROLL
+#define SCROLL_TEXT 0
+#else
 #define SCROLL_TEXT 1
+#endif
 
 /** AUDIO **/
+
+#define POK_ALT_MIXING 1 // NEW! alternative more accurate mixing, uses more CPU
+
 #define POK_AUD_PIN P2_19
 #define POK_AUD_PWM_US 15 //31 //Default value 31
 #ifndef PROJ_AUD_FREQ
@@ -481,6 +529,14 @@
 #define EESETTINGS_RTCALARMMODE     4011 // 0xFAB RTC alarm mode (0=disabled, 1=enabled, 3 = enabled with sound)
 #define EESETTINGS_RESERVED         4012 // 0xFAC 4bytes reserved (additional sleep configuration)
 #define EESETTINGS_WAKEUPTIME       4016 // 0xFB0 Wake-up time as 32bit value for 1Hz RTC clock
+#define EESETTINGS_SKIPINTRO	    4020 // 0xFB4 Show Logo (0-Yes, 1-No, 2-Yes then switch to 0, 3-No, then switch to 1)
+
+/** USB SERIAL PORT **/
+
+#ifndef PROJ_VENDOR_ID
+#define POK_VENDOR_ID 0x04D8
+#define POK_PRODUCT_ID 0x000A
+#endif
 
 
 #endif // POKITTO_SETTINGS_H