void Endstops::report_state() {
  if (endstop_hit_bits) {
    #if ENABLED(ULTRA_LCD)
      char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' ';
      #define _SET_STOP_CHAR(A,C) (chr## A = C)
    #else
      #define _SET_STOP_CHAR(A,C) ;
    #endif

    #define _ENDSTOP_HIT_ECHO(A,C) do{ \
      SERIAL_ECHOPAIR(" " STRINGIFY(A) ":", stepper.triggered_position_mm(A ##_AXIS)); \
      _SET_STOP_CHAR(A,C); }while(0)

    #define _ENDSTOP_HIT_TEST(A,C) \
      if (TEST(endstop_hit_bits, A ##_MIN) || TEST(endstop_hit_bits, A ##_MAX)) \
        _ENDSTOP_HIT_ECHO(A,C)

    SERIAL_ECHO_START;
    SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT);
    _ENDSTOP_HIT_TEST(X, 'X');
    _ENDSTOP_HIT_TEST(Y, 'Y');
    _ENDSTOP_HIT_TEST(Z, 'Z');

    #if ENABLED(Z_MIN_PROBE_ENDSTOP)
      #define P_AXIS Z_AXIS
      if (TEST(endstop_hit_bits, Z_MIN_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P');
    #endif
    SERIAL_EOL;

    #if ENABLED(ULTRA_LCD)
      char msg[3 * strlen(MSG_LCD_ENDSTOPS) + 8 + 1]; // Room for a UTF 8 string
      sprintf_P(msg, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP);
      lcd_setstatus(msg);
    #endif

    hit_on_purpose();

    #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && ENABLED(SDSUPPORT)
      if (stepper.abort_on_endstop_hit) {
        card.sdprinting = false;
        card.closefile();
        quickstop_stepper();
        thermalManager.disable_all_heaters(); // switch off all heaters.
      }
    #endif
  }
} // Endstops::report_state
  FORCE_INLINE void emergency_parser(unsigned char c) {

    static e_parser_state state = state_RESET;

    switch (state) {
      case state_RESET:
        switch (c) {
          case ' ': break;
          case 'N': state = state_N;      break;
          case 'M': state = state_M;      break;
          default: state = state_IGNORE;
        }
        break;

      case state_N:
        switch (c) {
          case '0': case '1': case '2':
          case '3': case '4': case '5':
          case '6': case '7': case '8':
          case '9': case '-': case ' ':   break;
          case 'M': state = state_M;      break;
          default:  state = state_IGNORE;
        }
        break;

      case state_M:
        switch (c) {
          case ' ': break;
          case '1': state = state_M1;     break;
          case '4': state = state_M4;     break;
          default: state = state_IGNORE;
        }
        break;

      case state_M1:
        switch (c) {
          case '0': state = state_M10;    break;
          case '1': state = state_M11;    break;
          default: state = state_IGNORE;
        }
        break;

      case state_M10:
        state = (c == '8') ? state_M108 : state_IGNORE;
        break;

      case state_M11:
        state = (c == '2') ? state_M112 : state_IGNORE;
        break;

      case state_M4:
        state = (c == '1') ? state_M41 : state_IGNORE;
        break;

      case state_M41:
        state = (c == '0') ? state_M410 : state_IGNORE;
        break;

      case state_IGNORE:
        if (c == '\n') state = state_RESET;
        break;

      default:
        if (c == '\n') {
          switch (state) {
            case state_M108:
              wait_for_heatup = false;
              break;
            case state_M112:
              kill(PSTR(MSG_KILLED));
              break;
            case state_M410:
              quickstop_stepper();
              break;
            default:
              break;
          }
          state = state_RESET;
        }
    }
  }