diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 636a054e03..71769db3fb 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -1594,6 +1594,13 @@
  */
 #define FASTER_GCODE_PARSER
 
+/**
+ * CNC G-code options
+ * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc.
+ */
+//#define PAREN_COMMENTS      // Support for parentheses-delimited comments
+//#define GCODE_MOTION_MODES  // Remember the motion mode (G0 G1 G2 G3 G5 G38.X) and apply for X Y Z E F, etc.
+
 /**
  * User-defined menu items that execute custom GCode
  */
@@ -1776,13 +1783,4 @@
 // Enable Marlin dev mode which adds some special commands
 //#define MARLIN_DEV_MODE
 
-
-/**
- * CNC Parsing options
- * 
- * These options increase marlin's acceptance of non reprap dialects more in line with what laser cutter or drawing machine cams produce
- */
-//#define PARENTHESE_COMMENTS // Enable Marlin to interpret parenthese delimited comments as such and ignore them
-//#define STICKY_MOVE_MODE    // Enable marlin to keep the current move mode (G0 G1 G2 G3 G5 G38.X) and use it even if receiving only parameters (X Y Z E F etc.)
-
 #endif // CONFIGURATION_ADV_H
diff --git a/Marlin/src/config/default/Configuration_adv.h b/Marlin/src/config/default/Configuration_adv.h
index 88a3df2d53..71769db3fb 100755
--- a/Marlin/src/config/default/Configuration_adv.h
+++ b/Marlin/src/config/default/Configuration_adv.h
@@ -1594,6 +1594,13 @@
  */
 #define FASTER_GCODE_PARSER
 
+/**
+ * CNC G-code options
+ * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc.
+ */
+//#define PAREN_COMMENTS      // Support for parentheses-delimited comments
+//#define GCODE_MOTION_MODES  // Remember the motion mode (G0 G1 G2 G3 G5 G38.X) and apply for X Y Z E F, etc.
+
 /**
  * User-defined menu items that execute custom GCode
  */
diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index 7e1a7f80cf..36a01c1f7f 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -263,6 +263,10 @@ void GcodeSuite::process_parsed_command(
           break;
       #endif
 
+      #if ENABLED(GCODE_MOTION_MODES)
+        case 80: G80(); break;                                    // G80: Reset the current motion mode
+      #endif
+
       case 90: relative_mode = false; break;                      // G90: Relative Mode
       case 91: relative_mode = true; break;                       // G91: Absolute Mode
 
diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h
index 7340e3b9bf..106b980e7c 100644
--- a/Marlin/src/gcode/gcode.h
+++ b/Marlin/src/gcode/gcode.h
@@ -65,6 +65,7 @@
  * G33  - Delta Auto-Calibration (Requires DELTA_AUTO_CALIBRATION)
  * G38  - Probe in any direction using the Z_MIN_PROBE (Requires G38_PROBE_TARGET)
  * G42  - Coordinated move to a mesh point (Requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BLINEAR, or AUTO_BED_LEVELING_UBL)
+ * G80  - Cancel current motion mode (Requires GCODE_MOTION_MODES)
  * G90  - Use Absolute Coordinates
  * G91  - Use Relative Coordinates
  * G92  - Set current position to coordinates given
@@ -428,6 +429,10 @@ private:
     static void G59();
   #endif
 
+  #if ENABLED(GCODE_MOTION_MODES)
+    static void G80();
+  #endif
+
   static void G92();
 
   #if HAS_RESUME_CONTINUE
diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp
index 04a592266f..8f30773246 100644
--- a/Marlin/src/gcode/host/M115.cpp
+++ b/Marlin/src/gcode/host/M115.cpp
@@ -153,5 +153,19 @@ void GcodeSuite::M115() {
       #endif
     );
 
+    // PAREN_COMMENTS
+    cap_line(PSTR("PAREN_COMMENTS")
+      #if ENABLED(PAREN_COMMENTS)
+        , true
+      #endif
+    );
+
+    // MOTION_MODES (M80-M89)
+    cap_line(PSTR("MOTION_MODES")
+      #if ENABLED(GCODE_MOTION_MODES)
+        , true
+      #endif
+    );
+
   #endif // EXTENDED_CAPABILITIES_REPORT
 }
diff --git a/Marlin/src/gcode/motion/G80.cpp b/Marlin/src/gcode/motion/G80.cpp
new file mode 100644
index 0000000000..983a46392d
--- /dev/null
+++ b/Marlin/src/gcode/motion/G80.cpp
@@ -0,0 +1,36 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "../../inc/MarlinConfigPre.h"
+
+#if ENABLED(GCODE_MOTION_MODES)
+
+/**
+ * G80: Cancel current motion mode
+ */
+void GcodeSuite::G80() {
+
+  parser.cancel_motion_mode();
+
+}
+
+#endif // GCODE_MOTION_MODES
diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp
index 0c51318600..7c3fe76b60 100644
--- a/Marlin/src/gcode/parser.cpp
+++ b/Marlin/src/gcode/parser.cpp
@@ -50,16 +50,17 @@ char *GCodeParser::command_ptr,
      *GCodeParser::value_ptr;
 char GCodeParser::command_letter;
 int GCodeParser::codenum;
+
 #if USE_GCODE_SUBCODES
   uint8_t GCodeParser::subcode;
 #endif
-#if ENABLED(STICKY_MOVE_MODE)
-  int GCodeParser::current_motion_mode_codenum;	
-  #if USE_GCODE_SUBCODES		  
-    uint8_t GCodeParser::current_motion_mode_subcode;	
+
+#if ENABLED(GCODE_MOTION_MODES)
+  int16_t GCodeParser::motion_mode_codenum = -1;
+  #if USE_GCODE_SUBCODES
+    uint8_t GCodeParser::motion_mode_subcode;
   #endif
 #endif
-  
 
 #if ENABLED(FASTER_GCODE_PARSER)
   // Optimized Parameters
@@ -124,12 +125,20 @@ void GCodeParser::parse(char *p) {
     starpos[1] = '\0';
   }
 
+  #if ENABLED(GCODE_MOTION_MODES)
+    #if ENABLED(ARC_SUPPORT)
+      #define GTOP 3
+    #else
+      #define GTOP 1
+    #endif
+  #endif
+
   // Bail if the letter is not G, M, or T
-  switch(letter) { 
-  case 'G': 
-  case 'M': 
-  case 'T': 
- 
+  // (or a valid parameter for the current motion mode)
+  switch (letter) {
+
+    case 'G': case 'M': case 'T':
+
       // Skip spaces to get the numeric part
       while (*p == ' ') p++;
 
@@ -142,9 +151,7 @@ void GCodeParser::parse(char *p) {
 
       // Get the code number - integer digits only
       codenum = 0;
-      do {
-      codenum *= 10, codenum += *p++ - '0';
-      } while (NUMERIC(*p));
+      do { codenum *= 10, codenum += *p++ - '0'; } while (NUMERIC(*p));
 
       // Allow for decimal point in command
       #if USE_GCODE_SUBCODES
@@ -158,48 +165,43 @@ void GCodeParser::parse(char *p) {
       // Skip all spaces to get to the first argument, or nul
       while (*p == ' ') p++;
 
-      #if ENABLED(STICKY_MOVE_MODE)
-        if( letter == 'G' && (codenum < 4 || codenum == 5 || codenum == 38 || (codenum>=80 &&codenum < 90  ))) {
-        current_motion_mode_codenum = codenum;
-        #if USE_GCODE_SUBCODES
-          current_motion_mode_subcode = subcode;
-        #endif
+      #if ENABLED(GCODE_MOTION_MODES)
+        if (letter == 'G' && (codenum <= GTOP || codenum == 5
+                                #if ENABLED(G38_PROBE_TARGET)
+                                  || codenum == 38
+                                #endif
+                             )
+        ) {
+          motion_mode_codenum = codenum;
+          #if USE_GCODE_SUBCODES
+            motion_mode_subcode = subcode;
+          #endif
         }
       #endif
+
       break;
-    
-  #if ENABLED(STICKY_MOVE_MODE)
 
-    case 'P':
-    case 'Q':
-      if (current_motion_mode_codenum != 5)
-        return;
-    case 'I':
-    case 'J':
-    case 'R':  
-      if (current_motion_mode_codenum < 2)
-        return;
-    case 'X':
-    case 'Y':
-    case 'Z':
-    case 'E':
-    case 'F':
-
-      command_letter = 'G';
-      codenum = current_motion_mode_codenum;
-      #if USE_GCODE_SUBCODES
-        subcode = current_motion_mode_subcode;
+    #if ENABLED(GCODE_MOTION_MODES)
+      #if ENABLED(ARC_SUPPORT)
+        case 'I': case 'J': case 'R':
+          if (motion_mode_codenum != 2 && motion_mode_codenum != 3) return;
       #endif
-      
-      // Roll back one character before to use the current arg
-      p--;
-    break;
-  #endif // STICKY_MOVE_MODE
+      case 'P': case 'Q':
+        if (motion_mode_codenum != 5) return;
+      case 'X': case 'Y': case 'Z': case 'E': case 'F':
+        if (motion_mode_codenum < 0) return;
+        command_letter = 'G';
+        codenum = motion_mode_codenum;
+        #if USE_GCODE_SUBCODES
+          subcode = motion_mode_subcode;
+        #endif
+        p--; // Back up one character to use the current parameter
+      break;
+    #endif // GCODE_MOTION_MODES
 
-  default: return; 
+    default: return;
   }
 
- 
   // The command parameters (if any) start here, for sure!
 
   #if DISABLED(FASTER_GCODE_PARSER)
diff --git a/Marlin/src/gcode/parser.h b/Marlin/src/gcode/parser.h
index 5939ea8a77..b6044b216e 100644
--- a/Marlin/src/gcode/parser.h
+++ b/Marlin/src/gcode/parser.h
@@ -76,23 +76,21 @@ public:
 
   // Command line state
   static char *command_ptr,               // The command, so it can be echoed
-              *string_arg;                // string of command line
-
-
-
-  static char command_letter;             // G, M, or T
+              *string_arg,                // string of command line
+              command_letter;             // G, M, or T
   static int codenum;                     // 123
   #if USE_GCODE_SUBCODES
     static uint8_t subcode;               // .1
   #endif
 
-  #if ENABLED(STICKY_MOVE_MODE)
-    static int current_motion_mode_codenum;	
-    #if USE_GCODE_SUBCODES		  
-      static uint8_t current_motion_mode_subcode;	
+  #if ENABLED(GCODE_MOTION_MODES)
+    static int16_t motion_mode_codenum;
+    #if USE_GCODE_SUBCODES
+      static uint8_t motion_mode_subcode;
     #endif
+    FORCE_INLINE static void cancel_motion_mode() { motion_mode_codenum = -1; }
   #endif
-  
+
   #if ENABLED(DEBUG_GCODE_PARSER)
     static void debug();
   #endif
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 6cbd0cc331..61d7c1d158 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -282,10 +282,11 @@ static int read_serial(const int index) {
  */
 inline void get_serial_commands() {
   static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE];
-  static bool serial_comment_mode[NUM_SERIAL] = { false };
-  #if ENABLED(PARENTHESE_COMMENTS)
-    static bool serial_comment_paranthese_mode[NUM_SERIAL] = { false };
-  #endif
+  static bool serial_comment_mode[NUM_SERIAL] = { false }
+              #if ENABLED(PAREN_COMMENTS)
+                , serial_comment_paren_mode[NUM_SERIAL] = { false }
+              #endif
+            ;
 
   // If the command buffer is empty for too long,
   // send "wait" to indicate Marlin is still waiting.
@@ -313,9 +314,10 @@ inline void get_serial_commands() {
        */
       if (serial_char == '\n' || serial_char == '\r') {
 
-        serial_comment_mode[i] = false;                   // end of line == end of comment
-        #if ENABLED(PARENTHESE_COMMENTS)
-          serial_comment_paranthese_mode[i] = false;                   // end of line == end of comment
+        // Start with comment mode off
+        serial_comment_mode[i] = false;
+        #if ENABLED(PAREN_COMMENTS)
+          serial_comment_paren_mode[i] = false;
         #endif
 
         // Skip empty lines and comments
@@ -411,22 +413,22 @@ inline void get_serial_commands() {
       else if (serial_char == '\\') {  // Handle escapes
         // if we have one more character, copy it over
         if ((c = read_serial(i)) >= 0 && !serial_comment_mode[i]
-        #if ENABLED(PARENTHESE_COMMENTS)
-         && ! serial_comment_paranthese_mode[i]
-        #endif
-         )
+          #if ENABLED(PAREN_COMMENTS)
+            && !serial_comment_paren_mode[i]
+          #endif
+        )
           serial_line_buffer[i][serial_count[i]++] = (char)c;
       }
       else { // it's not a newline, carriage return or escape char
-        if (serial_char == ';') serial_comment_mode[i] = true; 
-        #if ENABLED(PARENTHESE_COMMENTS)
-          else if (serial_char == '(') serial_comment_paranthese_mode[i] = true;
-          else if (serial_char == ')') serial_comment_paranthese_mode[i] = false;
-        #endif
-        else if (!serial_comment_mode[i] 
-        #if ENABLED(PARENTHESE_COMMENTS)
-          && ! serial_comment_paranthese_mode[i]
+        if (serial_char == ';') serial_comment_mode[i] = true;
+        #if ENABLED(PAREN_COMMENTS)
+          else if (serial_char == '(') serial_comment_paren_mode[i] = true;
+          else if (serial_char == ')') serial_comment_paren_mode[i] = false;
         #endif
+        else if (!serial_comment_mode[i]
+          #if ENABLED(PAREN_COMMENTS)
+            && ! serial_comment_paren_mode[i]
+          #endif
         ) serial_line_buffer[i][serial_count[i]++] = serial_char;
       }
     } // for NUM_SERIAL
@@ -442,11 +444,12 @@ inline void get_serial_commands() {
    */
   inline void get_sdcard_commands() {
     static bool stop_buffering = false,
-                sd_comment_mode = false;
+                sd_comment_mode = false
+                #if ENABLED(PAREN_COMMENTS)
+                  , sd_comment_paren_mode = false
+                #endif
+              ;
 
-    #if ENABLED(PARENTHESE_COMMENTS)
-      static bool sd_comment_parenthese_mode = false;
-    #endif
     if (!IS_SD_PRINTING) return;
 
     /**
@@ -467,9 +470,9 @@ inline void get_serial_commands() {
       if (card_eof || n == -1
           || sd_char == '\n' || sd_char == '\r'
           || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode
-          #if ENABLED(PARENTHESE_COMMENTS)
-            && ! sd_comment_parenthese_mode
-          #endif
+            #if ENABLED(PAREN_COMMENTS)
+              && !sd_comment_paren_mode
+            #endif
           )
       ) {
         if (card_eof) {
@@ -506,8 +509,8 @@ inline void get_serial_commands() {
         if (sd_char == '#') stop_buffering = true;
 
         sd_comment_mode = false; // for new command
-        #if ENABLED(PARENTHESE_COMMENTS)
-          sd_comment_parenthese_mode = false;
+        #if ENABLED(PAREN_COMMENTS)
+          sd_comment_paren_mode = false;
         #endif
 
         // Skip empty lines and comments
@@ -525,17 +528,16 @@ inline void get_serial_commands() {
          */
       }
       else {
-        if (sd_char == ';') sd_comment_mode = true; 
-        #if ENABLED(PARENTHESE_COMMENTS)
-          else if (sd_char == '(') sd_comment_parenthese_mode = true; 
-          else if (sd_char == ')') sd_comment_parenthese_mode = false; 
+        if (sd_char == ';') sd_comment_mode = true;
+        #if ENABLED(PAREN_COMMENTS)
+          else if (sd_char == '(') sd_comment_paren_mode = true;
+          else if (sd_char == ')') sd_comment_paren_mode = false;
         #endif
         else if (!sd_comment_mode
-        #if ENABLED(PARENTHESE_COMMENTS) 
-        && ! sd_comment_parenthese_mode
-        #endif
-        ) 
-          command_queue[cmd_queue_index_w][sd_count++] = sd_char;
+          #if ENABLED(PAREN_COMMENTS)
+            && ! sd_comment_paren_mode
+          #endif
+        ) command_queue[cmd_queue_index_w][sd_count++] = sd_char;
       }
     }
   }
diff --git a/buildroot/share/tests/STM32F1_tests b/buildroot/share/tests/STM32F1_tests
index 283e68d9b2..b9b91ff66d 100755
--- a/buildroot/share/tests/STM32F1_tests
+++ b/buildroot/share/tests/STM32F1_tests
@@ -5,8 +5,9 @@ set -e
 
 restore_configs
 opt_set MOTHERBOARD BOARD_STM32F1R
-opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT
-exec_test $1 $2 "STM32F1R EEPROM_SETTINGS EEPROM_CHITCHAT REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT"
+opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT \
+           PAREN_COMMENTS GCODE_MOTION_MODES
+exec_test $1 $2 "STM32F1R EEPROM_SETTINGS EEPROM_CHITCHAT REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT PAREN_COMMENTS GCODE_MOTION_MODES"
 
 opt_enable SPINDLE_LASER_ENABLE
 exec_test $1 $2 "STM32F1R SPINDLE_LASER_ENABLE"