From 941943c167bac5908203e7ae98f3b9f485c9fe1a Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Tue, 27 Jun 2017 02:36:19 -0500
Subject: [PATCH 1/4] Apply const, spacing, etc.

---
 Marlin/M100_Free_Mem_Chk.cpp                  | 20 +++++-----
 Marlin/Marlin_main.cpp                        | 37 ++++++++++---------
 Marlin/SdFatStructs.h                         |  2 +-
 Marlin/example_configurations/K8400/README.md |  2 +-
 Marlin/servo.cpp                              |  2 +-
 Marlin/twibus.h                               | 22 +++++------
 6 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/Marlin/M100_Free_Mem_Chk.cpp b/Marlin/M100_Free_Mem_Chk.cpp
index be418b049e..6620b0a16e 100644
--- a/Marlin/M100_Free_Mem_Chk.cpp
+++ b/Marlin/M100_Free_Mem_Chk.cpp
@@ -189,19 +189,17 @@ void free_memory_pool_report(char * const ptr, const int16_t size) {
    *  This is useful to check the correctness of the M100 D and the M100 F commands.
    */
   void corrupt_free_memory(char *ptr, const uint16_t size) {
-    if (parser.seen('C')) {
-      ptr += 8;
-      const uint16_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack.
-                     j = near_top / (size + 1);
+    ptr += 8;
+    const uint16_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack.
+                   j = near_top / (size + 1);
 
-      SERIAL_ECHOLNPGM("Corrupting free memory block.\n");
-      for (uint16_t i = 1; i <= size; i++) {
-        char * const addr = ptr + i * j;
-        *addr = i;
-        SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr));
-      }
-      SERIAL_EOL();
+    SERIAL_ECHOLNPGM("Corrupting free memory block.\n");
+    for (uint16_t i = 1; i <= size; i++) {
+      char * const addr = ptr + i * j;
+      *addr = i;
+      SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr));
     }
+    SERIAL_EOL();
   }
 #endif // M100_FREE_MEMORY_CORRUPTOR
 
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 48cf72cc02..4ea5bdf11b 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1276,16 +1276,17 @@ void get_available_commands() {
  *
  * Returns TRUE if the target is invalid
  */
-bool get_target_extruder_from_command(int code) {
+bool get_target_extruder_from_command(const uint16_t code) {
   if (parser.seen('T')) {
-    if (parser.value_byte() >= EXTRUDERS) {
+    const int8_t e = parser.value_byte();
+    if (e >= EXTRUDERS) {
       SERIAL_ECHO_START();
       SERIAL_CHAR('M');
       SERIAL_ECHO(code);
-      SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", parser.value_byte());
+      SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", e);
       return true;
     }
-    target_extruder = parser.value_byte();
+    target_extruder = e;
   }
   else
     target_extruder = active_extruder;
@@ -5676,7 +5677,7 @@ inline void gcode_G92() {
         #if HAS_POSITION_SHIFT
           const float p = current_position[i];
         #endif
-        float v = parser.value_axis_units((AxisEnum)i);
+        const float v = parser.value_axis_units((AxisEnum)i);
 
         current_position[i] = v;
 
@@ -6405,7 +6406,7 @@ static bool pin_is_protected(const int8_t pin) {
 inline void gcode_M42() {
   if (!parser.seen('S')) return;
 
-  int pin_status = parser.value_int();
+  const int pin_status = parser.value_int();
   if (!WITHIN(pin_status, 0, 255)) return;
 
   int pin_number = parser.seen('P') ? parser.value_int() : LED_PIN;
@@ -6645,7 +6646,7 @@ inline void gcode_M42() {
    */
   inline void gcode_M43() {
 
-    if (parser.seen('T')) {   // must be first or else it's "S" and "E" parameters will execute endstop or servo test
+    if (parser.seen('T')) {   // must be first or else its "S" and "E" parameters will execute endstop or servo test
       toggle_pins();
       return;
     }
@@ -8268,10 +8269,10 @@ inline void gcode_M205() {
       home_offset[Z_AXIS] = parser.value_linear_units() - DELTA_HEIGHT;
       update_software_endstops(Z_AXIS);
     }
-    if (parser.seen('L')) delta_diagonal_rod = parser.value_linear_units();
-    if (parser.seen('R')) delta_radius = parser.value_linear_units();
-    if (parser.seen('S')) delta_segments_per_second = parser.value_float();
-    if (parser.seen('B')) delta_calibration_radius = parser.value_float();
+    if (parser.seen('L')) delta_diagonal_rod             = parser.value_linear_units();
+    if (parser.seen('R')) delta_radius                   = parser.value_linear_units();
+    if (parser.seen('S')) delta_segments_per_second      = parser.value_float();
+    if (parser.seen('B')) delta_calibration_radius       = parser.value_float();
     if (parser.seen('X')) delta_tower_angle_trim[A_AXIS] = parser.value_float();
     if (parser.seen('Y')) delta_tower_angle_trim[B_AXIS] = parser.value_float();
     if (parser.seen('Z')) { // rotate all 3 axis for Z = 0
@@ -8580,7 +8581,7 @@ inline void gcode_M226() {
    */
   inline void gcode_M280() {
     if (!parser.seen('P')) return;
-    int servo_index = parser.value_int();
+    const int servo_index = parser.value_int();
     if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) {
       if (parser.seen('S'))
         MOVE_SERVO(servo_index, parser.value_int());
@@ -8753,7 +8754,7 @@ inline void gcode_M226() {
    *       M302 S170 P1 ; set min extrude temp to 170 but leave disabled
    */
   inline void gcode_M302() {
-    bool seen_S = parser.seen('S');
+    const bool seen_S = parser.seen('S');
     if (seen_S) {
       thermalManager.extrude_min_temp = parser.value_celsius();
       thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0);
@@ -8960,10 +8961,12 @@ inline void gcode_M400() { stepper.synchronize(); }
    * M405: Turn on filament sensor for control
    */
   inline void gcode_M405() {
-    // This is technically a linear measurement, but since it's quantized to centimeters and is a different unit than
-    // everything else, it uses parser.value_int() instead of parser.value_linear_units().
-    if (parser.seen('D')) meas_delay_cm = parser.value_byte();
-    NOMORE(meas_delay_cm, MAX_MEASUREMENT_DELAY);
+    // This is technically a linear measurement, but since it's quantized to centimeters and is a different
+    // unit than everything else, it uses parser.value_byte() instead of parser.value_linear_units().
+    if (parser.seen('D')) {
+      meas_delay_cm = parser.value_byte();
+      NOMORE(meas_delay_cm, MAX_MEASUREMENT_DELAY);
+    }
 
     if (filwidth_delay_index[1] == -1) { // Initialize the ring buffer if not done since startup
       const uint8_t temp_ratio = thermalManager.widthFil_to_size_ratio() - 100; // -100 to scale within a signed byte
diff --git a/Marlin/SdFatStructs.h b/Marlin/SdFatStructs.h
index 3e989dea9d..3e78aa2927 100644
--- a/Marlin/SdFatStructs.h
+++ b/Marlin/SdFatStructs.h
@@ -523,7 +523,7 @@ struct directoryEntry {
   uint8_t  reservedNT;
           /**
            * The granularity of the seconds part of creationTime is 2 seconds
-           * so this field is a count of tenths of a second and its valid
+           * so this field is a count of tenths of a second and it's valid
            * value range is 0-199 inclusive. (WHG note - seems to be hundredths)
            */
   uint8_t  creationTimeTenths;
diff --git a/Marlin/example_configurations/K8400/README.md b/Marlin/example_configurations/K8400/README.md
index c9089b5870..14c8f8362b 100644
--- a/Marlin/example_configurations/K8400/README.md
+++ b/Marlin/example_configurations/K8400/README.md
@@ -2,7 +2,7 @@
 http://www.k8400.eu/
 
 Configuration files for the K8400, ported upstream from the official Velleman firmware.
-Like it's predecessor, (K8200), the K8400 is a 3Drag clone. There are some minor differences, documented in pins_K8400.h.
+Like its predecessor, (K8200), the K8400 is a 3Drag clone. There are some minor differences, documented in pins_K8400.h.
 
 Single and dual head configurations provided. Copy the correct Configuration.h and Configuration_adv.h to the /Marlin/ directory.
 
diff --git a/Marlin/servo.cpp b/Marlin/servo.cpp
index 3536571c17..74feb5c614 100644
--- a/Marlin/servo.cpp
+++ b/Marlin/servo.cpp
@@ -95,7 +95,7 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
   if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
     *OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks;
     if (SERVO(timer, Channel[timer]).Pin.isActive)    // check if activated
-      digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high
+      digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
   }
   else {
     // finished all channels so wait for the refresh period to expire before starting over
diff --git a/Marlin/twibus.h b/Marlin/twibus.h
index b93cd1c4ca..5d49639349 100644
--- a/Marlin/twibus.h
+++ b/Marlin/twibus.h
@@ -38,18 +38,18 @@ typedef void (*twiRequestFunc_t)();
 /**
  * TWIBUS class
  *
- * This class implements a wrapper around the two wire (I2C) bus, it allows
- * Marlin to send and request data from any slave device on the bus. This is
- * an experimental feature and it's inner workings as well as public facing
- * interface are prune to change in the future.
+ * This class implements a wrapper around the two wire (I2C) bus, allowing
+ * Marlin to send and request data from any slave device on the bus.
  *
- * The two main consumers of this class are M260 and M261, where M260 allows
- * Marlin to send a I2C packet to a device (please be aware that no repeated
- * starts are possible), this can be done in caching method by calling multiple
- * times M260 B<byte-1 value in base 10> or a one liner M260, have a look at
- * the gcode_M260() function for more information. M261 allows Marlin to
- * request data from a device, the received data is then relayed into the serial
- * line for host interpretation.
+ * The two main consumers of this class are M260 and M261. M260 provides a way
+ * to send an I2C packet to a device (no repeated starts) by caching up to 32
+ * bytes in a buffer and then sending the buffer.
+ * M261 requests data from a device. The received data is relayed to serial out
+ * for the host to interpret.
+ *
+ *  For more information see
+ *    - http://marlinfw.org/docs/gcode/M260.html 
+ *    - http://marlinfw.org/docs/gcode/M261.html 
  *
  */
 class TWIBus {

From 12f092c812b9d940f93831c7af8f79f24aa16c9e Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Mon, 26 Jun 2017 23:31:45 -0500
Subject: [PATCH 2/4] Cleanups to gcode.h, use seenval()

---
 Marlin/G26_Mesh_Validation_Tool.cpp |  12 +--
 Marlin/Marlin_main.cpp              | 128 ++++++++++++++--------------
 Marlin/gcode.h                      |  22 ++---
 Marlin/ubl_G29.cpp                  |  12 +--
 4 files changed, 86 insertions(+), 88 deletions(-)

diff --git a/Marlin/G26_Mesh_Validation_Tool.cpp b/Marlin/G26_Mesh_Validation_Tool.cpp
index 4b4f6e5c0f..6442d7e5eb 100644
--- a/Marlin/G26_Mesh_Validation_Tool.cpp
+++ b/Marlin/G26_Mesh_Validation_Tool.cpp
@@ -638,11 +638,11 @@
     g26_hotend_temp           = HOTEND_TEMP;
     g26_prime_flag            = 0;
 
-    g26_ooze_amount           = parser.seen('O') && parser.has_value() ? parser.value_linear_units() : OOZE_AMOUNT;
+    g26_ooze_amount           = parser.seenval('O') ? parser.value_linear_units() : OOZE_AMOUNT;
     g26_keep_heaters_on       = parser.seen('K') && parser.value_bool();
     g26_continue_with_closest = parser.seen('C') && parser.value_bool();
 
-    if (parser.seen('B')) {
+    if (parser.seenval('B')) {
       g26_bed_temp = parser.value_celsius();
       if (!WITHIN(g26_bed_temp, 15, 140)) {
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
@@ -650,7 +650,7 @@
       }
     }
 
-    if (parser.seen('L')) {
+    if (parser.seenval('L')) {
       g26_layer_height = parser.value_linear_units();
       if (!WITHIN(g26_layer_height, 0.0, 2.0)) {
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
@@ -672,7 +672,7 @@
       }
     }
 
-    if (parser.seen('S')) {
+    if (parser.seenval('S')) {
       g26_nozzle = parser.value_float();
       if (!WITHIN(g26_nozzle, 0.1, 1.0)) {
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
@@ -699,7 +699,7 @@
       }
     }
 
-    if (parser.seen('F')) {
+    if (parser.seenval('F')) {
       g26_filament_diameter = parser.value_linear_units();
       if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) {
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
@@ -712,7 +712,7 @@
 
     g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size
 
-    if (parser.seen('H')) {
+    if (parser.seenval('H')) {
       g26_hotend_temp = parser.value_celsius();
       if (!WITHIN(g26_hotend_temp, 165, 280)) {
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 4ea5bdf11b..89dbf5c868 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1277,7 +1277,7 @@ void get_available_commands() {
  * Returns TRUE if the target is invalid
  */
 bool get_target_extruder_from_command(const uint16_t code) {
-  if (parser.seen('T')) {
+  if (parser.seenval('T')) {
     const int8_t e = parser.value_byte();
     if (e >= EXTRUDERS) {
       SERIAL_ECHO_START();
@@ -3135,7 +3135,7 @@ static void homeaxis(const AxisEnum axis) {
       const char* mixing_codes = "ABCDHI";
       byte mix_bits = 0;
       for (uint8_t i = 0; i < MIXING_STEPPERS; i++) {
-        if (parser.seen(mixing_codes[i])) {
+        if (parser.seenval(mixing_codes[i])) {
           SBI(mix_bits, i);
           float v = parser.value_float();
           NOLESS(v, 0.0);
@@ -3304,7 +3304,7 @@ inline void gcode_G0_G1(
       #endif
 
       float arc_offset[2] = { 0.0, 0.0 };
-      if (parser.seen('R')) {
+      if (parser.seenval('R')) {
         const float r = parser.value_linear_units(),
                     p1 = current_position[X_AXIS], q1 = current_position[Y_AXIS],
                     p2 = destination[X_AXIS], q2 = destination[Y_AXIS];
@@ -3321,8 +3321,8 @@ inline void gcode_G0_G1(
         }
       }
       else {
-        if (parser.seen('I')) arc_offset[0] = parser.value_linear_units();
-        if (parser.seen('J')) arc_offset[1] = parser.value_linear_units();
+        if (parser.seenval('I')) arc_offset[0] = parser.value_linear_units();
+        if (parser.seenval('J')) arc_offset[1] = parser.value_linear_units();
       }
 
       if (arc_offset[0] || arc_offset[1]) {
@@ -3358,8 +3358,8 @@ inline void gcode_G0_G1(
 inline void gcode_G4() {
   millis_t dwell_ms = 0;
 
-  if (parser.seen('P')) dwell_ms = parser.value_millis(); // milliseconds to wait
-  if (parser.seen('S')) dwell_ms = parser.value_millis_from_seconds(); // seconds to wait
+  if (parser.seenval('P')) dwell_ms = parser.value_millis(); // milliseconds to wait
+  if (parser.seenval('S')) dwell_ms = parser.value_millis_from_seconds(); // seconds to wait
 
   stepper.synchronize();
   refresh_cmd_timeout();
@@ -4111,7 +4111,7 @@ void home_all_axes() { gcode_G28(true); }
         break;
 
       case MeshSet:
-        if (parser.seen('X')) {
+        if (parser.seenval('X')) {
           px = parser.value_int() - 1;
           if (!WITHIN(px, 0, GRID_MAX_POINTS_X - 1)) {
             SERIAL_PROTOCOLLNPGM("X out of range (1-" STRINGIFY(GRID_MAX_POINTS_X) ").");
@@ -4123,7 +4123,7 @@ void home_all_axes() { gcode_G28(true); }
           return;
         }
 
-        if (parser.seen('Y')) {
+        if (parser.seenval('Y')) {
           py = parser.value_int() - 1;
           if (!WITHIN(py, 0, GRID_MAX_POINTS_Y - 1)) {
             SERIAL_PROTOCOLLNPGM("Y out of range (1-" STRINGIFY(GRID_MAX_POINTS_Y) ").");
@@ -4135,7 +4135,7 @@ void home_all_axes() { gcode_G28(true); }
           return;
         }
 
-        if (parser.seen('Z')) {
+        if (parser.seenval('Z')) {
           mbl.z_values[px][py] = parser.value_linear_units();
         }
         else {
@@ -4145,7 +4145,7 @@ void home_all_axes() { gcode_G28(true); }
         break;
 
       case MeshSetZOffset:
-        if (parser.seen('Z')) {
+        if (parser.seenval('Z')) {
           mbl.z_offset = parser.value_linear_units();
         }
         else {
@@ -4371,17 +4371,17 @@ void home_all_axes() { gcode_G28(true); }
             return;
           }
 
-          const float z = parser.seen('Z') && parser.has_value() ? parser.value_float() : RAW_CURRENT_POSITION(Z);
+          const float z = parser.seenval('Z') ? parser.value_float() : RAW_CURRENT_POSITION(Z);
           if (!WITHIN(z, -10, 10)) {
             SERIAL_ERROR_START();
             SERIAL_ERRORLNPGM("Bad Z value");
             return;
           }
 
-          const float x = parser.seen('X') && parser.has_value() ? parser.value_float() : NAN,
-                      y = parser.seen('Y') && parser.has_value() ? parser.value_float() : NAN;
-          int8_t i = parser.seen('I') && parser.has_value() ? parser.value_byte() : -1,
-                 j = parser.seen('J') && parser.has_value() ? parser.value_byte() : -1;
+          const float x = parser.seenval('X') ? parser.value_float() : NAN,
+                      y = parser.seenval('Y') ? parser.value_float() : NAN;
+          int8_t i = parser.seenval('I') ? parser.value_byte() : -1,
+                 j = parser.seenval('J') ? parser.value_byte() : -1;
 
           if (!isnan(x) && !isnan(y)) {
             // Get nearest i / j from x / y
@@ -4413,7 +4413,7 @@ void home_all_axes() { gcode_G28(true); }
 
       #endif
 
-      verbose_level = parser.seen('V') && parser.has_value() ? parser.value_int() : 0;
+      verbose_level = parser.seenval('V') ? parser.value_int() : 0;
       if (!WITHIN(verbose_level, 0, 4)) {
         SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4).");
         return;
@@ -4433,7 +4433,7 @@ void home_all_axes() { gcode_G28(true); }
         // These values may be saved with the completed mesh
         abl_grid_points_x = parser.seen('X') ? parser.value_int() : GRID_MAX_POINTS_X;
         abl_grid_points_y = parser.seen('Y') ? parser.value_int() : GRID_MAX_POINTS_Y;
-        if (parser.seen('P')) abl_grid_points_x = abl_grid_points_y = parser.value_int();
+        if (parser.seenval('P')) abl_grid_points_x = abl_grid_points_y = parser.value_int();
 
         if (abl_grid_points_x < 2 || abl_grid_points_y < 2) {
           SERIAL_PROTOCOLLNPGM("?Number of probe points is implausible (2 minimum).");
@@ -5595,7 +5595,7 @@ void home_all_axes() { gcode_G28(true); }
     // If any axis has enough movement, do the move
     LOOP_XYZ(i)
       if (FABS(destination[i] - current_position[i]) >= G38_MINIMUM_MOVE) {
-        if (!parser.seen('F')) feedrate_mm_s = homing_feedrate(i);
+        if (!parser.seenval('F')) feedrate_mm_s = homing_feedrate(i);
         // If G38.2 fails throw an error
         if (!G38_run_probe() && is_38_2) {
           SERIAL_ERROR_START();
@@ -5616,10 +5616,10 @@ void home_all_axes() { gcode_G28(true); }
    */
   inline void gcode_G42() {
     if (IsRunning()) {
-      const bool hasI = parser.seen('I');
-      const int8_t ix = parser.has_value() ? parser.value_int() : 0;
-      const bool hasJ = parser.seen('J');
-      const int8_t iy = parser.has_value() ? parser.value_int() : 0;
+      const bool hasI = parser.seenval('I');
+      const int8_t ix = hasI ? parser.value_int() : 0;
+      const bool hasJ = parser.seenval('J');
+      const int8_t iy = hasJ ? parser.value_int() : 0;
 
       if ((hasI && !WITHIN(ix, 0, GRID_MAX_POINTS_X - 1)) || (hasJ && !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1))) {
         SERIAL_ECHOLNPGM(MSG_ERR_MESH_XY);
@@ -5664,12 +5664,12 @@ void home_all_axes() { gcode_G28(true); }
  */
 inline void gcode_G92() {
   bool didXYZ = false,
-       didE = parser.seen('E');
+       didE = parser.seenval('E');
 
   if (!didE) stepper.synchronize();
 
   LOOP_XYZE(i) {
-    if (parser.seen(axis_codes[i])) {
+    if (parser.seenval(axis_codes[i])) {
       #if IS_SCARA
         current_position[i] = parser.value_axis_units((AxisEnum)i);
         if (i != E_AXIS) didXYZ = true;
@@ -5715,11 +5715,11 @@ inline void gcode_G92() {
 
     millis_t ms = 0;
     bool hasP = false, hasS = false;
-    if (parser.seen('P')) {
+    if (parser.seenval('P')) {
       ms = parser.value_millis(); // milliseconds to wait
       hasP = ms > 0;
     }
-    if (parser.seen('S')) {
+    if (parser.seenval('S')) {
       ms = parser.value_millis_from_seconds(); // seconds to wait
       hasS = ms > 0;
     }
@@ -6272,7 +6272,7 @@ inline void gcode_M17() {
    * M26: Set SD Card file index
    */
   inline void gcode_M26() {
-    if (card.cardOK && parser.seen('S'))
+    if (card.cardOK && parser.seenval('S'))
       card.setIndex(parser.value_long());
   }
 
@@ -6334,7 +6334,7 @@ inline void gcode_M31() {
     if (card.cardOK) {
       card.openFile(namestartpos, true, call_procedure);
 
-      if (parser.seen('S'))
+      if (parser.seenval('S'))
         card.setIndex(parser.value_long());
 
       card.startFileprint();
@@ -6370,8 +6370,8 @@ inline void gcode_M31() {
      */
     inline void gcode_M34() {
       if (parser.seen('S')) card.setSortOn(parser.value_bool());
-      if (parser.seen('F')) {
-        int v = parser.value_long();
+      if (parser.seenval('F')) {
+        const int v = parser.value_long();
         card.setSortFolders(v < 0 ? -1 : v > 0 ? 1 : 0);
       }
       //if (parser.seen('R')) card.setSortReverse(parser.value_bool());
@@ -6404,10 +6404,8 @@ static bool pin_is_protected(const int8_t pin) {
  *  S<byte> Pin status from 0 - 255
  */
 inline void gcode_M42() {
-  if (!parser.seen('S')) return;
-
-  const int pin_status = parser.value_int();
-  if (!WITHIN(pin_status, 0, 255)) return;
+  if (!parser.seenval('S')) return;
+  const byte pin_status = parser.value_byte();
 
   int pin_number = parser.seen('P') ? parser.value_int() : LED_PIN;
   if (pin_number < 0) return;
@@ -6666,8 +6664,8 @@ inline void gcode_M42() {
     }
 
     // Get the range of pins to test or watch
-    const uint8_t first_pin = parser.seen('P') ? parser.value_byte() : 0,
-                  last_pin = parser.seen('P') ? first_pin : NUM_DIGITAL_PINS - 1;
+    const uint8_t first_pin = parser.seenval('P') ? parser.value_byte() : 0,
+                  last_pin = parser.seenval('P') ? first_pin : NUM_DIGITAL_PINS - 1;
 
     if (first_pin > last_pin) return;
 
@@ -7026,7 +7024,7 @@ inline void gcode_M104() {
     if (target_extruder != active_extruder) return;
   #endif
 
-  if (parser.seen('S')) {
+  if (parser.seenval('S')) {
     const int16_t temp = parser.value_celsius();
     thermalManager.setTargetHotend(temp, target_extruder);
 
@@ -7153,7 +7151,7 @@ inline void gcode_M105() {
    * M155: Set temperature auto-report interval. M155 S<seconds>
    */
   inline void gcode_M155() {
-    if (parser.seen('S')) {
+    if (parser.seenval('S')) {
       auto_report_temp_interval = parser.value_byte();
       NOMORE(auto_report_temp_interval, 60);
       next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval;
@@ -7240,8 +7238,8 @@ inline void gcode_M109() {
     if (target_extruder != active_extruder) return;
   #endif
 
-  const bool no_wait_for_cooling = parser.seen('S');
-  if (no_wait_for_cooling || parser.seen('R')) {
+  const bool no_wait_for_cooling = parser.seenval('S');
+  if (no_wait_for_cooling || parser.seenval('R')) {
     const int16_t temp = parser.value_celsius();
     thermalManager.setTargetHotend(temp, target_extruder);
 
@@ -7389,8 +7387,8 @@ inline void gcode_M109() {
     if (DEBUGGING(DRYRUN)) return;
 
     LCD_MESSAGEPGM(MSG_BED_HEATING);
-    const bool no_wait_for_cooling = parser.seen('S');
-    if (no_wait_for_cooling || parser.seen('R')) {
+    const bool no_wait_for_cooling = parser.seenval('S');
+    if (no_wait_for_cooling || parser.seenval('R')) {
       thermalManager.setTargetBed(parser.value_celsius());
       #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
         if (parser.value_celsius() > BED_MINTEMP)
@@ -7497,7 +7495,7 @@ inline void gcode_M109() {
  * M110: Set Current Line Number
  */
 inline void gcode_M110() {
-  if (parser.seen('N')) gcode_LastN = parser.value_long();
+  if (parser.seenval('N')) gcode_LastN = parser.value_long();
 }
 
 /**
@@ -7547,7 +7545,7 @@ inline void gcode_M111() {
    *   S<seconds> Optional. Set the keepalive interval.
    */
   inline void gcode_M113() {
-    if (parser.seen('S')) {
+    if (parser.seenval('S')) {
       host_keepalive_interval = parser.value_byte();
       NOMORE(host_keepalive_interval, 60);
     }
@@ -7590,7 +7588,7 @@ inline void gcode_M111() {
  */
 inline void gcode_M140() {
   if (DEBUGGING(DRYRUN)) return;
-  if (parser.seen('S')) thermalManager.setTargetBed(parser.value_celsius());
+  if (parser.seenval('S')) thermalManager.setTargetBed(parser.value_celsius());
 }
 
 #if ENABLED(ULTIPANEL)
@@ -7611,16 +7609,16 @@ inline void gcode_M140() {
     }
     else {
       int v;
-      if (parser.seen('H')) {
+      if (parser.seenval('H')) {
         v = parser.value_int();
         lcd_preheat_hotend_temp[material] = constrain(v, EXTRUDE_MINTEMP, HEATER_0_MAXTEMP - 15);
       }
-      if (parser.seen('F')) {
+      if (parser.seenval('F')) {
         v = parser.value_int();
         lcd_preheat_fan_speed[material] = constrain(v, 0, 255);
       }
       #if TEMP_SENSOR_BED != 0
-        if (parser.seen('B')) {
+        if (parser.seenval('B')) {
           v = parser.value_int();
           lcd_preheat_bed_temp[material] = constrain(v, BED_MINTEMP, BED_MAXTEMP - 15);
         }
@@ -7635,9 +7633,9 @@ inline void gcode_M140() {
    * M149: Set temperature units
    */
   inline void gcode_M149() {
-         if (parser.seen('C')) parser.set_input_temp_units(TEMPUNIT_C);
-    else if (parser.seen('K')) parser.set_input_temp_units(TEMPUNIT_K);
-    else if (parser.seen('F')) parser.set_input_temp_units(TEMPUNIT_F);
+         if (parser.seenval('C')) parser.set_input_temp_units(TEMPUNIT_C);
+    else if (parser.seenval('K')) parser.set_input_temp_units(TEMPUNIT_K);
+    else if (parser.seenval('F')) parser.set_input_temp_units(TEMPUNIT_F);
   }
 #endif
 
@@ -7726,7 +7724,7 @@ inline void gcode_M83() { axis_relative_modes[E_AXIS] = true; }
  * M18, M84: Disable stepper motors
  */
 inline void gcode_M18_M84() {
-  if (parser.seen('S')) {
+  if (parser.seenval('S')) {
     stepper_inactive_time = parser.value_millis_from_seconds();
   }
   else {
@@ -8448,11 +8446,11 @@ inline void gcode_M211() {
   inline void gcode_M218() {
     if (get_target_extruder_from_command(218) || target_extruder == 0) return;
 
-    if (parser.seen('X')) hotend_offset[X_AXIS][target_extruder] = parser.value_linear_units();
-    if (parser.seen('Y')) hotend_offset[Y_AXIS][target_extruder] = parser.value_linear_units();
+    if (parser.seenval('X')) hotend_offset[X_AXIS][target_extruder] = parser.value_linear_units();
+    if (parser.seenval('Y')) hotend_offset[Y_AXIS][target_extruder] = parser.value_linear_units();
 
     #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE)
-      if (parser.seen('Z')) hotend_offset[Z_AXIS][target_extruder] = parser.value_linear_units();
+      if (parser.seenval('Z')) hotend_offset[Z_AXIS][target_extruder] = parser.value_linear_units();
     #endif
 
     SERIAL_ECHO_START();
@@ -8476,7 +8474,7 @@ inline void gcode_M211() {
  * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95)
  */
 inline void gcode_M220() {
-  if (parser.seen('S')) feedrate_percentage = parser.value_int();
+  if (parser.seenval('S')) feedrate_percentage = parser.value_int();
 }
 
 /**
@@ -8484,7 +8482,7 @@ inline void gcode_M220() {
  */
 inline void gcode_M221() {
   if (get_target_extruder_from_command(221)) return;
-  if (parser.seen('S'))
+  if (parser.seenval('S'))
     flow_percentage[target_extruder] = parser.value_int();
 }
 
@@ -9777,14 +9775,14 @@ inline void gcode_M907() {
    *       S# determines MS1 or MS2, X# sets the pin high/low.
    */
   inline void gcode_M351() {
-    if (parser.seen('S')) switch (parser.value_byte()) {
+    if (parser.seenval('S')) switch (parser.value_byte()) {
       case 1:
-        LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1);
-        if (parser.seen('B')) stepper.microstep_ms(4, parser.value_byte(), -1);
+        LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1);
+        if (parser.seenval('B')) stepper.microstep_ms(4, parser.value_byte(), -1);
         break;
       case 2:
-        LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte());
-        if (parser.seen('B')) stepper.microstep_ms(4, -1, parser.value_byte());
+        LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte());
+        if (parser.seenval('B')) stepper.microstep_ms(4, -1, parser.value_byte());
         break;
     }
     stepper.microstep_readings();
@@ -9827,8 +9825,8 @@ inline void gcode_M907() {
 inline void gcode_M355() {
   #if HAS_CASE_LIGHT
     uint8_t args = 0;
-    if (parser.seen('P')) ++args, case_light_brightness = parser.value_byte();
-    if (parser.seen('S')) ++args, case_light_on = parser.value_bool();
+    if (parser.seenval('P')) ++args, case_light_brightness = parser.value_byte();
+    if (parser.seenval('S')) ++args, case_light_on = parser.value_bool();
     if (args) update_case_light();
 
     // always report case light status
diff --git a/Marlin/gcode.h b/Marlin/gcode.h
index 1cd1cfabcf..801ed36ca1 100644
--- a/Marlin/gcode.h
+++ b/Marlin/gcode.h
@@ -132,7 +132,7 @@ public:
 
     #define SEEN_TEST(L) TEST(codebits[(L - 'A') >> 3], (L - 'A') & 0x7)
 
-  #else
+  #else // !FASTER_GCODE_PARSER
 
     // Code is found in the string. If not found, value_ptr is unchanged.
     // This allows "if (seen('A')||seen('B'))" to use the last-found value.
@@ -147,7 +147,7 @@ public:
 
     #define SEEN_TEST(L) !!strchr(command_args, L)
 
-  #endif // FASTER_GCODE_PARSER
+  #endif // !FASTER_GCODE_PARSER
 
   // Populate all fields by parsing a single line of GCode
   // This uses 54 bytes of SRAM to speed up seen/value
@@ -157,7 +157,7 @@ public:
   FORCE_INLINE static bool has_value() { return value_ptr != NULL; }
 
   // Seen and has value
-  FORCE_INLINE static bool seenval(const char c) { return seen(c) && has_value(); }
+  inline static bool seenval(const char c) { return seen(c) && has_value(); }
 
   static volatile bool seen_axis() {
     return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E');
@@ -184,20 +184,20 @@ public:
   }
 
   // Code value as a long or ulong
-  inline          static long value_long()  { return value_ptr ? strtol(value_ptr, NULL, 10) : 0L; }
-  inline unsigned static long value_ulong() { return value_ptr ? strtoul(value_ptr, NULL, 10) : 0UL; }
+  inline static int32_t value_long() { return value_ptr ? strtol(value_ptr, NULL, 10) : 0L; }
+  inline static uint32_t value_ulong() { return value_ptr ? strtoul(value_ptr, NULL, 10) : 0UL; }
 
   // Code value for use as time
   FORCE_INLINE static millis_t value_millis() { return value_ulong(); }
   FORCE_INLINE static millis_t value_millis_from_seconds() { return value_float() * 1000UL; }
 
   // Reduce to fewer bits
-  FORCE_INLINE static int value_int()    { return (int)value_long(); }
-  FORCE_INLINE uint16_t value_ushort()   { return (uint16_t)value_long(); }
-  inline static uint8_t value_byte()     { return (uint8_t)(constrain(value_long(), 0, 255)); }
+  FORCE_INLINE static int16_t value_int() { return (int16_t)value_long(); }
+  FORCE_INLINE static uint16_t value_ushort() { return (uint16_t)value_long(); }
+  inline static uint8_t value_byte() { return (uint8_t)constrain(value_long(), 0, 255); }
 
   // Bool is true with no value or non-zero
-  inline static bool value_bool()        { return !has_value() || value_byte(); }
+  inline static bool value_bool() { return !has_value() || value_byte(); }
 
   // Units modes: Inches, Fahrenheit, Kelvin
 
@@ -282,12 +282,12 @@ public:
       }
     }
 
-  #else
+  #else // !TEMPERATURE_UNITS_SUPPORT
 
     FORCE_INLINE static float value_celsius()      { return value_float(); }
     FORCE_INLINE static float value_celsius_diff() { return value_float(); }
 
-  #endif
+  #endif // !TEMPERATURE_UNITS_SUPPORT
 
   FORCE_INLINE static float value_feedrate() { return value_linear_units(); }
 
diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp
index c70755a331..0781f8fb7f 100644
--- a/Marlin/ubl_G29.cpp
+++ b/Marlin/ubl_G29.cpp
@@ -314,7 +314,7 @@
 
     // Check for commands that require the printer to be homed
     if (axis_unhomed_error()) {
-      const int8_t p_val = parser.seen('P') && parser.has_value() ? parser.value_int() : -1;
+      const int8_t p_val = parser.seenval('P') ? parser.value_int() : -1;
       if (p_val == 1 || p_val == 2 || p_val == 4 || parser.seen('J'))
         home_all_axes();
     }
@@ -492,7 +492,7 @@
               return;
             }
 
-            const float height = parser.seen('H') && parser.has_value() ? parser.value_float() : Z_CLEARANCE_BETWEEN_PROBES;
+            const float height = parser.seenval('H') ? parser.value_float() : Z_CLEARANCE_BETWEEN_PROBES;
             manually_probe_remaining_mesh(g29_x_pos, g29_y_pos, height, g29_card_thickness, parser.seen('T'));
 
             SERIAL_PROTOCOLLNPGM("G29 P2 finished.");
@@ -1094,9 +1094,9 @@
     g29_constant = 0.0;
     g29_repetition_cnt = 0;
 
-    g29_x_flag = parser.seen('X') && parser.has_value();
+    g29_x_flag = parser.seenval('X');
     g29_x_pos = g29_x_flag ? parser.value_float() : current_position[X_AXIS];
-    g29_y_flag = parser.seen('Y') && parser.has_value();
+    g29_y_flag = parser.seenval('Y');
     g29_y_pos = g29_y_flag ? parser.value_float() : current_position[Y_AXIS];
 
     if (parser.seen('R')) {
@@ -1170,7 +1170,7 @@
       g29_constant = parser.value_float();
 
     #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
-      if (parser.seen('F') && parser.has_value()) {
+      if (parser.seenval('F')) {
         const float fh = parser.value_float();
         if (!WITHIN(fh, 0.0, 100.0)) {
           SERIAL_PROTOCOLLNPGM("?(F)ade height for Bed Level Correction not plausible.\n");
@@ -1180,7 +1180,7 @@
       }
     #endif
 
-    g29_map_type = parser.seen('T') && parser.has_value() ? parser.value_int() : 0;
+    g29_map_type = parser.seenval('T') ? parser.value_int() : 0;
     if (!WITHIN(g29_map_type, 0, 2)) {
       SERIAL_PROTOCOLLNPGM("Invalid map type.\n");
       return UBL_ERR;

From 05449cf6ee62fd0534103b68b404a13c15c6b89f Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Tue, 27 Jun 2017 00:49:21 -0500
Subject: [PATCH 3/4] Add shorthand value accessors to gcode.h

---
 Marlin/G26_Mesh_Validation_Tool.cpp |  12 +-
 Marlin/Marlin_main.cpp              | 260 ++++++++++++++--------------
 Marlin/gcode.h                      |  11 ++
 Marlin/ubl_G29.cpp                  |   6 +-
 4 files changed, 147 insertions(+), 142 deletions(-)

diff --git a/Marlin/G26_Mesh_Validation_Tool.cpp b/Marlin/G26_Mesh_Validation_Tool.cpp
index 6442d7e5eb..7c780c676d 100644
--- a/Marlin/G26_Mesh_Validation_Tool.cpp
+++ b/Marlin/G26_Mesh_Validation_Tool.cpp
@@ -638,9 +638,9 @@
     g26_hotend_temp           = HOTEND_TEMP;
     g26_prime_flag            = 0;
 
-    g26_ooze_amount           = parser.seenval('O') ? parser.value_linear_units() : OOZE_AMOUNT;
-    g26_keep_heaters_on       = parser.seen('K') && parser.value_bool();
-    g26_continue_with_closest = parser.seen('C') && parser.value_bool();
+    g26_ooze_amount           = parser.linearval('O', OOZE_AMOUNT);
+    g26_keep_heaters_on       = parser.boolval('K');
+    g26_continue_with_closest = parser.boolval('C');
 
     if (parser.seenval('B')) {
       g26_bed_temp = parser.value_celsius();
@@ -727,7 +727,7 @@
     }
 
     #if ENABLED(NEWPANEL)
-      g26_repeats = parser.seen('R') && parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1;
+      g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1);
     #else
       if (!parser.seen('R')) {
         SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD.");
@@ -741,8 +741,8 @@
       return UBL_ERR;
     }
 
-    g26_x_pos = parser.seen('X') ? parser.value_linear_units() : current_position[X_AXIS];
-    g26_y_pos = parser.seen('Y') ? parser.value_linear_units() : current_position[Y_AXIS];
+    g26_x_pos = parser.linearval('X', current_position[X_AXIS]);
+    g26_y_pos = parser.linearval('Y', current_position[Y_AXIS]);
     if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) {
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
       return UBL_ERR;
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 89dbf5c868..f46125af7d 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3175,7 +3175,7 @@ void gcode_get_destination() {
       destination[i] = current_position[i];
   }
 
-  if (parser.seen('F') && parser.value_linear_units() > 0.0)
+  if (parser.linearval('F') > 0.0)
     feedrate_mm_s = MMM_TO_MMS(parser.value_feedrate());
 
   #if ENABLED(PRINTCOUNTER)
@@ -3329,7 +3329,7 @@ inline void gcode_G0_G1(
 
         #if ENABLED(ARC_P_CIRCLES)
           // P indicates number of circles to do
-          int8_t circles_to_do = parser.seen('P') ? parser.value_byte() : 0;
+          int8_t circles_to_do = parser.byteval('P');
           if (!WITHIN(circles_to_do, 0, 100)) {
             SERIAL_ERROR_START();
             SERIAL_ERRORLNPGM(MSG_ERR_ARC_ARGS);
@@ -3388,10 +3388,10 @@ inline void gcode_G4() {
       gcode_get_destination();
 
       const float offset[] = {
-        parser.seen('I') ? parser.value_linear_units() : 0.0,
-        parser.seen('J') ? parser.value_linear_units() : 0.0,
-        parser.seen('P') ? parser.value_linear_units() : 0.0,
-        parser.seen('Q') ? parser.value_linear_units() : 0.0
+        parser.linearval('I'),
+        parser.linearval('J'),
+        parser.linearval('P'),
+        parser.linearval('Q')
       };
 
       plan_cubic_move(offset);
@@ -3408,9 +3408,8 @@ inline void gcode_G4() {
    */
   inline void gcode_G10_G11(bool doRetract=false) {
     #if EXTRUDERS > 1
-      if (doRetract) {
-        retracted_swap[active_extruder] = (parser.seen('S') && parser.value_bool()); // checks for swap retract argument
-      }
+      if (doRetract)
+        retracted_swap[active_extruder] = parser.boolval('S'); // checks for swap retract argument
     #endif
     retract(doRetract
      #if EXTRUDERS > 1
@@ -3429,10 +3428,10 @@ inline void gcode_G4() {
     // Don't allow nozzle cleaning without homing first
     if (axis_unhomed_error()) return;
 
-    const uint8_t pattern = parser.seen('P') ? parser.value_ushort() : 0,
-                  strokes = parser.seen('S') ? parser.value_ushort() : NOZZLE_CLEAN_STROKES,
-                  objects = parser.seen('T') ? parser.value_ushort() : NOZZLE_CLEAN_TRIANGLES;
-    const float radius = parser.seen('R') ? parser.value_float() : NOZZLE_CLEAN_CIRCLE_RADIUS;
+    const uint8_t pattern = parser.ushortval('P', 0),
+                  strokes = parser.ushortval('S', NOZZLE_CLEAN_STROKES),
+                  objects = parser.ushortval('T', NOZZLE_CLEAN_TRIANGLES);
+    const float radius = parser.floatval('R', NOZZLE_CLEAN_CIRCLE_RADIUS);
 
     Nozzle::clean(pattern, strokes, radius, objects);
   }
@@ -3476,7 +3475,7 @@ inline void gcode_G4() {
   inline void gcode_G27() {
     // Don't allow nozzle parking without homing first
     if (axis_unhomed_error()) return;
-    Nozzle::park(parser.seen('P') ? parser.value_ushort() : 0);
+    Nozzle::park(parser.ushortval('P'));
   }
 #endif // NOZZLE_PARK_FEATURE
 
@@ -4039,7 +4038,7 @@ void home_all_axes() { gcode_G28(true); }
       static bool enable_soft_endstops;
     #endif
 
-    const MeshLevelingState state = parser.seen('S') ? (MeshLevelingState)parser.value_byte() : MeshReport;
+    const MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport);
     if (!WITHIN(state, 0, 5)) {
       SERIAL_PROTOCOLLNPGM("S out of range (0-5).");
       return;
@@ -4269,7 +4268,7 @@ void home_all_axes() { gcode_G28(true); }
     #endif
 
     #if ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY)
-      const bool faux = parser.seen('C') && parser.value_bool();
+      const bool faux = parser.boolval('C');
     #elif ENABLED(PROBE_MANUALLY)
       const bool faux = no_action;
     #else
@@ -4371,17 +4370,17 @@ void home_all_axes() { gcode_G28(true); }
             return;
           }
 
-          const float z = parser.seenval('Z') ? parser.value_float() : RAW_CURRENT_POSITION(Z);
+          const float z = parser.floatval('Z', RAW_CURRENT_POSITION(Z));
           if (!WITHIN(z, -10, 10)) {
             SERIAL_ERROR_START();
             SERIAL_ERRORLNPGM("Bad Z value");
             return;
           }
 
-          const float x = parser.seenval('X') ? parser.value_float() : NAN,
-                      y = parser.seenval('Y') ? parser.value_float() : NAN;
-          int8_t i = parser.seenval('I') ? parser.value_byte() : -1,
-                 j = parser.seenval('J') ? parser.value_byte() : -1;
+          const float x = parser.floatval('X', NAN),
+                      y = parser.floatval('Y', NAN);
+          int8_t i = parser.byteval('I', -1),
+                 j = parser.byteval('J', -1);
 
           if (!isnan(x) && !isnan(y)) {
             // Get nearest i / j from x / y
@@ -4413,13 +4412,13 @@ void home_all_axes() { gcode_G28(true); }
 
       #endif
 
-      verbose_level = parser.seenval('V') ? parser.value_int() : 0;
+      verbose_level = parser.intval('V');
       if (!WITHIN(verbose_level, 0, 4)) {
         SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4).");
         return;
       }
 
-      dryrun = (parser.seen('D') && parser.value_bool())
+      dryrun = parser.boolval('D')
         #if ENABLED(PROBE_MANUALLY)
           || no_action
         #endif
@@ -4427,12 +4426,12 @@ void home_all_axes() { gcode_G28(true); }
 
       #if ENABLED(AUTO_BED_LEVELING_LINEAR)
 
-        do_topography_map = verbose_level > 2 || parser.seen('T');
+        do_topography_map = verbose_level > 2 || parser.boolval('T');
 
         // X and Y specify points in each direction, overriding the default
         // These values may be saved with the completed mesh
-        abl_grid_points_x = parser.seen('X') ? parser.value_int() : GRID_MAX_POINTS_X;
-        abl_grid_points_y = parser.seen('Y') ? parser.value_int() : GRID_MAX_POINTS_Y;
+        abl_grid_points_x = parser.intval('X', GRID_MAX_POINTS_X);
+        abl_grid_points_y = parser.intval('Y', GRID_MAX_POINTS_Y);
         if (parser.seenval('P')) abl_grid_points_x = abl_grid_points_y = parser.value_int();
 
         if (abl_grid_points_x < 2 || abl_grid_points_y < 2) {
@@ -4444,18 +4443,18 @@ void home_all_axes() { gcode_G28(true); }
 
       #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
 
-        zoffset = parser.seen('Z') ? parser.value_linear_units() : 0;
+        zoffset = parser.linearval('Z');
 
       #endif
 
       #if ABL_GRID
 
-        xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.seen('S') ? parser.value_linear_units() : XY_PROBE_SPEED);
+        xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.linearval('S', XY_PROBE_SPEED));
 
-        left_probe_bed_position = parser.seen('L') ? (int)parser.value_linear_units() : LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION);
-        right_probe_bed_position = parser.seen('R') ? (int)parser.value_linear_units() : LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION);
-        front_probe_bed_position = parser.seen('F') ? (int)parser.value_linear_units() : LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION);
-        back_probe_bed_position = parser.seen('B') ? (int)parser.value_linear_units() : LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION);
+        left_probe_bed_position = (int)parser.linearval('L', LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION));
+        right_probe_bed_position = (int)parser.linearval('R', LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION));
+        front_probe_bed_position = (int)parser.linearval('F', LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION));
+        back_probe_bed_position = (int)parser.linearval('B', LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION));
 
         const bool left_out_l = left_probe_bed_position < LOGICAL_X_POSITION(MIN_PROBE_X),
                    left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - (MIN_PROBE_EDGE),
@@ -4735,7 +4734,7 @@ void home_all_axes() { gcode_G28(true); }
 
     #else // !PROBE_MANUALLY
 
-      const bool stow_probe_after_each = parser.seen('E');
+      const bool stow_probe_after_each = parser.boolval('E');
 
       #if ABL_GRID
 
@@ -5086,8 +5085,8 @@ void home_all_axes() { gcode_G28(true); }
    *   S0  Leave the probe deployed
    */
   inline void gcode_G30() {
-    const float xpos = parser.seen('X') ? parser.value_linear_units() : current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER,
-                ypos = parser.seen('Y') ? parser.value_linear_units() : current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER;
+    const float xpos = parser.linearval('X', current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER),
+                ypos = parser.linearval('Y', current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER);
 
     if (!position_is_reachable_by_probe_xy(xpos, ypos)) return;
 
@@ -5098,7 +5097,7 @@ void home_all_axes() { gcode_G28(true); }
 
     setup_for_endstop_or_probe_move();
 
-    const float measured_z = probe_pt(xpos, ypos, !parser.seen('S') || parser.value_bool(), 1);
+    const float measured_z = probe_pt(xpos, ypos, parser.boolval('S', true), 1);
 
     if (!isnan(measured_z)) {
       SERIAL_PROTOCOLPAIR("Bed X: ", FIXFLOAT(xpos));
@@ -5164,32 +5163,32 @@ void home_all_axes() { gcode_G28(true); }
 
     inline void gcode_G33() {
 
-      const int8_t probe_points = parser.seen('P') ? parser.value_int() : DELTA_CALIBRATION_DEFAULT_POINTS;
+      const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS);
       if (!WITHIN(probe_points, 1, 7)) {
         SERIAL_PROTOCOLLNPGM("?(P)oints is implausible (1 to 7).");
         return;
       }
 
-      const int8_t verbose_level = parser.seen('V') ? parser.value_byte() : 1;
+      const int8_t verbose_level = parser.byteval('V', 1);
       if (!WITHIN(verbose_level, 0, 2)) {
         SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-2).");
         return;
       }
 
-      const float calibration_precision = parser.seen('C') ? parser.value_float() : 0.0;
+      const float calibration_precision = parser.floatval('C');
       if (calibration_precision < 0) {
         SERIAL_PROTOCOLLNPGM("?(C)alibration precision is implausible (>0).");
         return;
       }
 
-      const int8_t force_iterations = parser.seen('F') ? parser.value_int() : 1;
+      const int8_t force_iterations = parser.intval('F', 1);
       if (!WITHIN(force_iterations, 1, 30)) {
         SERIAL_PROTOCOLLNPGM("?(F)orce iteration is implausible (1-30).");
         return;
       }
 
-      const bool towers_set           = !parser.seen('T'),
-                 stow_after_each      = parser.seen('E') && parser.value_bool(),
+      const bool towers_set           = !parser.boolval('T'),
+                 stow_after_each      = parser.boolval('E'),
                  _1p_calibration      = probe_points == 1,
                  _4p_calibration      = probe_points == 2,
                  _4p_towers_points    = _4p_calibration && towers_set,
@@ -5640,13 +5639,13 @@ void home_all_axes() { gcode_G28(true); }
       set_destination_to_current();
       if (hasI) destination[X_AXIS] = LOGICAL_X_POSITION(_GET_MESH_X(ix));
       if (hasJ) destination[Y_AXIS] = LOGICAL_Y_POSITION(_GET_MESH_Y(iy));
-      if (parser.seen('P') && parser.value_bool()) {
+      if (parser.boolval('P')) {
         if (hasI) destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER;
         if (hasJ) destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER;
       }
 
-      if (parser.seen('F') && parser.value_linear_units() > 0.0)
-        feedrate_mm_s = MMM_TO_MMS(parser.value_linear_units());
+      const float fval = parser.linearval('F');
+      if (fval > 0.0) feedrate_mm_s = MMM_TO_MMS(fval);
 
       // SCARA kinematic has "safe" XY raw moves
       #if IS_SCARA
@@ -5851,7 +5850,7 @@ inline void gcode_G92() {
     #if ENABLED(SPINDLE_LASER_PWM)
       if (parser.seen('O')) ocr_val_mode();
       else {
-        const float spindle_laser_power = parser.seen('S') ? parser.value_float() : 0;
+        const float spindle_laser_power = parser.floatval('S');
         if (spindle_laser_power == 0) {
           WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);                                    // turn spindle off (active low)
           delay_for_power_down();
@@ -6329,7 +6328,7 @@ inline void gcode_M31() {
       stepper.synchronize();
 
     char* namestartpos = parser.string_arg;
-    bool call_procedure = parser.seen('P');
+    const bool call_procedure = parser.boolval('P');
 
     if (card.cardOK) {
       card.openFile(namestartpos, true, call_procedure);
@@ -6407,7 +6406,7 @@ inline void gcode_M42() {
   if (!parser.seenval('S')) return;
   const byte pin_status = parser.value_byte();
 
-  int pin_number = parser.seen('P') ? parser.value_int() : LED_PIN;
+  const int pin_number = parser.intval('P', LED_PIN);
   if (pin_number < 0) return;
 
   if (pin_is_protected(pin_number)) {
@@ -6440,11 +6439,11 @@ inline void gcode_M42() {
   #include "pinsDebug.h"
 
   inline void toggle_pins() {
-    const bool I_flag = parser.seen('I') && parser.value_bool();
-    const int repeat = parser.seen('R') ? parser.value_int() : 1,
-              start = parser.seen('S') ? parser.value_int() : 0,
-              end = parser.seen('E') ? parser.value_int() : NUM_DIGITAL_PINS - 1,
-              wait = parser.seen('W') ? parser.value_int() : 500;
+    const bool I_flag = parser.boolval('I');
+    const int repeat = parser.intval('R', 1),
+              start = parser.intval('S'),
+              end = parser.intval('E', NUM_DIGITAL_PINS - 1),
+              wait = parser.intval('W', 500);
 
     for (uint8_t pin = start; pin <= end; pin++) {
       //report_pin_state_extended(pin, I_flag, false);
@@ -6503,7 +6502,7 @@ inline void gcode_M42() {
 
     #else
 
-      const uint8_t probe_index = parser.seen('P') ? parser.value_byte() : Z_ENDSTOP_SERVO_NR;
+      const uint8_t probe_index = parser.byteval('P', Z_ENDSTOP_SERVO_NR);
 
       SERIAL_PROTOCOLLNPGM("Servo probe test");
       SERIAL_PROTOCOLLNPAIR(".  using index:  ", probe_index);
@@ -6664,15 +6663,15 @@ inline void gcode_M42() {
     }
 
     // Get the range of pins to test or watch
-    const uint8_t first_pin = parser.seenval('P') ? parser.value_byte() : 0,
+    const uint8_t first_pin = parser.byteval('P'),
                   last_pin = parser.seenval('P') ? first_pin : NUM_DIGITAL_PINS - 1;
 
     if (first_pin > last_pin) return;
 
-    const bool ignore_protection = parser.seen('I') && parser.value_bool();
+    const bool ignore_protection = parser.boolval('I');
 
     // Watch until click, M108, or reset
-    if (parser.seen('W') && parser.value_bool()) {
+    if (parser.boolval('W')) {
       SERIAL_PROTOCOLLNPGM("Watching pins");
       byte pin_state[last_pin - first_pin + 1];
       for (int8_t pin = first_pin; pin <= last_pin; pin++) {
@@ -6751,7 +6750,7 @@ inline void gcode_M42() {
 
     if (axis_unhomed_error()) return;
 
-    const int8_t verbose_level = parser.seen('V') ? parser.value_byte() : 1;
+    const int8_t verbose_level = parser.byteval('V', 1);
     if (!WITHIN(verbose_level, 0, 4)) {
       SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4).");
       return;
@@ -6760,19 +6759,19 @@ inline void gcode_M42() {
     if (verbose_level > 0)
       SERIAL_PROTOCOLLNPGM("M48 Z-Probe Repeatability Test");
 
-    int8_t n_samples = parser.seen('P') ? parser.value_byte() : 10;
+    const int8_t n_samples = parser.byteval('P', 10);
     if (!WITHIN(n_samples, 4, 50)) {
       SERIAL_PROTOCOLLNPGM("?Sample size not plausible (4-50).");
       return;
     }
 
-    const bool stow_probe_after_each = parser.seen('E');
+    const bool stow_probe_after_each = parser.boolval('E');
 
     float X_current = current_position[X_AXIS],
           Y_current = current_position[Y_AXIS];
 
-    const float X_probe_location = parser.seen('X') ? parser.value_linear_units() : X_current + X_PROBE_OFFSET_FROM_EXTRUDER,
-                Y_probe_location = parser.seen('Y') ? parser.value_linear_units() : Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER;
+    const float X_probe_location = parser.linearval('X', X_current + X_PROBE_OFFSET_FROM_EXTRUDER),
+                Y_probe_location = parser.linearval('Y', Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER);
 
     #if DISABLED(DELTA)
       if (!WITHIN(X_probe_location, LOGICAL_X_POSITION(MIN_PROBE_X), LOGICAL_X_POSITION(MAX_PROBE_X))) {
@@ -6798,7 +6797,7 @@ inline void gcode_M42() {
     }
     if (n_legs == 1) n_legs = 2;
 
-    bool schizoid_flag = parser.seen('S');
+    const bool schizoid_flag = parser.boolval('S');
     if (schizoid_flag && !seen_L) n_legs = 7;
 
     /**
@@ -7006,7 +7005,7 @@ inline void gcode_M77() { print_job_timer.stop(); }
    */
   inline void gcode_M78() {
     // "M78 S78" will reset the statistics
-    if (parser.seen('S') && parser.value_int() == 78)
+    if (parser.intval('S') == 78)
       print_job_timer.initStats();
     else
       print_job_timer.showStats();
@@ -7177,9 +7176,9 @@ inline void gcode_M105() {
    *  P<index> Fan index, if more than one fan
    */
   inline void gcode_M106() {
-    uint16_t s = parser.seen('S') ? parser.value_ushort() : 255,
-             p = parser.seen('P') ? parser.value_ushort() : 0;
+    uint16_t s = parser.ushortval('S', 255);
     NOMORE(s, 255);
+    const uint8_t p = parser.byteval('P', 0);
     if (p < FAN_COUNT) fanSpeeds[p] = s;
   }
 
@@ -7187,7 +7186,7 @@ inline void gcode_M105() {
    * M107: Fan Off
    */
   inline void gcode_M107() {
-    uint16_t p = parser.seen('P') ? parser.value_ushort() : 0;
+    const uint16_t p = parser.ushortval('P');
     if (p < FAN_COUNT) fanSpeeds[p] = 0;
   }
 
@@ -7502,7 +7501,7 @@ inline void gcode_M110() {
  * M111: Set the debug level
  */
 inline void gcode_M111() {
-  marlin_debug_flags = parser.seen('S') ? parser.value_byte() : (uint8_t)DEBUG_NONE;
+  marlin_debug_flags = parser.byteval('S', (uint8_t)DEBUG_NONE);
 
   const static char str_debug_1[] PROGMEM = MSG_DEBUG_ECHO;
   const static char str_debug_2[] PROGMEM = MSG_DEBUG_INFO;
@@ -7563,7 +7562,7 @@ inline void gcode_M111() {
     /**
      * M126: Heater 1 valve open
      */
-    inline void gcode_M126() { baricuda_valve_pressure = parser.seen('S') ? parser.value_byte() : 255; }
+    inline void gcode_M126() { baricuda_valve_pressure = parser.byteval('S', 255); }
     /**
      * M127: Heater 1 valve close
      */
@@ -7574,7 +7573,7 @@ inline void gcode_M111() {
     /**
      * M128: Heater 2 valve open
      */
-    inline void gcode_M128() { baricuda_e_to_p_pressure = parser.seen('S') ? parser.value_byte() : 255; }
+    inline void gcode_M128() { baricuda_e_to_p_pressure = parser.byteval('S', 255); }
     /**
      * M129: Heater 2 valve close
      */
@@ -7602,7 +7601,7 @@ inline void gcode_M140() {
    *   F<fan speed>
    */
   inline void gcode_M145() {
-    uint8_t material = parser.seen('S') ? (uint8_t)parser.value_int() : 0;
+    const uint8_t material = (uint8_t)parser.intval('S');
     if (material >= COUNT(lcd_preheat_hotend_temp)) {
       SERIAL_ERROR_START();
       SERIAL_ERRORLNPGM(MSG_ERR_MATERIAL_INDEX);
@@ -8034,16 +8033,14 @@ inline void gcode_M121() { endstops.enable_globally(false); }
     ;
 
     // Lift Z axis
-    const float z_lift = parser.seen('Z') ? parser.value_linear_units() :
-      #if defined(PAUSE_PARK_Z_ADD) && PAUSE_PARK_Z_ADD > 0
-        PAUSE_PARK_Z_ADD
-      #else
-        0
+    const float z_lift = parser.linearval('Z')
+      #if PAUSE_PARK_Z_ADD > 0
+        + PAUSE_PARK_Z_ADD
       #endif
     ;
 
     // Move XY axes to filament change position or given position
-    const float x_pos = parser.seen('X') ? parser.value_linear_units() : 0
+    const float x_pos = parser.linearval('X')
       #ifdef PAUSE_PARK_X_POS
         + PAUSE_PARK_X_POS
       #endif
@@ -8051,7 +8048,7 @@ inline void gcode_M121() { endstops.enable_globally(false); }
         + (active_extruder ? hotend_offset[X_AXIS][active_extruder] : 0)
       #endif
     ;
-    const float y_pos = parser.seen('Y') ? parser.value_linear_units() : 0
+    const float y_pos = parser.linearval('Y')
       #ifdef PAUSE_PARK_Y_POS
         + PAUSE_PARK_Y_POS
       #endif
@@ -8491,10 +8488,10 @@ inline void gcode_M221() {
  */
 inline void gcode_M226() {
   if (parser.seen('P')) {
-    int pin_number = parser.value_int(),
-        pin_state = parser.seen('S') ? parser.value_int() : -1; // required pin state - default is inverted
+    const int pin_number = parser.value_int(),
+              pin_state = parser.intval('S', -1); // required pin state - default is inverted
 
-    if (pin_state >= -1 && pin_state <= 1 && pin_number > -1 && !pin_is_protected(pin_number)) {
+    if (WITHIN(pin_state, -1, 1) && pin_number > -1 && !pin_is_protected(pin_number)) {
 
       int target = LOW;
 
@@ -8559,7 +8556,7 @@ inline void gcode_M226() {
   inline void gcode_M261() {
     if (parser.seen('A')) i2c.address(parser.value_byte());
 
-    uint8_t bytes = parser.seen('B') ? parser.value_byte() : 1;
+    uint8_t bytes = parser.byteval('B', 1);
 
     if (i2c.addr && bytes && bytes <= TWIBUS_BUFFER_SIZE) {
       i2c.relay(bytes);
@@ -8604,8 +8601,8 @@ inline void gcode_M226() {
    * M300: Play beep sound S<frequency Hz> P<duration ms>
    */
   inline void gcode_M300() {
-    uint16_t const frequency = parser.seen('S') ? parser.value_ushort() : 260;
-    uint16_t duration = parser.seen('P') ? parser.value_ushort() : 1000;
+    uint16_t const frequency = parser.ushortval('S', 260);
+    uint16_t duration = parser.ushortval('P', 1000);
 
     // Limits the tone duration to 0-5 seconds.
     NOMORE(duration, 5000);
@@ -8633,7 +8630,7 @@ inline void gcode_M226() {
 
     // multi-extruder PID patch: M301 updates or prints a single extruder's PID values
     // default behaviour (omitting E parameter) is to update for extruder 0 only
-    int e = parser.seen('E') ? parser.value_int() : 0; // extruder being updated
+    const uint8_t e = parser.byteval('E'); // extruder being updated
 
     if (e < HOTENDS) { // catch bad input value
       if (parser.seen('P')) PID_PARAM(Kp, e) = parser.value_float();
@@ -8781,11 +8778,10 @@ inline void gcode_M226() {
  */
 inline void gcode_M303() {
   #if HAS_PID_HEATING
-    const int e = parser.seen('E') ? parser.value_int() : 0,
-              c = parser.seen('C') ? parser.value_int() : 5;
-    const bool u = parser.seen('U') && parser.value_bool();
+    const int e = parser.intval('E'), c = parser.intval('C', 5);
+    const bool u = parser.boolval('U');
 
-    int16_t temp = parser.seen('S') ? parser.value_celsius() : (e < 0 ? 70 : 150);
+    int16_t temp = parser.celsiusval('S', e < 0 ? 70 : 150);
 
     if (WITHIN(e, 0, HOTENDS - 1))
       target_extruder = e;
@@ -9078,11 +9074,9 @@ void quickstop_stepper() {
       #endif
     }
 
-    bool to_enable = false;
-    if (parser.seen('S')) {
-      to_enable = parser.value_bool();
+    const bool to_enable = parser.boolval('S');
+    if (parser.seen('S'))
       set_bed_leveling_enabled(to_enable);
-    }
 
     #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
       if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units());
@@ -9149,11 +9143,12 @@ void quickstop_stepper() {
    *   M421 I<xindex> J<yindex> Q<offset>
    */
   inline void gcode_M421() {
-    const bool hasI = parser.seen('I');
-    const int8_t ix = hasI ? parser.value_int() : -1;
-    const bool hasJ = parser.seen('J');
-    const int8_t iy = hasJ ? parser.value_int() : -1;
-    const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q');
+    int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1);
+    const bool hasI = ix >= 0,
+               hasJ = iy >= 0,
+               hasC = parser.seen('C'),
+               hasZ = parser.seen('Z'),
+               hasQ = !hasZ && parser.seen('Q');
 
     if (!hasI || !hasJ || !(hasZ || hasQ)) {
       SERIAL_ERROR_START();
@@ -9183,11 +9178,12 @@ void quickstop_stepper() {
    *   M421 C Q<offset>
    */
   inline void gcode_M421() {
-    const bool hasC = parser.seen('C'), hasI = parser.seen('I');
-    int8_t ix = hasI ? parser.value_int() : -1;
-    const bool hasJ = parser.seen('J');
-    int8_t iy = hasJ ? parser.value_int() : -1;
-    const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q');
+    int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1);
+    const bool hasI = ix >= 0,
+               hasJ = iy >= 0,
+               hasC = parser.seen('C'),
+               hasZ = parser.seen('Z'),
+               hasQ = !hasZ && parser.seen('Q');
 
     if (hasC) {
       const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false);
@@ -9278,7 +9274,7 @@ inline void gcode_M502() {
  * M503: print settings currently in memory
  */
 inline void gcode_M503() {
-  (void)settings.report(parser.seen('S') && !parser.value_bool());
+  (void)settings.report(!parser.boolval('S', true));
 }
 
 #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
@@ -9382,25 +9378,23 @@ inline void gcode_M503() {
     ;
 
     // Lift Z axis
-    const float z_lift = parser.seen('Z') ? parser.value_linear_units() :
+    const float z_lift = parser.linearval('Z', 0
       #if defined(PAUSE_PARK_Z_ADD) && PAUSE_PARK_Z_ADD > 0
-        PAUSE_PARK_Z_ADD
-      #else
-        0
+        + PAUSE_PARK_Z_ADD
       #endif
-    ;
+    );
 
     // Move XY axes to filament exchange position
-    const float x_pos = parser.seen('X') ? parser.value_linear_units() : 0
+    const float x_pos = parser.linearval('X', 0
       #ifdef PAUSE_PARK_X_POS
         + PAUSE_PARK_X_POS
       #endif
-    ;
-    const float y_pos = parser.seen('Y') ? parser.value_linear_units() : 0
+    );
+    const float y_pos = parser.linearval('Y', 0
       #ifdef PAUSE_PARK_Y_POS
         + PAUSE_PARK_Y_POS
       #endif
-    ;
+    );
 
     // Unload filament
     const float unload_length = parser.seen('U') ? parser.value_axis_units(E_AXIS) : 0
@@ -9416,13 +9410,13 @@ inline void gcode_M503() {
       #endif
     ;
 
-    const int beep_count = parser.seen('B') ? parser.value_int() :
+    const int beep_count = parser.intval('B',
       #ifdef FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS
         FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS
       #else
         -1
       #endif
-    ;
+    );
 
     const bool job_running = print_job_timer.isRunning();
 
@@ -9485,7 +9479,7 @@ inline void gcode_M503() {
 
   inline void gcode_M605() {
     stepper.synchronize();
-    extruder_duplication_enabled = parser.seen('S') && parser.value_int() == (int)DXC_DUPLICATION_MODE;
+    extruder_duplication_enabled = parser.intval('S') == (int)DXC_DUPLICATION_MODE;
     SERIAL_ECHO_START();
     SERIAL_ECHOLNPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF);
   }
@@ -9503,14 +9497,14 @@ inline void gcode_M503() {
   inline void gcode_M900() {
     stepper.synchronize();
 
-    const float newK = parser.seen('K') ? parser.value_float() : -1;
+    const float newK = parser.floatval('K', -1);
     if (newK >= 0) planner.extruder_advance_k = newK;
 
-    float newR = parser.seen('R') ? parser.value_float() : -1;
+    float newR = parser.floatval('R', -1);
     if (newR < 0) {
-      const float newD = parser.seen('D') ? parser.value_float() : -1,
-                  newW = parser.seen('W') ? parser.value_float() : -1,
-                  newH = parser.seen('H') ? parser.value_float() : -1;
+      const float newD = parser.floatval('D', -1),
+                  newW = parser.floatval('W', -1),
+                  newH = parser.floatval('H', -1);
       if (newD >= 0 && newW >= 0 && newH >= 0)
         newR = newD ? (newW * newH) / (sq(newD * 0.5) * M_PI) : 0;
     }
@@ -9579,7 +9573,7 @@ inline void gcode_M503() {
   inline void gcode_M906() {
     uint16_t values[XYZE];
     LOOP_XYZE(i)
-      values[i] = parser.seen(axis_codes[i]) ? parser.value_int() : 0;
+      values[i] = parser.intval(axis_codes[i]);
 
     #if ENABLED(X_IS_TMC2130)
       if (values[X_AXIS]) tmc2130_set_current(stepperX, 'X', values[X_AXIS]);
@@ -9651,7 +9645,7 @@ inline void gcode_M503() {
     inline void gcode_M913() {
       uint16_t values[XYZE];
       LOOP_XYZE(i)
-        values[i] = parser.seen(axis_codes[i]) ? parser.value_int() : 0;
+        values[i] = parser.intval(axis_codes[i]);
 
       #if ENABLED(X_IS_TMC2130)
         if (values[X_AXIS]) tmc2130_set_pwmthrs(stepperX, 'X', values[X_AXIS], planner.axis_steps_per_mm[X_AXIS]);
@@ -9738,14 +9732,14 @@ inline void gcode_M907() {
   inline void gcode_M908() {
     #if HAS_DIGIPOTSS
       stepper.digitalPotWrite(
-        parser.seen('P') ? parser.value_int() : 0,
-        parser.seen('S') ? parser.value_int() : 0
+        parser.intval('P'),
+        parser.intval('S')
       );
     #endif
     #ifdef DAC_STEPPER_CURRENT
       dac_current_raw(
-        parser.seen('P') ? parser.value_byte() : -1,
-        parser.seen('S') ? parser.value_ushort() : 0
+        parser.byteval('P', -1),
+        parser.ushortval('S', 0)
       );
     #endif
   }
@@ -9856,9 +9850,9 @@ inline void gcode_M355() {
    *
    */
   inline void gcode_M163() {
-    const int mix_index = parser.seen('S') ? parser.value_int() : 0;
+    const int mix_index = parser.intval('S');
     if (mix_index < MIXING_STEPPERS) {
-      float mix_value = parser.seen('P') ? parser.value_float() : 0.0;
+      float mix_value = parser.floatval('P');
       NOLESS(mix_value, 0.0);
       mixing_factor[mix_index] = RECIPROCAL(mix_value);
     }
@@ -9873,7 +9867,7 @@ inline void gcode_M355() {
      *
      */
     inline void gcode_M164() {
-      const int tool_index = parser.seen('S') ? parser.value_int() : 0;
+      const int tool_index = parser.intval('S');
       if (tool_index < MIXING_VIRTUAL_TOOLS) {
         normalize_mix();
         for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
@@ -9916,7 +9910,7 @@ inline void gcode_M999() {
   Running = true;
   lcd_reset_alert_level();
 
-  if (parser.seen('S') && parser.value_bool()) return;
+  if (parser.boolval('S')) return;
 
   // gcode_LastN = Stopped_gcode_LastN;
   FlushSerialRequestResend();
@@ -10298,8 +10292,8 @@ inline void gcode_T(uint8_t tmp_extruder) {
 
     tool_change(
       tmp_extruder,
-      parser.seen('F') ? MMM_TO_MMS(parser.value_linear_units()) : 0.0,
-      (tmp_extruder == active_extruder) || (parser.seen('S') && parser.value_bool())
+      MMM_TO_MMS(parser.linearval('F')),
+      (tmp_extruder == active_extruder) || parser.boolval('S')
     );
 
   #endif
diff --git a/Marlin/gcode.h b/Marlin/gcode.h
index 801ed36ca1..0a9c859f14 100644
--- a/Marlin/gcode.h
+++ b/Marlin/gcode.h
@@ -293,6 +293,17 @@ public:
 
   void unknown_command_error();
 
+  // Provide simple value accessors with default option
+  FORCE_INLINE static float    floatval(const char c, const float dval=0.0)   { return seenval(c) ? value_float()        : dval; }
+  FORCE_INLINE static bool     boolval(const char c, const bool dval=false)   { return seen(c)    ? value_bool()         : dval; }
+  FORCE_INLINE static uint8_t  byteval(const char c, const uint8_t dval=0)    { return seenval(c) ? value_byte()         : dval; }
+  FORCE_INLINE static int16_t  intval(const char c, const int16_t dval=0)     { return seenval(c) ? value_int()          : dval; }
+  FORCE_INLINE static uint16_t ushortval(const char c, const uint16_t dval=0) { return seenval(c) ? value_ushort()       : dval; }
+  FORCE_INLINE static int32_t  longval(const char c, const int32_t dval=0)    { return seenval(c) ? value_long()         : dval; }
+  FORCE_INLINE static uint32_t ulongval(const char c, const uint32_t dval=0)  { return seenval(c) ? value_ulong()        : dval; }
+  FORCE_INLINE static float    linearval(const char c, const float dval=0.0)  { return seenval(c) ? value_linear_units() : dval; }
+  FORCE_INLINE static float    celsiusval(const char c, const float dval=0.0) { return seenval(c) ? value_celsius()      : dval; }
+
 };
 
 extern GCodeParser parser;
diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp
index 0781f8fb7f..294e3616a3 100644
--- a/Marlin/ubl_G29.cpp
+++ b/Marlin/ubl_G29.cpp
@@ -314,7 +314,7 @@
 
     // Check for commands that require the printer to be homed
     if (axis_unhomed_error()) {
-      const int8_t p_val = parser.seenval('P') ? parser.value_int() : -1;
+      const int8_t p_val = parser.intval('P', -1);
       if (p_val == 1 || p_val == 2 || p_val == 4 || parser.seen('J'))
         home_all_axes();
     }
@@ -492,7 +492,7 @@
               return;
             }
 
-            const float height = parser.seenval('H') ? parser.value_float() : Z_CLEARANCE_BETWEEN_PROBES;
+            const float height = parser.floatval('H', Z_CLEARANCE_BETWEEN_PROBES);
             manually_probe_remaining_mesh(g29_x_pos, g29_y_pos, height, g29_card_thickness, parser.seen('T'));
 
             SERIAL_PROTOCOLLNPGM("G29 P2 finished.");
@@ -1180,7 +1180,7 @@
       }
     #endif
 
-    g29_map_type = parser.seenval('T') ? parser.value_int() : 0;
+    g29_map_type = parser.intval('T');
     if (!WITHIN(g29_map_type, 0, 2)) {
       SERIAL_PROTOCOLLNPGM("Invalid map type.\n");
       return UBL_ERR;

From bd776df8c10f7248b69efa0860ad7dfdd1778b89 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Tue, 27 Jun 2017 18:39:06 -0500
Subject: [PATCH 4/4] Optimize seen_axis by moving 'X' to index 24

---
 Marlin/gcode.h | 44 +++++++++++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 15 deletions(-)

diff --git a/Marlin/gcode.h b/Marlin/gcode.h
index 0a9c859f14..42a5c89b14 100644
--- a/Marlin/gcode.h
+++ b/Marlin/gcode.h
@@ -97,6 +97,13 @@ public:
   // Reset is done before parsing
   static void reset();
 
+  // Index so that 'X' falls on index 24
+  #define PARAM_IND(N)  ((N) >> 3)
+  #define PARAM_BIT(N)  ((N) & 0x7)
+  #define LETTER_OFF(N) ((N) - 'A' + 1)
+  #define LETTER_IND(N) PARAM_IND(LETTER_OFF(N))
+  #define LETTER_BIT(N) PARAM_BIT(LETTER_OFF(N))
+
   #if ENABLED(FASTER_GCODE_PARSER)
 
     // Set the flag and pointer for a parameter
@@ -105,14 +112,14 @@ public:
         , const bool debug=false
       #endif
     ) {
-      const uint8_t ind = c - 'A';
+      const uint8_t ind = LETTER_OFF(c);
       if (ind >= COUNT(param)) return;           // Only A-Z
-      SBI(codebits[ind >> 3], ind & 0x7);        // parameter exists
+      SBI(codebits[PARAM_IND(ind)], PARAM_BIT(ind));        // parameter exists
       param[ind] = ptr ? ptr - command_ptr : 0;  // parameter offset or 0
       #if ENABLED(DEBUG_GCODE_PARSER)
         if (debug) {
-          SERIAL_ECHOPAIR("Set bit ", (int)(ind & 0x7));
-          SERIAL_ECHOPAIR(" of index ", (int)(ind >> 3));
+          SERIAL_ECHOPAIR("Set bit ", (int)PARAM_BIT(ind));
+          SERIAL_ECHOPAIR(" of index ", (int)PARAM_IND(ind));
           SERIAL_ECHOLNPAIR(" | param = ", hex_address((void*)param[ind]));
         }
       #endif
@@ -120,22 +127,28 @@ public:
 
     // Code seen bit was set. If not found, value_ptr is unchanged.
     // This allows "if (seen('A')||seen('B'))" to use the last-found value.
+    // This is volatile because its side-effects are important
     static volatile bool seen(const char c) {
-      const uint8_t ind = c - 'A';
+      const uint8_t ind = LETTER_OFF(c);
       if (ind >= COUNT(param)) return false; // Only A-Z
-      const bool b = TEST(codebits[ind >> 3], ind & 0x7);
+      const bool b = TEST(codebits[PARAM_IND(ind)], PARAM_BIT(ind));
       if (b) value_ptr = command_ptr + param[ind];
       return b;
     }
 
-    static volatile bool seen_any() { return codebits[3] || codebits[2] || codebits[1] || codebits[0]; }
+    static bool seen_any() { return codebits[3] || codebits[2] || codebits[1] || codebits[0]; }
 
-    #define SEEN_TEST(L) TEST(codebits[(L - 'A') >> 3], (L - 'A') & 0x7)
+    #define SEEN_TEST(L) TEST(codebits[LETTER_IND(L)], LETTER_BIT(L))
+
+    // Seen any axis parameter
+    // Optimized by moving 'X' up to index 24
+    FORCE_INLINE bool seen_axis() { return codebits[3] || SEEN_TEST('E'); }
 
   #else // !FASTER_GCODE_PARSER
 
     // Code is found in the string. If not found, value_ptr is unchanged.
     // This allows "if (seen('A')||seen('B'))" to use the last-found value.
+    // This is volatile because its side-effects are important
     static volatile bool seen(const char c) {
       const char *p = strchr(command_args, c);
       const bool b = !!p;
@@ -143,26 +156,27 @@ public:
       return b;
     }
 
-    static volatile bool seen_any() { return *command_args == '\0'; }
+    static bool seen_any() { return *command_args == '\0'; }
 
     #define SEEN_TEST(L) !!strchr(command_args, L)
 
+    // Seen any axis parameter
+    static bool seen_axis() {
+      return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E');
+    }
+
   #endif // !FASTER_GCODE_PARSER
 
   // Populate all fields by parsing a single line of GCode
   // This uses 54 bytes of SRAM to speed up seen/value
   static void parse(char * p);
 
-  // Code value pointer was set
+  // The code value pointer was set
   FORCE_INLINE static bool has_value() { return value_ptr != NULL; }
 
-  // Seen and has value
+  // Seen a parameter with a value
   inline static bool seenval(const char c) { return seen(c) && has_value(); }
 
-  static volatile bool seen_axis() {
-    return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E');
-  }
-
   // Float removes 'E' to prevent scientific notation interpretation
   inline static float value_float() {
     if (value_ptr) {