diff --git a/Marlin/cardreader.h b/Marlin/cardreader.h
index 653f59452e36d652dd8d2b093dd0610d602fdba7..44ebf0e2c1f4a014c62411b562cf6f0414ff9c34 100644
--- a/Marlin/cardreader.h
+++ b/Marlin/cardreader.h
@@ -28,7 +28,8 @@ public:
   
 
   void ls();
-  
+  void chdir(const char * relpath);
+  void updir();
 
   inline bool eof() { return sdpos>=filesize ;};
   inline int16_t get() {  sdpos = file.curPosition();return (int16_t)file.read();};
@@ -40,8 +41,9 @@ public:
   bool sdprinting ;  
   bool cardOK ;
   char filename[11];
+  bool filenameIsDir;
 private:
-  SdFile root,*curDir;
+  SdFile root,*curDir,workDir,workDirParent,workDirParentParent;
   Sd2Card card;
   SdVolume volume;
   SdFile file;
diff --git a/Marlin/cardreader.pde b/Marlin/cardreader.pde
index bab87834ec65d16b893fd6d328260ace383e1865..c0dbc58e475eb5827f3f6c59afd9ceece415bfd1 100644
--- a/Marlin/cardreader.pde
+++ b/Marlin/cardreader.pde
@@ -1,4 +1,5 @@
 #include "cardreader.h"
+//#include <unistd.h>
 #ifdef SDSUPPORT
 
 CardReader::CardReader()
@@ -36,11 +37,7 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
   return buffer;
 }
 
-// bool SdFat::chdir(bool set_cwd) {
-//   if (set_cwd) SdBaseFile::cwd_ = &vwd_;
-//   vwd_.close();
-//   return vwd_.openRoot(&vol_);
-// }
+
 void  CardReader::lsDive(char *prepend,SdFile parent)
 {
   dir_t p;
@@ -85,11 +82,19 @@ void  CardReader::lsDive(char *prepend,SdFile parent)
     {
       if (p.name[0] == DIR_NAME_FREE) break;
       if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue;
+      if ( p.name[0] == '.')
+      {
+        if ( p.name[1] != '.')
+        continue;
+      }
       if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
+      filenameIsDir=DIR_IS_SUBDIR(&p);
       
-      
-      if(p.name[8]!='G') continue;
-      if(p.name[9]=='~') continue;
+      if(!filenameIsDir)
+      {
+        if(p.name[8]!='G') continue;
+        if(p.name[9]=='~') continue;
+      }
       //if(cnt++!=nr) continue;
       createFilename(filename,p);
       if(lsAction==LS_SerialPrint)
@@ -126,33 +131,35 @@ void CardReader::ls()
 void CardReader::initsd()
 {
   cardOK = false;
-  #if SDSS >- 1
-    if(root.isOpen())
-      root.close();
-    if (!card.init(SPI_FULL_SPEED,SDSS))
-    {
-      //if (!card.init(SPI_HALF_SPEED,SDSS))
-      SERIAL_ECHO_START;
-      SERIAL_ECHOLNPGM("SD init fail");
-    }
-    else if (!volume.init(&card))
-    {
-      SERIAL_ERROR_START;
-      SERIAL_ERRORLNPGM("volume.init failed");
-    }
-    else if (!root.openRoot(&volume)) 
-    {
-      SERIAL_ERROR_START;
-      SERIAL_ERRORLNPGM("openRoot failed");
-    }
-    else 
-    {
-      cardOK = true;
-      SERIAL_ECHO_START;
-      SERIAL_ECHOLNPGM("SD card ok");
-    }
-    curDir=&root;
-  #endif //SDSS
+  if(root.isOpen())
+    root.close();
+  if (!card.init(SPI_FULL_SPEED,SDSS))
+  {
+    //if (!card.init(SPI_HALF_SPEED,SDSS))
+    SERIAL_ECHO_START;
+    SERIAL_ECHOLNPGM("SD init fail");
+  }
+  else if (!volume.init(&card))
+  {
+    SERIAL_ERROR_START;
+    SERIAL_ERRORLNPGM("volume.init failed");
+  }
+  else if (!root.openRoot(&volume)) 
+  {
+    SERIAL_ERROR_START;
+    SERIAL_ERRORLNPGM("openRoot failed");
+  }
+  else 
+  {
+    cardOK = true;
+    SERIAL_ECHO_START;
+    SERIAL_ECHOLNPGM("SD card ok");
+  }
+  curDir=&root;
+  if(!workDir.openRoot(&volume))
+  {
+    SERIAL_ECHOLNPGM("workDir open failed");
+  }
 }
 void CardReader::release()
 {
@@ -229,6 +236,10 @@ void CardReader::openFile(char* name,bool read)
       
     }
   }
+  else //relative path
+  {
+    curDir=&workDir;
+  }
   if(read)
   {
     if (file.open(curDir, fname, O_READ)) 
@@ -362,6 +373,7 @@ void CardReader::closefile()
 
 void CardReader::getfilename(const uint8_t nr)
 {
+  curDir=&workDir;
   lsAction=LS_GetFilename;
   nrFiles=nr;
   curDir->rewind();
@@ -371,12 +383,45 @@ void CardReader::getfilename(const uint8_t nr)
 
 uint16_t CardReader::getnrfilenames()
 {
+  curDir=&workDir;
   lsAction=LS_Count;
   nrFiles=0;
   curDir->rewind();
   lsDive("",*curDir);
+  //SERIAL_ECHOLN(nrFiles);
   return nrFiles;
 }
 
+void CardReader::chdir(const char * relpath)
+{
+  SdFile newfile;
+  SdFile *parent=&root;
+  
+  if(workDir.isOpen())
+    parent=&workDir;
+  
+  if(!newfile.open(*parent,relpath, O_READ))
+  {
+   SERIAL_ECHO_START;
+   SERIAL_ECHOPGM("Cannot enter subdir:");
+   SERIAL_ECHOLN(relpath);
+  }
+  else
+  {
+    workDirParentParent=workDirParent;
+    workDirParent=*parent;
+    
+    workDir=newfile;
+  }
+}
+
+void CardReader::updir()
+{
+  if(!workDir.isRoot())
+  {
+    workDir=workDirParent;
+    workDirParent=workDirParentParent;
+  }
+}
 
 #endif //SDSUPPORT
\ No newline at end of file
diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h
index 6bae43dccbbf15eb76a8a57e6787a447ce6be6d2..6222c70c2575c6b926c42eb3307d9da8caee69ab 100644
--- a/Marlin/ultralcd.h
+++ b/Marlin/ultralcd.h
@@ -51,13 +51,13 @@
   #define blocktime 500
   #define lcdslow 5
     
-  enum MainStatus{Main_Status, Main_Menu, Main_Prepare, Main_Control, Main_SD};
+  enum MainStatus{Main_Status, Main_Menu, Main_Prepare, Main_Control, Main_SD,Sub_TempControl,Sub_MotionControl};
 
   class MainMenu{
   public:
     MainMenu();
     void update();
-    uint8_t activeline;
+    int8_t activeline;
     MainStatus status;
     uint8_t displayStartingRow;
     
@@ -65,6 +65,8 @@
     void showMainMenu();
     void showPrepare();
     void showControl();
+    void showControlMotion();
+    void showControlTemp();
     void showSD();
     bool force_lcd_update;
     int lastencoderpos;
@@ -72,6 +74,55 @@
     int8_t lastlineoffset;
     
     bool linechanging;
+    
+  private:
+    inline void updateActiveLines(const uint8_t &maxlines,volatile int &encoderpos)
+    {
+      if(linechanging) return; // an item is changint its value, do not switch lines hence
+      lastlineoffset=lineoffset; 
+      int curencoderpos=encoderpos;  
+      force_lcd_update=false;
+      if(  (abs(curencoderpos-lastencoderpos)<lcdslow) ) 
+      { 
+        lcd.setCursor(0,activeline);lcd.print((activeline+lineoffset)?' ':' '); 
+        if(curencoderpos<0)  
+        {  
+          lineoffset--; 
+          if(lineoffset<0) lineoffset=0; 
+          curencoderpos=lcdslow-1; 
+          force_lcd_update=true; 
+        } 
+        if(curencoderpos>(LCD_HEIGHT-1+1)*lcdslow) 
+        { 
+          lineoffset++; 
+          curencoderpos=(LCD_HEIGHT-1)*lcdslow; 
+          if(lineoffset>(maxlines+1-LCD_HEIGHT)) 
+            lineoffset=maxlines+1-LCD_HEIGHT; 
+          if(curencoderpos>maxlines*lcdslow) 
+            curencoderpos=maxlines*lcdslow; 
+          force_lcd_update=true; 
+        } 
+        lastencoderpos=encoderpos=curencoderpos; 
+        activeline=curencoderpos/lcdslow;
+        if(activeline<0) activeline=0;
+        if(activeline>LCD_HEIGHT-1) activeline=LCD_HEIGHT-1;
+        if(activeline>maxlines) 
+        {
+          activeline=maxlines;
+          curencoderpos=maxlines*lcdslow;
+        }
+        lcd.setCursor(0,activeline);lcd.print((activeline+lineoffset)?'>':'\003');    
+      } 
+    }
+    
+    inline void clearIfNecessary()
+    {
+      if(lastlineoffset!=lineoffset ||force_lcd_update)
+      {
+        force_lcd_update=true;
+         lcd.clear();
+      } 
+    }
   };
 
   //conversion routines, could need some overworking
diff --git a/Marlin/ultralcd.pde b/Marlin/ultralcd.pde
index c4ea234883d062b222bf0ddc8f2eee3a6c05c2f3..57f63c1061de041035fc67b25fe628d9e089c01d 100644
--- a/Marlin/ultralcd.pde
+++ b/Marlin/ultralcd.pde
@@ -114,11 +114,13 @@ void lcd_init()
   };
   byte uplevel[8]={0x04, 0x0e, 0x1f, 0x04, 0x1c, 0x00, 0x00, 0x00};//thanks joris
   byte refresh[8]={0x00, 0x06, 0x19, 0x18, 0x03, 0x13, 0x0c, 0x00}; //thanks joris
+  byte folder [8]={0x00, 0x1c, 0x1f, 0x11, 0x11, 0x1f, 0x00, 0x00}; //thanks joris
   lcd.begin(LCD_WIDTH, LCD_HEIGHT);
   lcd.createChar(1,Degree);
   lcd.createChar(2,Thermometer);
   lcd.createChar(3,uplevel);
   lcd.createChar(4,refresh);
+  lcd.createChar(5,folder);
   LCD_MESSAGEPGM("UltiMarlin ready.");
 }
 
@@ -224,6 +226,7 @@ void buttons_check()
     buttons=~newbutton; //invert it, because a pressed switch produces a logical 0
   #endif
   
+  //manage encoder rotation
   char enc=0;
   if(buttons&EN_A)
     enc|=(1<<0);
@@ -279,7 +282,6 @@ MainMenu::MainMenu()
   linechanging=false;
 }
 
-
 void MainMenu::showStatus()
 { 
 #if LCD_HEIGHT==4
@@ -312,22 +314,22 @@ void MainMenu::showStatus()
     oldtargetHotEnd0=ttHotEnd0;
   }
   #if defined BED_USES_THERMISTOR || defined BED_USES_AD595 
-  static int oldtBed=-1;
-  static int oldtargetBed=-1; 
-  int tBed=intround(degBed());
-  if((tBed!=oldtBed)||force_lcd_update)
-  {
-    lcd.setCursor(1,0);
-    lcd.print(ftostr3(tBed));
-    olddegHotEnd0=tBed;
-  }
-  int targetBed=intround(degTargetBed());
-  if((targetBed!=oldtargetBed)||force_lcd_update)
-  {
-    lcd.setCursor(5,0);
-    lcd.print(ftostr3(targetBed));
-    oldtargetBed=targetBed;
-  }
+    static int oldtBed=-1;
+    static int oldtargetBed=-1; 
+    int tBed=intround(degBed());
+    if((tBed!=oldtBed)||force_lcd_update)
+    {
+      lcd.setCursor(1,0);
+      lcd.print(ftostr3(tBed));
+      oldtBed=tBed;
+    }
+    int targetBed=intround(degTargetBed());
+    if((targetBed!=oldtargetBed)||force_lcd_update)
+    {
+      lcd.setCursor(5,0);
+      lcd.print(ftostr3(targetBed));
+      oldtargetBed=targetBed;
+    }
   #endif
   //starttime=2;
   static uint16_t oldtime=0;
@@ -422,173 +424,88 @@ void MainMenu::showStatus()
   }
 
 #endif
+  force_lcd_update=false;
 }
 
 enum {ItemP_exit, ItemP_home, ItemP_origin, ItemP_preheat, ItemP_extrude, ItemP_disstep};
 
+//any action must not contain a ',' character anywhere, or this breaks:
+#define MENUITEM(repaint_action, click_action) \
+  {\
+    if(force_lcd_update)  { lcd.setCursor(0,line);  repaint_action; } \
+    if((activeline==line) && CLICKED) {click_action} \
+  }
+  
 void MainMenu::showPrepare()
 {
  uint8_t line=0;
- if(lastlineoffset!=lineoffset)
- {
-   force_lcd_update=true;
-   clear(); 
- }
+ clearIfNecessary();
  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
  {
    //Serial.println((int)(line-lineoffset));
   switch(i)
   {
     case ItemP_exit:
-      {
-        if(force_lcd_update)
-        {
-          lcd.setCursor(0,line);lcdprintPGM(" Prepare");
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK
-          status=Main_Menu;
-          beepshort();
-        }
-      }break;
+      MENUITEM(  lcdprintPGM(" Prepare")  ,  BLOCK;status=Main_Menu;beepshort(); ) ;
+      break;
     case ItemP_home:
-      {
-        if(force_lcd_update)
-        {
-          lcd.setCursor(0,line);lcdprintPGM(" Auto Home");
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK
-          enquecommand("G28 X-105 Y-105 Z0");
-          beepshort();
-        }
-      }break;
+      MENUITEM(  lcdprintPGM(" Auto Home")  ,  BLOCK;enquecommand("G28 X-105 Y-105 Z0");beepshort(); ) ;
+      break;
     case ItemP_origin:
-      {
-        if(force_lcd_update)
-        {
-          lcd.setCursor(0,line);lcdprintPGM(" Set Origin");
-          
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK
-          enquecommand("G92 X0 Y0 Z0");
-          beepshort();
-        }
-      }break;
+      MENUITEM(  lcdprintPGM(" Set Origin")  ,  BLOCK;enquecommand("G92 X0 Y0 Z0");beepshort(); ) ;
+      break;
     case ItemP_preheat:
-      {
-        if(force_lcd_update)
-        {
-          lcd.setCursor(0,line);lcdprintPGM(" Preheat"); 
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK
-          setTargetHotend0(170);
-          beepshort();
-        }
-      }break;
+      MENUITEM(  lcdprintPGM(" Preheat")  ,  BLOCK;setTargetHotend0(170);beepshort(); ) ;
+      break;
     case ItemP_extrude:
-      {
-        if(force_lcd_update)
-        {
-          lcd.setCursor(0,line);lcdprintPGM(" Extrude");
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK
-          enquecommand("G92 E0");
-          enquecommand("G1 F700 E50");
-          beepshort();
-        }
-      }break;
+      MENUITEM(  lcdprintPGM(" Extrude")  ,  BLOCK;enquecommand("G92 E0");enquecommand("G1 F700 E50");beepshort(); ) ;
+      break;
     case ItemP_disstep:
-      {
-        if(force_lcd_update)
-        {
-          lcd.setCursor(0,line);lcdprintPGM(" Disable Steppers");
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK
-          enquecommand("M84");
-          beepshort();
-        }
-      }break;
+      MENUITEM(  lcdprintPGM(" Disable Steppers")  ,  BLOCK;enquecommand("M84");beepshort(); ) ;
+      break;
     default:   
       break;
   }
   line++;
  }
- lastlineoffset=lineoffset;
- if((encoderpos/lcdslow!=lastencoderpos/lcdslow)||force_lcd_update)
- {
-   
-    lcd.setCursor(0,activeline);lcd.print((activeline+lineoffset)?' ':' ');
-    
-    if(encoderpos<0)
-    {
-     lineoffset--;
-     if(lineoffset<0)
-       lineoffset=0;
-     encoderpos=0;
-     force_lcd_update=true;
-    }
-    if(encoderpos/lcdslow>3)
-    {
-     lineoffset++;
-     encoderpos=3*lcdslow;
-     if(lineoffset>(ItemP_disstep+1-LCD_HEIGHT))
-       lineoffset=ItemP_disstep+1-LCD_HEIGHT;
-     force_lcd_update=true;
-    }
-    //encoderpos=encoderpos%LCD_HEIGHT;
-    lastencoderpos=encoderpos;
-    activeline=encoderpos/lcdslow;
-    lcd.setCursor(0,activeline);lcd.print((activeline+lineoffset)?'>':'\003');   
-  } 
+ updateActiveLines(ItemP_disstep,encoderpos);
 }
+
+
+//does not work
+// #define MENUCHANGEITEM(repaint_action,  enter_action, accept_action,  change_action) \
+//   {\
+//     if(force_lcd_update)  { lcd.setCursor(0,line);  repaint_action; } \
+//     if(activeline==line)  \
+//     { \
+//       if(CLICKED) \
+//       { \
+//         linechanging=!linechanging; \
+//         if(linechanging)  {enter_action;} \
+//         else {accept_action;} \
+//       }  \
+//       else \
+//       if(linechanging) {change_action};}\
+//   }
+//   
+
 enum {
-  ItemC_exit, ItemC_nozzle, 
-  ItemC_PID_P,ItemC_PID_I,ItemC_PID_D,ItemC_PID_C,
-  ItemC_fan, 
-  ItemC_acc, ItemC_xyjerk, 
-  ItemC_vmaxx, ItemC_vmaxy, ItemC_vmaxz, ItemC_vmaxe, 
-  ItemC_vtravmin,ItemC_vmin,  
-  ItemC_amaxx, ItemC_amaxy, ItemC_amaxz, ItemC_amaxe, 
-  ItemC_aret,ItemC_esteps, ItemC_store, ItemC_load,ItemC_failsafe
+  ItemCT_exit, ItemCT_nozzle, ItemCT_fan,
+  ItemCT_PID_P,ItemCT_PID_I,ItemCT_PID_D,ItemCT_PID_C
 };
 
-void MainMenu::showControl()
+void MainMenu::showControlTemp()
 {
- uint8_t line=0;
- if((lastlineoffset!=lineoffset)||force_lcd_update)
- {
-   force_lcd_update=true;
-   clear();
- }
+  uint8_t line=0;
+ clearIfNecessary();
  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
  {
   switch(i)
   {
-    case ItemC_exit:
-      {
-        if(force_lcd_update)
-        {
-          lcd.setCursor(0,line);lcdprintPGM(" Control");
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK
-          status=Main_Menu;
-          beepshort();
-        }
-      }break;
-    case ItemC_nozzle:
+    case ItemCT_exit:
+      MENUITEM(  lcdprintPGM(" Temperature")  ,  BLOCK;status=Main_Control;beepshort(); ) ;
+      break;
+    case ItemCT_nozzle:
       {
         if(force_lcd_update)
         {
@@ -622,7 +539,7 @@ void MainMenu::showControl()
         }
       }break;
       
-      case ItemC_fan:
+      case ItemCT_fan:
       {
         if(force_lcd_update)
         {
@@ -659,12 +576,12 @@ void MainMenu::showControl()
           }
         }
       }break;
-    case ItemC_acc:
-    {
+      case ItemCT_PID_P: 
+      {
       if(force_lcd_update)
         {
-          lcd.setCursor(0,line);lcdprintPGM(" Acc:");
-          lcd.setCursor(13,line);lcd.print(itostr3(acceleration/100));lcdprintPGM("00");
+          lcd.setCursor(0,line);lcdprintPGM(" PID-P: ");
+          lcd.setCursor(13,line);lcd.print(itostr4(Kp));
         }
         
         if((activeline==line) )
@@ -674,30 +591,31 @@ void MainMenu::showControl()
             linechanging=!linechanging;
             if(linechanging)
             {
-               encoderpos=(int)acceleration/100;
+               encoderpos=(int)Kp/5;
             }
             else
             {
-              acceleration= encoderpos*100;
+              Kp= encoderpos*5;
               encoderpos=activeline*lcdslow;
+                
             }
             BLOCK;
             beepshort();
           }
           if(linechanging)
           {
-            if(encoderpos<5) encoderpos=5;
-            if(encoderpos>990) encoderpos=990;
-            lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");
+            if(encoderpos<1) encoderpos=1;
+            if(encoderpos>9990/5) encoderpos=9990/5;
+            lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));
           }
         }
       }break;
-    case ItemC_xyjerk: //max_xy_jerk
+    case ItemCT_PID_I: 
       {
       if(force_lcd_update)
         {
-          lcd.setCursor(0,line);lcdprintPGM(" Vxy-jerk: ");
-          lcd.setCursor(13,line);lcd.print(itostr3(max_xy_jerk));
+          lcd.setCursor(0,line);lcdprintPGM(" PID-I: ");
+          lcd.setCursor(13,line);lcd.print(ftostr51(Ki));
         }
         
         if((activeline==line) )
@@ -707,11 +625,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;
             if(linechanging)
             {
-               encoderpos=(int)max_xy_jerk;
+               encoderpos=(int)(Ki*10);
             }
             else
             {
-              max_xy_jerk= encoderpos;
+              Ki= encoderpos/10.;
               encoderpos=activeline*lcdslow;
                 
             }
@@ -720,18 +638,18 @@ void MainMenu::showControl()
           }
           if(linechanging)
           {
-            if(encoderpos<1) encoderpos=1;
-            if(encoderpos>990) encoderpos=990;
-            lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
+            if(encoderpos<0) encoderpos=0;
+            if(encoderpos>9990) encoderpos=9990;
+            lcd.setCursor(13,line);lcd.print(ftostr51(encoderpos/10.));
           }
         }
       }break;
-      case ItemC_PID_P: 
+      case ItemCT_PID_D: 
       {
       if(force_lcd_update)
         {
-          lcd.setCursor(0,line);lcdprintPGM(" PID-P: ");
-          lcd.setCursor(13,line);lcd.print(itostr4(Kp));
+          lcd.setCursor(0,line);lcdprintPGM(" PID-D: ");
+          lcd.setCursor(13,line);lcd.print(itostr4(Kd));
         }
         
         if((activeline==line) )
@@ -741,11 +659,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;
             if(linechanging)
             {
-               encoderpos=(int)Kp/5;
+               encoderpos=(int)Kd/5;
             }
             else
             {
-              Kp= encoderpos*5;
+              Kd= encoderpos*5;
               encoderpos=activeline*lcdslow;
                 
             }
@@ -754,18 +672,19 @@ void MainMenu::showControl()
           }
           if(linechanging)
           {
-            if(encoderpos<1) encoderpos=1;
+            if(encoderpos<0) encoderpos=0;
             if(encoderpos>9990/5) encoderpos=9990/5;
             lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));
           }
         }
-      }break;
-    case ItemC_PID_I: 
+      }break;   
+    case ItemCT_PID_C: 
+      #ifdef PID_ADD_EXTRUSION_RATE
       {
       if(force_lcd_update)
         {
-          lcd.setCursor(0,line);lcdprintPGM(" PID-I: ");
-          lcd.setCursor(13,line);lcd.print(ftostr51(Ki));
+          lcd.setCursor(0,line);lcdprintPGM(" PID-C: ");
+          lcd.setCursor(13,line);lcd.print(itostr3(Kc));
         }
         
         if((activeline==line) )
@@ -775,11 +694,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;
             if(linechanging)
             {
-               encoderpos=(int)(Ki*10);
+               encoderpos=(int)Kc;
             }
             else
             {
-              Ki= encoderpos/10.;
+              Kc= encoderpos;
               encoderpos=activeline*lcdslow;
                 
             }
@@ -789,17 +708,54 @@ void MainMenu::showControl()
           if(linechanging)
           {
             if(encoderpos<0) encoderpos=0;
-            if(encoderpos>9990) encoderpos=9990;
-            lcd.setCursor(13,line);lcd.print(ftostr51(encoderpos/10.));
+            if(encoderpos>990) encoderpos=990;
+            lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
           }
         }
-      }break;
-      case ItemC_PID_D: 
-      {
+      }
+      #endif
+      break;
+    default:   
+      break;
+  }
+  line++;
+ }
+ #ifdef PID_ADD_EXTRUSION_RATE
+  updateActiveLines(ItemCT_PID_C,encoderpos);
+ #else
+  updateActiveLines(ItemCT_PID_D,encoderpos);
+ #endif
+}
+
+
+enum {
+  ItemCM_exit, 
+  ItemCM_acc, ItemCM_xyjerk, 
+  ItemCM_vmaxx, ItemCM_vmaxy, ItemCM_vmaxz, ItemCM_vmaxe, 
+  ItemCM_vtravmin,ItemCM_vmin,  
+  ItemCM_amaxx, ItemCM_amaxy, ItemCM_amaxz, ItemCM_amaxe, 
+  ItemCM_aret,ItemCM_esteps
+};
+
+
+
+void MainMenu::showControlMotion()
+{
+ uint8_t line=0;
+ clearIfNecessary();
+ for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
+ {
+  switch(i)
+  {
+    case ItemCM_exit:
+      MENUITEM(  lcdprintPGM(" Motion")  ,  BLOCK;status=Main_Control;beepshort(); ) ;
+      break;
+    case ItemCM_acc:
+    {
       if(force_lcd_update)
         {
-          lcd.setCursor(0,line);lcdprintPGM(" PID-D: ");
-          lcd.setCursor(13,line);lcd.print(itostr4(Kd));
+          lcd.setCursor(0,line);lcdprintPGM(" Acc:");
+          lcd.setCursor(13,line);lcd.print(itostr3(acceleration/100));lcdprintPGM("00");
         }
         
         if((activeline==line) )
@@ -809,34 +765,30 @@ void MainMenu::showControl()
             linechanging=!linechanging;
             if(linechanging)
             {
-               encoderpos=(int)Kd/5;
+               encoderpos=(int)acceleration/100;
             }
             else
             {
-              Kd= encoderpos*5;
+              acceleration= encoderpos*100;
               encoderpos=activeline*lcdslow;
-                
             }
             BLOCK;
             beepshort();
           }
           if(linechanging)
           {
-            if(encoderpos<0) encoderpos=0;
-            if(encoderpos>9990/5) encoderpos=9990/5;
-            lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));
+            if(encoderpos<5) encoderpos=5;
+            if(encoderpos>990) encoderpos=990;
+            lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");
           }
         }
       }break;
-    
-    
-      
-    case ItemC_PID_C: 
+    case ItemCM_xyjerk: //max_xy_jerk
       {
       if(force_lcd_update)
         {
-          lcd.setCursor(0,line);lcdprintPGM(" PID-C: ");
-          lcd.setCursor(13,line);lcd.print(itostr3(Kc));
+          lcd.setCursor(0,line);lcdprintPGM(" Vxy-jerk: ");
+          lcd.setCursor(13,line);lcd.print(itostr3(max_xy_jerk));
         }
         
         if((activeline==line) )
@@ -846,11 +798,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;
             if(linechanging)
             {
-               encoderpos=(int)Kc;
+               encoderpos=(int)max_xy_jerk;
             }
             else
             {
-              Kc= encoderpos;
+              max_xy_jerk= encoderpos;
               encoderpos=activeline*lcdslow;
                 
             }
@@ -859,25 +811,26 @@ void MainMenu::showControl()
           }
           if(linechanging)
           {
-            if(encoderpos<0) encoderpos=0;
+            if(encoderpos<1) encoderpos=1;
             if(encoderpos>990) encoderpos=990;
             lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
           }
         }
       }break;
-    case ItemC_vmaxx:
-    case ItemC_vmaxy:
-    case ItemC_vmaxz:
-    case ItemC_vmaxe:
+      
+    case ItemCM_vmaxx:
+    case ItemCM_vmaxy:
+    case ItemCM_vmaxz:
+    case ItemCM_vmaxe:
       {
       if(force_lcd_update)
         {
           lcd.setCursor(0,line);lcdprintPGM(" Vmax ");
-          if(i==ItemC_vmaxx)lcdprintPGM("x:");
-          if(i==ItemC_vmaxy)lcdprintPGM("y:");
-          if(i==ItemC_vmaxz)lcdprintPGM("z:");
-          if(i==ItemC_vmaxe)lcdprintPGM("e:");
-          lcd.setCursor(13,line);lcd.print(itostr3(max_feedrate[i-ItemC_vmaxx]));
+          if(i==ItemCM_vmaxx)lcdprintPGM("x:");
+          if(i==ItemCM_vmaxy)lcdprintPGM("y:");
+          if(i==ItemCM_vmaxz)lcdprintPGM("z:");
+          if(i==ItemCM_vmaxe)lcdprintPGM("e:");
+          lcd.setCursor(13,line);lcd.print(itostr3(max_feedrate[i-ItemCM_vmaxx]));
         }
         
         if((activeline==line) )
@@ -887,11 +840,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;
             if(linechanging)
             {
-               encoderpos=(int)max_feedrate[i-ItemC_vmaxx];
+               encoderpos=(int)max_feedrate[i-ItemCM_vmaxx];
             }
             else
             {
-              max_feedrate[i-ItemC_vmaxx]= encoderpos;
+              max_feedrate[i-ItemCM_vmaxx]= encoderpos;
               encoderpos=activeline*lcdslow;
                 
             }
@@ -907,7 +860,7 @@ void MainMenu::showControl()
         }
       }break;
     
-    case ItemC_vmin:
+    case ItemCM_vmin:
     {
       if(force_lcd_update)
         {
@@ -941,7 +894,7 @@ void MainMenu::showControl()
           }
         }
       }break;
-    case ItemC_vtravmin:
+    case ItemCM_vtravmin:
     {
       if(force_lcd_update)
         {
@@ -976,19 +929,19 @@ void MainMenu::showControl()
         }
       }break;
     
-    case ItemC_amaxx:      
-    case ItemC_amaxy:
-    case ItemC_amaxz:
-    case ItemC_amaxe:
+    case ItemCM_amaxx:      
+    case ItemCM_amaxy:
+    case ItemCM_amaxz:
+    case ItemCM_amaxe:
     {
       if(force_lcd_update)
         {
           lcd.setCursor(0,line);lcdprintPGM(" Amax ");
-          if(i==ItemC_amaxx)lcdprintPGM("x:");
-          if(i==ItemC_amaxy)lcdprintPGM("y:");
-          if(i==ItemC_amaxz)lcdprintPGM("z:");
-          if(i==ItemC_amaxe)lcdprintPGM("e:");
-          lcd.setCursor(13,line);lcd.print(itostr3(max_acceleration_units_per_sq_second[i-ItemC_amaxx]/100));lcdprintPGM("00");
+          if(i==ItemCM_amaxx)lcdprintPGM("x:");
+          if(i==ItemCM_amaxy)lcdprintPGM("y:");
+          if(i==ItemCM_amaxz)lcdprintPGM("z:");
+          if(i==ItemCM_amaxe)lcdprintPGM("e:");
+          lcd.setCursor(13,line);lcd.print(itostr3(max_acceleration_units_per_sq_second[i-ItemCM_amaxx]/100));lcdprintPGM("00");
         }
         
         if((activeline==line) )
@@ -998,11 +951,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;
             if(linechanging)
             {
-               encoderpos=(int)max_acceleration_units_per_sq_second[i-ItemC_amaxx]/100;
+               encoderpos=(int)max_acceleration_units_per_sq_second[i-ItemCM_amaxx]/100;
             }
             else
             {
-              max_acceleration_units_per_sq_second[i-ItemC_amaxx]= encoderpos*100;
+              max_acceleration_units_per_sq_second[i-ItemCM_amaxx]= encoderpos*100;
               encoderpos=activeline*lcdslow;
             }
             BLOCK;
@@ -1016,7 +969,7 @@ void MainMenu::showControl()
           }
         }
       }break;
-    case ItemC_aret://float retract_acceleration = 7000;
+    case ItemCM_aret://float retract_acceleration = 7000;
     {
         if(force_lcd_update)
         {
@@ -1050,7 +1003,7 @@ void MainMenu::showControl()
           }
         }
       }break;
-    case ItemC_esteps://axis_steps_per_unit[i] = code_value();
+    case ItemCM_esteps://axis_steps_per_unit[i] = code_value();
          {
       if(force_lcd_update)
         {
@@ -1087,6 +1040,37 @@ void MainMenu::showControl()
           }
         }
       }break; 
+    default:   
+      break;
+  }
+  line++;
+ }
+ updateActiveLines(ItemCM_esteps,encoderpos);
+}
+
+
+enum {
+  ItemC_exit,ItemC_temp,ItemC_move,
+  ItemC_store, ItemC_load,ItemC_failsafe
+};
+
+void MainMenu::showControl()
+{
+ uint8_t line=0;
+ clearIfNecessary();
+ for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
+ {
+  switch(i)
+  {
+    case ItemC_exit:
+      MENUITEM(  lcdprintPGM(" Control     \x7E")  ,  BLOCK;status=Main_Menu;beepshort(); ) ;
+      break;
+    case ItemC_temp:
+      MENUITEM(  lcdprintPGM(" Temperature \x7E")  ,  BLOCK;status=Sub_TempControl;beepshort(); ) ;
+      break;
+   case ItemC_move:
+      MENUITEM(  lcdprintPGM(" Motion      \x7E")  ,  BLOCK;status=Sub_MotionControl;beepshort(); ) ;
+      break;
     case ItemC_store:
     {
       if(force_lcd_update)
@@ -1134,55 +1118,22 @@ void MainMenu::showControl()
   }
   line++;
  }
- lastlineoffset=lineoffset;
-
- if(!linechanging &&  ((encoderpos/lcdslow!=lastencoderpos/lcdslow)||force_lcd_update))
- {
-   
-    lcd.setCursor(0,activeline);lcd.print((activeline+lineoffset)?' ':' ');
-    
-    if(encoderpos<0)
-    {
-     lineoffset--;
-     if(lineoffset<0)
-       lineoffset=0;
-     encoderpos=0;
-     force_lcd_update=true;
-    }
-    if(encoderpos/lcdslow>3)
-    {
-     lineoffset++;
-     encoderpos=3*lcdslow;
-     if(lineoffset>(ItemC_failsafe+1-LCD_HEIGHT))
-       lineoffset=ItemC_failsafe+1-LCD_HEIGHT;
-     force_lcd_update=true;
-    }
-    //encoderpos=encoderpos%LCD_HEIGHT;
-    lastencoderpos=encoderpos;
-    activeline=encoderpos/lcdslow;
-    if(activeline>3) activeline=3;
-    lcd.setCursor(0,activeline);lcd.print((activeline+lineoffset)?'>':'\003');   
-  } 
+ updateActiveLines(ItemC_failsafe,encoderpos);
 }
 
 
 
 
 
-
 void MainMenu::showSD()
 {
 #ifdef SDSUPPORT
  uint8_t line=0;
 
- if(lastlineoffset!=lineoffset)
- {
-   force_lcd_update=true; 
- }
+ clearIfNecessary();
  static uint8_t nrfiles=0;
  if(force_lcd_update)
  {
-   clear();
   if(card.cardOK)
   {
     nrfiles=card.getnrfilenames();
@@ -1192,78 +1143,85 @@ void MainMenu::showSD()
     nrfiles=0;
     lineoffset=0;
   }
-  //Serial.print("Nr files:"); Serial.println((int)nrfiles);
  }
- 
+ bool enforceupdate=false;
  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
  {
   switch(i)
   {
     case 0:
+      MENUITEM(  lcdprintPGM(" File")  ,  BLOCK;status=Main_Menu;beepshort(); ) ;
+      break;
+//     case 1:
+//       {
+//         if(force_lcd_update)
+//         {
+//           lcd.setCursor(0,line);
+//            #ifdef CARDINSERTED
+//           if(CARDINSERTED)
+//           #else
+//           if(true)
+//           #endif
+//           {
+//             lcdprintPGM(" \004Refresh");
+//           }
+//           else
+//           {
+//             lcdprintPGM(" \004Insert Card");
+//           }
+//           
+//         }
+//         if((activeline==line) && CLICKED)
+//         {
+//           BLOCK;
+//           beepshort();
+//           card.initsd();
+//           force_lcd_update=true;
+//            nrfiles=card.getnrfilenames();
+//         }
+//       }break;
+    case 1:
+      MENUITEM(  lcdprintPGM(" ..")  ,  BLOCK;card.updir();enforceupdate=true;lineoffset=0;beepshort(); ) ;
+      
+      break;
+    default:
+    {
+      #define FIRSTITEM 2
+      if(i-FIRSTITEM<nrfiles)
       {
         if(force_lcd_update)
         {
-          lcd.setCursor(0,line);lcdprintPGM(" File");
+          card.getfilename(i-FIRSTITEM);
+          //Serial.print("Filenr:");Serial.println(i-2);
+          lcd.setCursor(0,line);lcdprintPGM(" ");
+          if(card.filenameIsDir) lcd.print("\005");
+          lcd.print(card.filename);
         }
         if((activeline==line) && CLICKED)
         {
           BLOCK
-          status=Main_Menu;
-          beepshort();
-        }
-      }break;
-    case 1:
-      {
-        if(force_lcd_update)
-        {
-          lcd.setCursor(0,line);
-           #ifdef CARDINSERTED
-          if(CARDINSERTED)
-          #else
-          if(true)
-          #endif
+          card.getfilename(i-FIRSTITEM);
+          if(card.filenameIsDir)
           {
-            lcdprintPGM(" \004Refresh");
+            for(int8_t i=0;i<strlen(card.filename);i++)
+              card.filename[i]=tolower(card.filename[i]);
+            card.chdir(card.filename);
+            lineoffset=0;
+            enforceupdate=true;
           }
           else
           {
-            lcdprintPGM(" \004Insert Card");
+            char cmd[30];
+            for(int8_t i=0;i<strlen(card.filename);i++)
+              card.filename[i]=tolower(card.filename[i]);
+            sprintf(cmd,"M23 %s",card.filename);
+            //sprintf(cmd,"M115");
+            enquecommand(cmd);
+            enquecommand("M24");
+            beep(); 
+            status=Main_Status;
+            lcd_status(card.filename);
           }
-          
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK;
-          beepshort();
-          card.initsd();
-          force_lcd_update=true;
-           nrfiles=card.getnrfilenames();
-        }
-      }break;
-    default:
-    {
-      if(i-2<nrfiles)
-      {
-        if(force_lcd_update)
-        {
-          card.getfilename(i-2);
-          //Serial.print("Filenr:");Serial.println(i-2);
-          lcd.setCursor(0,line);lcdprintPGM(" ");lcd.print(card.filename);
-        }
-        if((activeline==line) && CLICKED)
-        {
-          BLOCK
-          card.getfilename(i-2);
-          char cmd[30];
-          for(int8_t i=0;i<strlen(card.filename);i++)
-            card.filename[i]=tolower(card.filename[i]);
-          sprintf(cmd,"M23 %s",card.filename);
-          //sprintf(cmd,"M115");
-          enquecommand(cmd);
-          enquecommand("M24");
-          beep(); 
-          status=Main_Status;
-          lcd_status(card.filename);
         }
       }
       
@@ -1272,93 +1230,38 @@ void MainMenu::showSD()
   }
   line++;
  }
- lastlineoffset=lineoffset;
- if((encoderpos!=lastencoderpos)||force_lcd_update)
+ updateActiveLines(FIRSTITEM+nrfiles-1,encoderpos);
+ if(enforceupdate)
  {
-   
-    lcd.setCursor(0,activeline);lcd.print((activeline+lineoffset)?' ':' ');
-    
-    if(encoderpos<0)
-    {
-     lineoffset--;
-     if(lineoffset<0)
-       lineoffset=0;
-     encoderpos=0;
-     force_lcd_update=true;
-    }
-    if(encoderpos/lcdslow>3)
-    {
-     lineoffset++;
-     encoderpos=3*lcdslow;
-     if(lineoffset>(1+nrfiles+1-LCD_HEIGHT))
-       lineoffset=1+nrfiles+1-LCD_HEIGHT;
-     force_lcd_update=true;
-     
-    }
-    lastencoderpos=encoderpos;
-    activeline=encoderpos;
-    if(activeline>3) 
-    {
-      activeline=3;
-    }
-    if(activeline<0) 
-    {
-      activeline=0;
-    }
-    if(activeline>1+nrfiles) activeline=1+nrfiles;
-    if(lineoffset>1+nrfiles) lineoffset=1+nrfiles;
-    lcd.setCursor(0,activeline);lcd.print((activeline+lineoffset)?'>':'\003');   
-    
-  }
+   force_lcd_update=true;
+   enforceupdate=false;
+ }
 #endif
 }
 
 enum {ItemM_watch, ItemM_prepare, ItemM_control, ItemM_file };
 void MainMenu::showMainMenu()
 {
-   //if(int(encoderpos/lcdslow)!=int(lastencoderpos/lcdslow))
-   //  force_lcd_update=true;
+
   #ifndef ULTIPANEL
     force_lcd_update=false;
   #endif
-   //Serial.println((int)activeline);
-   if(force_lcd_update)
-     clear();
+   
+  clearIfNecessary();
   for(int8_t line=0;line<LCD_HEIGHT;line++)
   {
     switch(line)
     { 
       case ItemM_watch:
-      {
-        if(force_lcd_update) {lcd.setCursor(0,line);lcdprintPGM(" Watch   \x7E");}
-        if((activeline==line)&&CLICKED)
-        {
-          BLOCK;
-          beepshort();
-          status=Main_Status;
-        }
-      } break;
+        MENUITEM(  lcdprintPGM(" Watch")  ,  BLOCK;status=Main_Status;beepshort(); ) ;
+       break;
       case ItemM_prepare:
-      {
-        if(force_lcd_update) {lcd.setCursor(0,line);lcdprintPGM(" Prepare \x7E");}
-        if((activeline==line)&&CLICKED)
-        {
-          BLOCK;
-          status=Main_Prepare;
-          beepshort();
-        }
-      } break;
+        MENUITEM(  lcdprintPGM(" Prepare \x7E")  ,  BLOCK;status=Main_Prepare;beepshort(); ) ;
+      break;
        
       case ItemM_control:
-      {
-        if(force_lcd_update) {lcd.setCursor(0,line);lcdprintPGM(" Control \x7E");}
-        if((activeline==line)&&CLICKED)
-        {
-          BLOCK;
-          status=Main_Control;
-          beepshort();
-        }
-      }break;
+        MENUITEM(  lcdprintPGM(" Control \x7E")  ,  BLOCK;status=Main_Control;beepshort(); ) ;
+      break;
       #ifdef SDSUPPORT
       case ItemM_file:    
       {
@@ -1392,6 +1295,9 @@ void MainMenu::showMainMenu()
           beepshort();
         }
       }break;
+      #else
+      case ItemM_file:
+        break;
       #endif
       default: 
         SERIAL_ERROR_START;
@@ -1399,24 +1305,7 @@ void MainMenu::showMainMenu()
       break;
     }
   }
-  if(activeline<0) 
-    activeline=0;
-  if(activeline>=LCD_HEIGHT) 
-    activeline=LCD_HEIGHT-1;
-  if((encoderpos!=lastencoderpos)||force_lcd_update)
-  {
-    lcd.setCursor(0,activeline);lcd.print(activeline?' ':' ');
-    if(encoderpos<0) encoderpos=0;
-    if(encoderpos>3*lcdslow) 
-      encoderpos=3*lcdslow;
-    activeline=abs(encoderpos/lcdslow)%LCD_HEIGHT;
-    if(activeline<0) 
-      activeline=0;
-    if(activeline>=LCD_HEIGHT) 
-      activeline=LCD_HEIGHT-1;
-    lastencoderpos=encoderpos;
-    lcd.setCursor(0,activeline);lcd.print(activeline?'>':'\003');
-  }
+  updateActiveLines(3,encoderpos);
 }
 
 void MainMenu::update()
@@ -1433,20 +1322,18 @@ void MainMenu::update()
       if(CARDINSERTED)
       {
         card.initsd();
-        lcd_status("Card inserted");
+        LCD_MESSAGEPGM("Card inserted");
       }
       else
       {
         card.release();
-        lcd_status("Card removed");
+        LCD_MESSAGEPGM("Card removed");
       }
     }
   #endif
  
   if(status!=oldstatus)
   {
-    //Serial.println(status);
-    //clear();
     force_lcd_update=true;
     encoderpos=0;
     lineoffset=0;
@@ -1482,6 +1369,14 @@ void MainMenu::update()
       {
         showControl(); 
       }break;
+      case Sub_MotionControl:
+      {
+        showControlMotion(); 
+      }break;
+      case Sub_TempControl:
+      {
+        showControlTemp(); 
+      }break;
       case Main_SD: 
       {
         showSD();
@@ -1490,7 +1385,7 @@ void MainMenu::update()
   
   if(timeoutToStatus<millis())
     status=Main_Status;
-  force_lcd_update=false;
+  //force_lcd_update=false;
   lastencoderpos=encoderpos;
 }
 
diff --git a/README.md b/README.md
index 22b3c9a0fd08a0f55800163e6a1468be333ec604..988bf9a6e6c9f74fff919bc3d76a0a12d7081f74 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,7 @@ This is only possible, if some future moves are already processed, hence the nam
 It leads to less over-deposition at corners, especially at flat angles.
 
 *Arc support:*
+
 Splic3r can find curves that, although broken into segments, were ment to describe an arc.
 Marlin is able to print those arcs. The advantage is the firmware can choose the resolution,
 and can perform the arc with nearly constant velocity, resulting in a nice finish. 
@@ -118,13 +119,15 @@ This leads to less blocking in the heater management routine.
 
 Non-standard M-Codes, different to an old version of sprinter:
 ==============================================================
+Movement:
+
 *   G2  - CW ARC
 *   G3  - CCW ARC
 
 General:
 
-*   M17  - Enable/Power all stepper motors
-*   M18  - Disable all stepper motors; same as M84
+*   M17  - Enable/Power all stepper motors. Compatibility to ReplicatorG.
+*   M18  - Disable all stepper motors; same as M84.Compatibility to ReplicatorG.
 *   M30  - Print time since last M109 or SD card start to serial
 *   M42  - Change pin status via gcode
 *   M80  - Turn on Power Supply
@@ -137,9 +140,9 @@ Movement variables:
 *   M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!!
 *   M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec
 *   M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) im mm/sec^2  also sets minimum segment time in ms (B20000) to prevent buffer underruns and M20 minimum feedrate
-*   M220 - set build speed factor override percentage S:factor in percent ; aka "realtime tuneing in the gcode"
+*   M220 - set build speed mulitplying S:factor in percent ; aka "realtime tuneing in the gcode". So you can slow down if you have islands in one height-range, and speed up otherwise.
 *   M301 - Set PID parameters P I and D
-*   M400 - Finish all moves
+*   M400 - Finish all buffered moves.
 
 Advance: