diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h
index 8a27d7820..f0dbd0388 100644
--- a/include/hamlib/rig.h
+++ b/include/hamlib/rig.h
@@ -495,7 +495,7 @@ typedef unsigned int vfo_t;
  * \brief Macro for bandpass to be set to normal
  * \def RIG_PASSBAND_NORMAL
  */
-#define RIG_PASSBAND_NORMAL     s_Hz(0) // was 0 but collided with Yasue SH00; capability
+#define RIG_PASSBAND_NORMAL     s_Hz(0) // was 0 but collided with Yaesu SH00; capability
 
 /**
  * \brief Macro for bandpass to be left alone
diff --git a/rigs/yaesu/ft1200.c b/rigs/yaesu/ft1200.c
index 7706d463c..14dacd3fe 100644
--- a/rigs/yaesu/ft1200.c
+++ b/rigs/yaesu/ft1200.c
@@ -112,14 +112,16 @@ const struct rig_caps ftdx1200_caps =
         // cppcheck-suppress *
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
         [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
-    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC */
+    .preamp =             { 10, 20, RIG_DBLST_END, },
     .attenuator =         { 6, 12, 18, RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(9999),
-    .max_ifshift =        Hz(1000),
+    .max_ifshift =        Hz(1200),
     .vfo_ops =            FTDX1200_VFO_OPS,
     .targetable_vfo =     RIG_TARGETABLE_FREQ,
     .transceive =         RIG_TRN_OFF,        /* May enable later as the 1200 has an Auto Info command */
@@ -172,12 +174,11 @@ const struct rig_caps ftdx1200_caps =
         {FTDX1200_FM_RX_MODES,     kHz(1)},    /* Fast */
 
         RIG_TS_END,
-
     },
 
     /* mode/filter list, .remember =  order matters! */
     .filters =            {
-        {FTDX1200_CW_RTTY_PKT_RX_MODES,  Hz(2400)},   /* Normal CW, RTTY, PKT/USER */
+        {FTDX1200_CW_RTTY_PKT_RX_MODES,  Hz(1800)},   /* Normal CW, RTTY, PKT/USER */
         {FTDX1200_CW_RTTY_PKT_RX_MODES,  Hz(500)},    /* Narrow CW, RTTY, PKT/USER */
         {FTDX1200_CW_RTTY_PKT_RX_MODES,  Hz(2400)},   /* Wide   CW, RTTY, PKT/USER */
         {RIG_MODE_SSB,                 Hz(2400)},   /* Normal SSB */
@@ -185,8 +186,10 @@ const struct rig_caps ftdx1200_caps =
         {RIG_MODE_SSB,                 Hz(4000)},   /* Wide   SSB */
         {RIG_MODE_AM,                  Hz(9000)},   /* Normal AM  */
         {RIG_MODE_AM,                  Hz(6000)},   /* Narrow AM  */
-        {FTDX1200_FM_RX_MODES,           Hz(12000)},  /* Normal FM  */
-        {FTDX1200_FM_RX_MODES,           Hz(8000)},   /* Narrow FM  */
+        {FTDX1200_FM_WIDE_RX_MODES,    Hz(16000)},  /* Normal FM  */
+        {FTDX1200_FM_WIDE_RX_MODES,    Hz(9000)},   /* Narrow FM  */
+        {RIG_MODE_FMN,                 Hz(9000)},   /* Narrow FM  */
+        {FTDX1200_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY},
 
         RIG_FLT_END,
     },
diff --git a/rigs/yaesu/ft1200.h b/rigs/yaesu/ft1200.h
index 7910be05a..88afd85de 100644
--- a/rigs/yaesu/ft1200.h
+++ b/rigs/yaesu/ft1200.h
@@ -34,12 +34,13 @@
 /* Receiver caps */
 
 #define FTDX1200_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
-        RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM)
+        RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN)
 
 #define FTDX1200_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
 		RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB)
 #define FTDX1200_AM_RX_MODES (RIG_MODE_AM)
-#define FTDX1200_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM)
+#define FTDX1200_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM)
+#define FTDX1200_FM_RX_MODES (FTDX1200_FM_WIDE_RX_MODES|RIG_MODE_FMN)
 #define FTDX1200_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\
         RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR)
 
diff --git a/rigs/yaesu/ft2000.c b/rigs/yaesu/ft2000.c
index 68ca3398d..af7a73d62 100644
--- a/rigs/yaesu/ft2000.c
+++ b/rigs/yaesu/ft2000.c
@@ -40,12 +40,49 @@
 #include "idx_builtin.h"
 #include "tones.h"
 
-/*
- * ft2000 rigs capabilities.
- * Also this struct is READONLY!
- *
- */
+const struct newcat_priv_caps ft2000_priv_caps =
+{
+    .roofing_filter_count = 7,
+    .roofing_filters =
+        {
+            // The index must match ext level combo index
+            { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 },
+            { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 },
+            { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 },
+            { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 },
+            { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 },
+            { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 },
+            { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 },
+        }
+};
 
+const struct confparams ft2000_ext_levels[] =
+{
+    {
+        TOK_ROOFING_FILTER,
+        "ROOFINGFILTER",
+        "Roofing filter",
+        "Roofing filter",
+        NULL,
+        RIG_CONF_COMBO,
+        { .c = { .combostr = {
+                "AUTO", "15 kHz", "6 kHz", "3 kHz",
+                "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz",
+                NULL }
+        } }
+    },
+    { RIG_CONF_END, NULL, }
+};
+
+int ft2000_ext_tokens[] =
+{
+    TOK_ROOFING_FILTER, TOK_BACKEND_NONE
+};
+
+
+/*
+ * FT-2000 rig capabilities
+ */
 const struct rig_caps ft2000_caps =
 {
     RIG_MODEL(RIG_MODEL_FT2000),
@@ -78,10 +115,12 @@ const struct rig_caps ft2000_caps =
         // cppcheck-suppress *
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
         [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
-    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC */
+    .preamp =             { 10, 17, RIG_DBLST_END, },
     .attenuator =         { 6, 12, 18, RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(9999),
@@ -138,7 +177,6 @@ const struct rig_caps ft2000_caps =
         {FT2000_FM_RX_MODES,     kHz(1)},    /* Fast */
 
         RIG_TS_END,
-
     },
 
     /* mode/filter list, .remember =  order matters! */
@@ -157,7 +195,10 @@ const struct rig_caps ft2000_caps =
         RIG_FLT_END,
     },
 
-    .priv =               NULL,
+    .ext_tokens =         ft2000_ext_tokens,
+    .extlevels =          ft2000_ext_levels,
+
+    .priv =               &ft2000_priv_caps,
 
     .rig_init =           newcat_init,
     .rig_cleanup =        newcat_cleanup,
@@ -207,5 +248,7 @@ const struct rig_caps ft2000_caps =
     .get_trn =            newcat_get_trn,
     .set_channel =        newcat_set_channel,
     .get_channel =        newcat_get_channel,
+    .set_ext_level =      newcat_set_ext_level,
+    .get_ext_level =      newcat_get_ext_level,
 
 };
diff --git a/rigs/yaesu/ft3000.c b/rigs/yaesu/ft3000.c
index 516a181b4..32f245504 100644
--- a/rigs/yaesu/ft3000.c
+++ b/rigs/yaesu/ft3000.c
@@ -115,11 +115,13 @@ const struct rig_caps ftdx3000_caps =
     .has_set_parm =       RIG_PARM_NONE,
     .level_gran = {
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
-        [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } },
+        [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
-    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC */
+    .preamp =             { 10, 17, RIG_DBLST_END, },
     .attenuator =         { 6, 12, 18, RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(9999),
@@ -138,7 +140,7 @@ const struct rig_caps ftdx3000_caps =
 
     .rx_range_list1 =     {
         /* General coverage + ham, ANT_5 is RX only antenna */
-        {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "USA"},
+        {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS, "USA"},
         RIG_FRNG_END,
     },
 
@@ -152,7 +154,7 @@ const struct rig_caps ftdx3000_caps =
     },
 
     .rx_range_list2 =     {
-        {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "EUR"},
+        {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS, "EUR"},
         RIG_FRNG_END,
     },
 
@@ -176,7 +178,6 @@ const struct rig_caps ftdx3000_caps =
         {FTDX5000_FM_RX_MODES,     kHz(1)},    /* Fast */
 
         RIG_TS_END,
-
     },
 
     /* mode/filter list, .remember =  order matters! */
@@ -184,13 +185,14 @@ const struct rig_caps ftdx3000_caps =
         {FTDX5000_CW_RTTY_PKT_RX_MODES,  Hz(1800)},   /* Normal CW, RTTY, PKT/USER */
         {FTDX5000_CW_RTTY_PKT_RX_MODES,  Hz(500)},    /* Narrow CW, RTTY, PKT/USER */
         {FTDX5000_CW_RTTY_PKT_RX_MODES,  Hz(2400)},   /* Wide   CW, RTTY, PKT/USER */
-        {RIG_MODE_SSB,                 Hz(2400)},   /* Normal SSB */
-        {RIG_MODE_SSB,                 Hz(1800)},   /* Narrow SSB */
-        {RIG_MODE_SSB,                 Hz(3000)},   /* Wide   SSB */
-        {RIG_MODE_AM,                  Hz(9000)},   /* Normal AM  */
-        {RIG_MODE_AM,                  Hz(6000)},   /* Narrow AM  */
-        {FTDX5000_FM_RX_MODES,           Hz(15000)},  /* Normal FM  */
-        {FTDX5000_FM_RX_MODES,           Hz(8000)},   /* Narrow FM  */
+        {RIG_MODE_SSB,                   Hz(2400)},   /* Normal SSB */
+        {RIG_MODE_SSB,                   Hz(1800)},   /* Narrow SSB */
+        {RIG_MODE_SSB,                   Hz(4000)},   /* Wide   SSB */
+        {FTDX5000_AM_RX_MODES,           Hz(9000)},   /* Normal AM  */
+        {FTDX5000_AM_RX_MODES,           Hz(6000)},   /* Narrow AM  */
+        {FTDX5000_FM_RX_MODES,           Hz(16000)},  /* Normal FM  */
+        {FTDX5000_FM_RX_MODES,           Hz(9000)},   /* Narrow FM  */
+        {FTDX5000_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY},
 
         RIG_FLT_END,
     },
diff --git a/rigs/yaesu/ft450.c b/rigs/yaesu/ft450.c
index 057c86e95..98857ed43 100644
--- a/rigs/yaesu/ft450.c
+++ b/rigs/yaesu/ft450.c
@@ -77,11 +77,13 @@ const struct rig_caps ft450_caps =
         // cppcheck-suppress *
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
         [LVL_CWPITCH] = { .min = { .i = 400 }, .max = { .i = 800 }, .step = { .i = 100 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
-    .preamp =             { 10, RIG_DBLST_END, }, /* TBC */
-    .attenuator =         { 18, RIG_DBLST_END, }, /* TBC */
+    .preamp =             { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */
+    .attenuator =         { 20, RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(0),
     .max_ifshift =        Hz(1000),
diff --git a/rigs/yaesu/ft5000.c b/rigs/yaesu/ft5000.c
index c02df103a..cfb13e238 100644
--- a/rigs/yaesu/ft5000.c
+++ b/rigs/yaesu/ft5000.c
@@ -110,11 +110,13 @@ const struct rig_caps ftdx5000_caps =
     .level_gran = {
         // cppcheck-suppress *
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
-        [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } },
+        [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
-    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC */
+    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC: Not specified in manual */
     .attenuator =         { 6, 12, 18, RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(9999),
@@ -171,21 +173,21 @@ const struct rig_caps ftdx5000_caps =
         {FTDX5000_FM_RX_MODES,     kHz(1)},    /* Fast */
 
         RIG_TS_END,
-
     },
 
     /* mode/filter list, .remember =  order matters! */
     .filters =            {
-        {FTDX5000_CW_RTTY_PKT_RX_MODES,  Hz(1800)},   /* Normal CW, RTTY, PKT/USER */
+        {FTDX5000_CW_RTTY_PKT_RX_MODES,  Hz(1700)},   /* Normal CW, RTTY, PKT/USER */
         {FTDX5000_CW_RTTY_PKT_RX_MODES,  Hz(500)},    /* Narrow CW, RTTY, PKT/USER */
         {FTDX5000_CW_RTTY_PKT_RX_MODES,  Hz(2400)},   /* Wide   CW, RTTY, PKT/USER */
         {RIG_MODE_SSB,                 Hz(2400)},   /* Normal SSB */
         {RIG_MODE_SSB,                 Hz(1800)},   /* Narrow SSB */
-        {RIG_MODE_SSB,                 Hz(3000)},   /* Wide   SSB */
-        {RIG_MODE_AM,                  Hz(9000)},   /* Normal AM  */
-        {RIG_MODE_AM,                  Hz(6000)},   /* Narrow AM  */
-        {FTDX5000_FM_RX_MODES,           Hz(15000)},  /* Normal FM  */
-        {FTDX5000_FM_RX_MODES,           Hz(8000)},   /* Narrow FM  */
+        {RIG_MODE_SSB,                 Hz(4000)},   /* Wide   SSB */
+        {FTDX5000_AM_RX_MODES,         Hz(9000)},   /* Normal AM  */
+        {FTDX5000_AM_RX_MODES,         Hz(6000)},   /* Narrow AM  */
+        {FTDX5000_FM_RX_MODES,         Hz(16000)},  /* Normal FM  */
+        {FTDX5000_FM_RX_MODES,         Hz(9000)},   /* Narrow FM  */
+        {FTDX5000_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY},
 
         RIG_FLT_END,
     },
diff --git a/rigs/yaesu/ft5000.h b/rigs/yaesu/ft5000.h
index db32b61b6..7b045376e 100644
--- a/rigs/yaesu/ft5000.h
+++ b/rigs/yaesu/ft5000.h
@@ -32,13 +32,13 @@
 
 /* Receiver caps */
 
-#define FTDX5000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
+#define FTDX5000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
         RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\
         RIG_MODE_FM|RIG_MODE_FMN)
 
 #define FTDX5000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
 		RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB)
-#define FTDX5000_AM_RX_MODES (RIG_MODE_AM)
+#define FTDX5000_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN)
 #define FTDX5000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN)
 #define FTDX5000_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\
         RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR)
@@ -47,7 +47,7 @@
 
 #define FTDX5000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \
 		                RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) /* 100 W class */
-#define FTDX5000_AM_TX_MODES (RIG_MODE_AM)    /* set 25W max */
+#define FTDX5000_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN)    /* set 25W max */
 
 /* TBC */
 #define FTDX5000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\
@@ -100,7 +100,7 @@
  *
  */
 
-#define FTDX5000_TX_ANTS  (RIG_ANT_1|RIG_ANT_2)
+#define FTDX5000_TX_ANTS  (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4)
 
 #define FTDX5000_MEM_CHNL_LENGTH           1       /* 0x10 P1 = 01 return size */
 #define FTDX5000_OP_DATA_LENGTH            19      /* 0x10 P1 = 03 return size */
diff --git a/rigs/yaesu/ft891.c b/rigs/yaesu/ft891.c
index da1997b08..3a73d4fb2 100644
--- a/rigs/yaesu/ft891.c
+++ b/rigs/yaesu/ft891.c
@@ -77,14 +77,16 @@ const struct rig_caps ft891_caps =
         // cppcheck-suppress *
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
         [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
-    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC */
-    .attenuator =         { 6, 12, 18, RIG_DBLST_END, },
+    .preamp =             { 10, RIG_DBLST_END, }, /* TBC */
+    .attenuator =         { 12, RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(9999),
-    .max_ifshift =        Hz(1000),
+    .max_ifshift =        Hz(1200),
     .vfo_ops =            FT891_VFO_OPS,
     .targetable_vfo =     RIG_TARGETABLE_FREQ,
     .transceive =         RIG_TRN_OFF,        /* May enable later as the 950 has an Auto Info command */
@@ -170,6 +172,7 @@ const struct rig_caps ft891_caps =
         {RIG_MODE_SSB,                Hz(600)},     /*        SSB */
         {RIG_MODE_SSB,                Hz(400)},     /*        SSB */
         {RIG_MODE_SSB,                Hz(200)},     /*        SSB */
+        {FT891_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY },
         {RIG_MODE_AM,                 Hz(9000)},    /* Normal AM */
         {RIG_MODE_AM,                 Hz(6000)},    /* Narrow AM */
         {FT891_FM_RX_MODES,           Hz(16000)},   /* Normal FM */
@@ -200,8 +203,6 @@ const struct rig_caps ft891_caps =
     .get_rit =            newcat_get_rit,
     .set_xit =            newcat_set_xit,
     .get_xit =            newcat_get_xit,
-    .set_ant =            newcat_set_ant,
-    .get_ant =            newcat_get_ant,
     .get_func =           newcat_get_func,
     .set_func =           newcat_set_func,
     .get_level =          newcat_get_level,
diff --git a/rigs/yaesu/ft891.h b/rigs/yaesu/ft891.h
index e95401aee..6a3b541f0 100644
--- a/rigs/yaesu/ft891.h
+++ b/rigs/yaesu/ft891.h
@@ -95,7 +95,7 @@
  *
  */
 
-#define FT891_ANTS  (RIG_ANT_1|RIG_ANT_2)
+#define FT891_ANTS  (RIG_ANT_CURR)
 
 #define FT891_MEM_CHNL_LENGTH           1       /* 0x10 P1 = 01 return size */
 #define FT891_OP_DATA_LENGTH            19      /* 0x10 P1 = 03 return size */
diff --git a/rigs/yaesu/ft9000.c b/rigs/yaesu/ft9000.c
index b0d626ae3..149a43df3 100644
--- a/rigs/yaesu/ft9000.c
+++ b/rigs/yaesu/ft9000.c
@@ -78,11 +78,13 @@ const struct rig_caps ft9000_caps =
         // cppcheck-suppress *
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
         [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
-    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC */
-    .attenuator =         { 6, 12, 18, RIG_DBLST_END, },
+    .preamp =             { 10,  RIG_DBLST_END, }, /* TBC: Not specified in manual */
+    .attenuator =         { RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(9999),
     .max_ifshift =        Hz(1000),
diff --git a/rigs/yaesu/ft9000.h b/rigs/yaesu/ft9000.h
index 5cfc27d71..03525832d 100644
--- a/rigs/yaesu/ft9000.h
+++ b/rigs/yaesu/ft9000.h
@@ -68,14 +68,13 @@
                RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\
                RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\
                RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\
-               RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF)
+               RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|RIG_LEVEL_MONITOR_GAIN)
 
 /* TBC */
 #define FT9000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\
-               RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\
-               RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\
-               RIG_FUNC_RIT|RIG_FUNC_XIT\
-               )
+               RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\
+               RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|\
+               RIG_FUNC_RIT|RIG_FUNC_XIT)
 
 /* TBC */
 #define FT9000_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\
diff --git a/rigs/yaesu/ft950.c b/rigs/yaesu/ft950.c
index 6703daa93..27bba7c0f 100644
--- a/rigs/yaesu/ft950.c
+++ b/rigs/yaesu/ft950.c
@@ -25,7 +25,6 @@
  *
  */
 
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -39,12 +38,48 @@
 #include "ft950.h"
 #include "idx_builtin.h"
 
-/*
- * ft950 rigs capabilities.
- * Also this struct is READONLY!
- *
- */
+const struct newcat_priv_caps ft950_priv_caps =
+{
+    .roofing_filter_count = 7,
+    .roofing_filters =
+        {
+            // The index must match ext level combo index
+            { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 },
+            { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 },
+            { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 },
+            { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 },
+            { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 },
+            { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 },
+            { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 },
+        }
+};
 
+const struct confparams ft950_ext_levels[] =
+{
+    {
+        TOK_ROOFING_FILTER,
+        "ROOFINGFILTER",
+        "Roofing filter",
+        "Roofing filter",
+        NULL,
+        RIG_CONF_COMBO,
+        { .c = { .combostr = {
+                "AUTO", "15 kHz", "6 kHz", "3 kHz",
+                "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz",
+                NULL }
+        } }
+    },
+    { RIG_CONF_END, NULL, }
+};
+
+int ft950_ext_tokens[] =
+{
+    TOK_ROOFING_FILTER, TOK_BACKEND_NONE
+};
+
+/*
+ * FT-950 rig capabilities
+ */
 const struct rig_caps ft950_caps =
 {
     RIG_MODEL(RIG_MODEL_FT950),
@@ -77,10 +112,12 @@ const struct rig_caps ft950_caps =
         // cppcheck-suppress *
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
         [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
-    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC */
+    .preamp =             { 10, 17, RIG_DBLST_END, },
     .attenuator =         { 6, 12, 18, RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(9999),
@@ -140,7 +177,6 @@ const struct rig_caps ft950_caps =
         {FT950_FM_RX_MODES,     kHz(1)},    /* Fast */
 
         RIG_TS_END,
-
     },
 
     /* mode/filter list, .remember =  order matters! */
@@ -177,22 +213,25 @@ const struct rig_caps ft950_caps =
         {RIG_MODE_SSB,                Hz(200)},     /*        SSB */
         {RIG_MODE_AM,                 Hz(9000)},    /* Normal AM */
         {RIG_MODE_AM,                 Hz(6000)},    /* Narrow AM */
-        {FT950_FM_RX_MODES,           Hz(16000)},   /* Normal FM */
-        {FT950_FM_RX_MODES,           Hz(9000)},    /* Narrow FM */
+        {FT950_FM_WIDE_RX_MODES,      Hz(16000)},   /* Normal FM */
+        {FT950_FM_WIDE_RX_MODES,      Hz(9000)},    /* Narrow FM */
+        {RIG_MODE_FMN,                Hz(9000)},    /* Narrow FM */
+        {FT950_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY},
 
         RIG_FLT_END,
     },
 
+    .ext_tokens =         ft950_ext_tokens,
+    .extlevels =          ft950_ext_levels,
 
-
-    .priv =               NULL,           /* private data FIXME: */
+    .priv =               &ft950_priv_caps,
 
     .rig_init =           newcat_init,
     .rig_cleanup =        newcat_cleanup,
     .rig_open =           newcat_open,     /* port opened */
     .rig_close =          newcat_close,    /* port closed */
 
-    .cfgparams =            newcat_cfg_params,
+    .cfgparams =          newcat_cfg_params,
     .set_conf =           newcat_set_conf,
     .get_conf =           newcat_get_conf,
     .set_freq =           newcat_set_freq,
@@ -235,5 +274,7 @@ const struct rig_caps ft950_caps =
     .get_trn =            newcat_get_trn,
     .set_channel =        newcat_set_channel,
     .get_channel =        newcat_get_channel,
+    .set_ext_level =      newcat_set_ext_level,
+    .get_ext_level =      newcat_get_ext_level,
 
 };
diff --git a/rigs/yaesu/ft950.h b/rigs/yaesu/ft950.h
index 64c4961d0..09de523e1 100644
--- a/rigs/yaesu/ft950.h
+++ b/rigs/yaesu/ft950.h
@@ -38,19 +38,20 @@
 /* Receiver caps */
 
 #define FT950_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
-		RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM)
+		RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FMN)
 #define FT950_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
 		RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB)
 #define FT950_AM_RX_MODES (RIG_MODE_AM)
-#define FT950_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM)
+#define FT950_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM)
+#define FT950_FM_RX_MODES (FT950_FM_WIDE_RX_MODES|RIG_MODE_FMN)
 #define FT950_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR)
 #define FT950_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\
         RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR)
 
 /* TRX caps */
 
-#define FT950_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */
-#define FT950_AM_TX_MODES (RIG_MODE_AM )    /* set 25W max */
+#define FT950_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB) /* 100 W class */
+#define FT950_AM_TX_MODES (RIG_MODE_AM)    /* set 25W max */
 
 #define FT950_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\
                RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\
diff --git a/rigs/yaesu/ft991.c b/rigs/yaesu/ft991.c
index 0db7f3fcf..e643c0253 100644
--- a/rigs/yaesu/ft991.c
+++ b/rigs/yaesu/ft991.c
@@ -76,14 +76,16 @@ const struct rig_caps ft991_caps =
         // cppcheck-suppress *
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
         [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           common_dcs_list,
-    .preamp =             { 10, 20, RIG_DBLST_END, }, /* TBC */
-    .attenuator =         { 6, 12, 18, RIG_DBLST_END, },
+    .preamp =             { 10, 20, RIG_DBLST_END, },
+    .attenuator =         { 12, RIG_DBLST_END, },
     .max_rit =            Hz(9999),
     .max_xit =            Hz(9999),
-    .max_ifshift =        Hz(1000),
+    .max_ifshift =        Hz(1200),
     .vfo_ops =            FT991_VFO_OPS,
     .targetable_vfo =     RIG_TARGETABLE_FREQ,
     .transceive =         RIG_TRN_OFF,        /* May enable later as the 950 has an Auto Info command */
@@ -161,10 +163,11 @@ const struct rig_caps ft991_caps =
         {RIG_MODE_SSB,                Hz(600)},     /*        SSB */
         {RIG_MODE_SSB,                Hz(400)},     /*        SSB */
         {RIG_MODE_SSB,                Hz(200)},     /*        SSB */
+        {FT991_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY },
         {RIG_MODE_AM,                 Hz(9000)},    /* Normal AM */
-        {RIG_MODE_AMN,                 Hz(6000)},    /* Narrow AM */
-        {FT991_FM_RX_MODES,           Hz(16000)},   /* Normal FM */
-        {FT991_FM_RX_MODES,           Hz(9000)},    /* Narrow FM */
+        {RIG_MODE_AMN,                Hz(6000)},    /* Narrow AM */
+        {FT991_FM_WIDE_RX_MODES,      Hz(16000)},   /* Normal FM */
+        {RIG_MODE_FMN,                Hz(9000)},    /* Narrow FM */
 
         RIG_FLT_END,
     },
@@ -192,8 +195,6 @@ const struct rig_caps ft991_caps =
     .get_rit =            newcat_get_rit,
     .set_xit =            newcat_set_xit,
     .get_xit =            newcat_get_xit,
-    .set_ant =            newcat_set_ant,
-    .get_ant =            newcat_get_ant,
     .get_func =           newcat_get_func,
     .set_func =           newcat_set_func,
     .get_level =          newcat_get_level,
diff --git a/rigs/yaesu/ft991.h b/rigs/yaesu/ft991.h
index 4557d1a13..159aeeac0 100644
--- a/rigs/yaesu/ft991.h
+++ b/rigs/yaesu/ft991.h
@@ -38,7 +38,8 @@
 #define FT991_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
         RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB)
 #define FT991_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN)
-#define FT991_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_C4FM)
+#define FT991_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_C4FM)
+#define FT991_FM_RX_MODES (FT991_FM_WIDE_RX_MODES|RIG_MODE_FMN)
 #define FT991_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR)
 #define FT991_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\
         RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR)
diff --git a/rigs/yaesu/ftdx101.c b/rigs/yaesu/ftdx101.c
index a330c1e10..75b3668af 100644
--- a/rigs/yaesu/ftdx101.c
+++ b/rigs/yaesu/ftdx101.c
@@ -104,6 +104,8 @@ const struct rig_caps ftdx101d_caps =
     .level_gran = {
         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
         [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } },
+        [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } },
+        [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } },
     },
     .ctcss_list =         common_ctcss_list,
     .dcs_list =           NULL,
@@ -125,7 +127,7 @@ const struct rig_caps ftdx101d_caps =
 
     .rx_range_list1 =     {
         /* General coverage + ham, ANT_5 is RX only antenna */
-        {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS | RIG_ANT_5, "USA"},
+        {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "USA"},
         RIG_FRNG_END,
     },
 
@@ -139,7 +141,7 @@ const struct rig_caps ftdx101d_caps =
     },
 
     .rx_range_list2 =     {
-        {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS | RIG_ANT_5, "EUR"},
+        {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "EUR"},
         RIG_FRNG_END,
     },
 
diff --git a/rigs/yaesu/ftdx101.h b/rigs/yaesu/ftdx101.h
index 66be4a8a5..5e0309f4b 100644
--- a/rigs/yaesu/ftdx101.h
+++ b/rigs/yaesu/ftdx101.h
@@ -91,7 +91,7 @@
  * Other features (used by rig_caps)
  */
 
-#define FTDX101_TX_ANTS  (RIG_ANT_1|RIG_ANT_2)
+#define FTDX101_TX_ANTS  (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3)
 
 #define FTDX101_MEM_CHNL_LENGTH           1       /* 0x10 P1 = 01 return size */
 #define FTDX101_OP_DATA_LENGTH            19      /* 0x10 P1 = 03 return size */
diff --git a/rigs/yaesu/newcat.c b/rigs/yaesu/newcat.c
index 3a410cbbd..24e760196 100644
--- a/rigs/yaesu/newcat.c
+++ b/rigs/yaesu/newcat.c
@@ -203,7 +203,7 @@ static ncboolean is_ft891;
 static ncboolean is_ft950;
 static ncboolean is_ft991;
 static ncboolean is_ft2000;
-static ncboolean is_ft9000;
+static ncboolean is_ftdx9000;
 static ncboolean is_ftdx5000;
 static ncboolean is_ftdx1200;
 static ncboolean is_ftdx3000;
@@ -2849,25 +2849,34 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
 
         switch (val.i)
         {
-        case RIG_AGC_OFF:    snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT00;");
+        case RIG_AGC_OFF:
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT00;");
             break;
 
-        case RIG_AGC_FAST:   snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT01;");
+        case RIG_AGC_FAST:
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT01;");
             break;
 
-        case RIG_AGC_MEDIUM: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT02;");
+        case RIG_AGC_MEDIUM:
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT02;");
             break;
 
-        case RIG_AGC_SLOW:   snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT03;");
+        case RIG_AGC_SLOW:
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT03;");
             break;
 
-        case RIG_AGC_AUTO:   snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT04;");
+        case RIG_AGC_AUTO:
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT04;");
             break;
 
-        default: return -RIG_EINVAL;
+        default:
+            return -RIG_EINVAL;
         }
 
-        priv->cmd_str[2] = main_sub_vfo;
+        if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
+        {
+            priv->cmd_str[2] = main_sub_vfo;
+        }
         break;
 
     case RIG_LEVEL_IF:
@@ -2895,6 +2904,11 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS%c0%+.4d%c", main_sub_vfo,
                      val.i, cat_term);
         }
+        else if (is_ft891)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS0%d%+.4d%c", val.i == 0 ? 0 : 1,
+                     val.i, cat_term);
+        }
         else
         {
             snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS%c%+.4d%c", main_sub_vfo,
@@ -2906,9 +2920,12 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             priv->cmd_str[2] = main_sub_vfo;
         }
 
+        // Some Yaesu rigs reject this command in AM/FM modes
+        priv->question_mark_response_means_rejected = 1;
         break;
 
-    case RIG_LEVEL_CWPITCH:
+    case RIG_LEVEL_CWPITCH: {
+        int kp;
         if (!newcat_valid_command(rig, "KP"))
         {
             return -RIG_ENAVAIL;
@@ -2927,9 +2944,19 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             i = val.i;
         }
 
-        snprintf(priv->cmd_str, sizeof(priv->cmd_str), "KP%02d%c",
-                 2 * ((i + 50 - 300) / 100), cat_term);
+        if (is_ft950 || is_ft2000)
+        {
+            kp = (i - 300) / 50;
+        }
+        else
+        {
+            // Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps
+            kp = (i - 300) / 10;
+        }
+
+        snprintf(priv->cmd_str, sizeof(priv->cmd_str), "KP%02d%c", kp, cat_term);
         break;
+    }
 
     case RIG_LEVEL_KEYSPD:
         if (!newcat_valid_command(rig, "KS"))
@@ -2956,6 +2983,9 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
         }
 
         snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MG%03d%c", fpf, cat_term);
+
+        // Some Yaesu rigs reject this command in RTTY modes
+        priv->question_mark_response_means_rejected = 1;
         break;
 
     case RIG_LEVEL_METER:
@@ -3037,23 +3067,25 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
         priv->cmd_str[0] = '\0';
 
         for (i = 0; state->preamp[i] != RIG_DBLST_END; i++)
+        {
             if (state->preamp[i] == val.i)
             {
                 snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PA0%d%c", i + 1, cat_term);
                 break;
             }
-
-        if (strlen(priv->cmd_str) != 0)
-        {
-            if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
-            {
-                priv->cmd_str[2] = main_sub_vfo;
-            }
-
-            break;
         }
 
-        return -RIG_EINVAL;
+        if (strlen(priv->cmd_str) == 0)
+        {
+            return -RIG_EINVAL;
+        }
+
+        if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
+        {
+            priv->cmd_str[2] = main_sub_vfo;
+        }
+
+        break;
 
     case RIG_LEVEL_ATT:
         if (!newcat_valid_command(rig, "RA"))
@@ -3076,23 +3108,25 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
         priv->cmd_str[0] = '\0';
 
         for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++)
+        {
             if (state->attenuator[i] == val.i)
             {
                 snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RA0%d%c", i + 1, cat_term);
-                break;  /* for loop */
+                break;
             }
-
-        if (strlen(priv->cmd_str) != 0)
-        {
-            if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
-            {
-                priv->cmd_str[2] = main_sub_vfo;
-            }
-
-            break;
         }
 
-        return -RIG_EINVAL;
+        if (strlen(priv->cmd_str) == 0)
+        {
+            return -RIG_EINVAL;
+        }
+
+        if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
+        {
+            priv->cmd_str[2] = main_sub_vfo;
+        }
+
+        break;
 
     case RIG_LEVEL_RF:
         if (!newcat_valid_command(rig, "RG"))
@@ -3100,7 +3134,16 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             return -RIG_ENAVAIL;
         }
 
-        fpf = newcat_scale_float(255, val.f);
+        if (is_ft891)
+        {
+            scale = 30;
+        }
+        else
+        {
+            scale = 255;
+        }
+
+        fpf = newcat_scale_float(scale, val.f);
         snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RG%c%03d%c", main_sub_vfo, fpf,
                  cat_term);
         break;
@@ -3149,6 +3192,8 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             }
         }
 
+        // Some Yaesu rigs reject this command in AM/FM modes
+        priv->question_mark_response_means_rejected = 1;
         break;
 
     case RIG_LEVEL_COMP:
@@ -3157,74 +3202,107 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             return -RIG_ENAVAIL;
         }
 
-        scale = (is_ft950) ? 100 : 255;
-        scale = (is_ftdx1200 || is_ftdx101) ? 100 : scale ;
+        if (is_ft2000 || is_ftdx9000 || is_ftdx5000)
+        {
+            scale = 255;
+        }
+        else
+        {
+            scale = 100;
+        }
+
         fpf = newcat_scale_float(scale, val.f);
         snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PL%03d%c", fpf, cat_term);
         break;
 
-    case RIG_LEVEL_BKINDL:
+    case RIG_LEVEL_BKINDL: {
+        int millis;
+        value_t keyspd;
 
-        /* Standard: word "PARIS" == 50 Unit Intervals, UIs */
-        /* 1 dot == 2 UIs */
-        /* tenth_dots-per-second -to- milliseconds */
         if (!newcat_valid_command(rig, "SD"))
         {
             return -RIG_ENAVAIL;
         }
 
-        // we don't get full resolution as long as val->i is in integer tenths
-        // consider changing this to float or to milliseconds
-        val.i *= 100; // tenths to ms conversion
+        // Convert 10/ths of dots to milliseconds using the current key speed
+        err = newcat_get_level(rig, vfo, RIG_LEVEL_KEYSPD, &keyspd);
+        if (err != RIG_OK)
+        {
+            return err;
+        }
+
+        millis = dot10ths_to_millis(val.i, keyspd.i);
 
         if (is_ftdx101)
         {
-            if (val.i <= 30) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD00;"); }
-
-            else if (val.i <= 50) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD01;"); }
-
-            else if (val.i <= 100) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD02;"); }
-
-            else if (val.i <= 150) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD03;"); }
-
-            else if (val.i <= 200) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD04;"); }
-
-            else if (val.i <= 250) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD05;"); }
-
-            else if (val.i > 2900) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD33;"); }
-            // this covers 300-2900 06-32
-            else { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%02d;", 6 + ((val.i - 300) / 100)); }
+            if (millis <= 30) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD00;"); }
+            else if (millis <= 50) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD01;"); }
+            else if (millis <= 100) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD02;"); }
+            else if (millis <= 150) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD03;"); }
+            else if (millis <= 200) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD04;"); }
+            else if (millis <= 250) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD05;"); }
+            else if (millis > 2900) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD33;"); }
+            else
+            {
+                // This covers 300-2900 06-32
+                snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%02d;", 6 + ((millis - 300) / 100));
+            }
         }
-        else if (is_ft950 || is_ft450 || is_ftdx1200)
+        else if (is_ftdx5000)
         {
-            if (val.i < 30)
+            if (millis < 20)
             {
-                val.i = 30;
+                millis = 20;
+            }
+            if (millis > 5000)
+            {
+                millis = 5000;
             }
 
-            if (val.i > 3000)
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term);
+        }
+        else if (is_ft950 || is_ft450 || is_ft891 || is_ft991 || is_ftdx1200 || is_ftdx3000)
+        {
+            if (millis < 30)
             {
-                val.i = 3000;
+                millis = 30;
+            }
+            if (millis > 3000)
+            {
+                millis = 3000;
             }
 
-            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", val.i, cat_term);
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term);
+        }
+        else if (is_ft2000 || is_ftdx9000)
+        {
+            if (millis < 0)
+            {
+                millis = 0;
+            }
+            if (millis > 5000)
+            {
+                millis = 5000;
+            }
+
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term);
         }
         else // default
         {
-            if (val.i < 1)
+            if (millis < 1)
             {
-                val.i = 1;
+                millis = 1;
+            }
+            if (millis > 5000)
+            {
+                millis = 5000;
             }
 
-            if (val.i > 5000)
-            {
-                val.i = 5000;
-            }
-
-            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", val.i, cat_term);
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term);
         }
 
         break;
+    }
 
     case RIG_LEVEL_SQL:
         if (!newcat_valid_command(rig, "SQ"))
@@ -3232,7 +3310,16 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             return -RIG_ENAVAIL;
         }
 
-        fpf = newcat_scale_float(255, val.f);
+        if (is_ft891 || is_ft991 || is_ftdx101)
+        {
+            scale = 100;
+        }
+        else
+        {
+            scale = 255;
+        }
+
+        fpf = newcat_scale_float(scale, val.f);
         snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SQ%c%03d%c", main_sub_vfo, fpf,
                  cat_term);
         break;
@@ -3303,28 +3390,55 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             return -RIG_ENAVAIL;
         }
 
-        scale = (is_ft950 || is_ftdx101) ? 100 : 255;
-        scale = (is_ftdx1200) ? 100 : scale;
+        if (is_ft2000 || is_ftdx9000 || is_ftdx5000)
+        {
+            scale = 255;
+        }
+        else
+        {
+            scale = 100;
+        }
+
         fpf = newcat_scale_float(scale, val.f);
         snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VG%03d%c", fpf, cat_term);
         break;
 
     case RIG_LEVEL_ANTIVOX:
-        if (is_ft950)
-        {
-            fpf = newcat_scale_float(100, val.f);
-            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%03d%c", fpf, cat_term);
-        }
-        else if (is_ftdx101)
+        if (is_ftdx101)
         {
             fpf = newcat_scale_float(100, val.f);
             snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AV%03d%c", fpf, cat_term);
         }
-        else if (is_ftdx1200)
+        else if (is_ftdx5000)
+        {
+            fpf = newcat_scale_float(100, val.f);
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX176%03d%c", fpf, cat_term);
+        }
+        else if (is_ftdx3000 || is_ftdx1200)
         {
             fpf = newcat_scale_float(100, val.f);
             snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%03d%c", fpf, cat_term);
         }
+        else if (is_ft991)
+        {
+            fpf = newcat_scale_float(100, val.f);
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX147%03d%c", fpf, cat_term);
+        }
+        else if (is_ft891)
+        {
+            fpf = newcat_scale_float(100, val.f);
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX1619%03d%c", fpf, cat_term);
+        }
+        else if (is_ft950)
+        {
+            fpf = newcat_scale_float(100, val.f);
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%03d%c", fpf, cat_term);
+        }
+        else if (is_ft2000)
+        {
+            fpf = newcat_scale_float(100, val.f);
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX042%03d%c", fpf, cat_term);
+        }
         else
         {
             return -RIG_EINVAL;
@@ -3340,12 +3454,29 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
 
         val.i = val.i / 10;
 
-        if (val.i < 1)      /* fix lower bounds limit */
+        if (is_ftdx9000)
         {
-            val.i = 1;
+            if (val.i < 0)
+            {
+                val.i = 0;
+            }
+        }
+        else
+        {
+            if (val.i < 1)
+            {
+                val.i = 1;
+            }
         }
 
-        if (newcat_is_rig(rig, RIG_MODEL_FT950))
+        if (is_ft891 || is_ft991 || is_ftdx101)
+        {
+            if (val.i > 320)
+            {
+                val.i = 320;
+            }
+        }
+        if (is_ft950 || is_ftdx9000)
         {
             if (val.i > 300)
             {
@@ -3362,14 +3493,14 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
 
         snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP01%03d%c", val.i, cat_term);
 
-        if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE && !is_ft9000)
-        {
-            priv->cmd_str[2] = main_sub_vfo;
-        }
-        else if (is_ft9000) // different BP command format
+        if (is_ftdx9000)
         {
             snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP%03d%c", val.i, cat_term);
         }
+        else if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
+        {
+            priv->cmd_str[2] = main_sub_vfo;
+        }
 
         break;
 
@@ -3388,14 +3519,26 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
             fpf = newcat_scale_float(255, val.f);
         }
 
-        snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%03d%c", fpf, cat_term);
+        if (is_ftdx9000)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML%03d%c", fpf, cat_term);
+        }
+        else
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%03d%c", fpf, cat_term);
+        }
         break;
 
     default:
         return -RIG_EINVAL;
     }
 
-    return newcat_set_cmd(rig);
+    err = newcat_set_cmd(rig);
+
+    // Clear flag after executing command
+    priv->question_mark_response_means_rejected = 0;
+
+    return err;
 }
 
 
@@ -3409,6 +3552,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
     int retlvl_len;
     float scale;
     char main_sub_vfo = '0';
+    int i;
 
     rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
 
@@ -3484,7 +3628,6 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
         {
             priv->cmd_str[2] = main_sub_vfo;
         }
-
         break;
 
     case RIG_LEVEL_CWPITCH:
@@ -3578,7 +3721,6 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
             return -RIG_ENAVAIL;
         }
 
-        /* should be tenth of dots */
         snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%c", cat_term);
         break;
 
@@ -3681,18 +3823,38 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
         break;
 
     case RIG_LEVEL_ANTIVOX:
-        if (is_ft950)
-        {
-            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%c", cat_term);
-        }
-        else if (is_ftdx101)
+        if (is_ftdx101)
         {
             snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AV%c", cat_term);
         }
+        else if (is_ftdx5000)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX176%c", cat_term);
+        }
+        else if (is_ftdx3000 || is_ftdx1200)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%c", cat_term);
+        }
         else if (is_ftdx1200)
         {
             snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%c", cat_term);
         }
+        else if (is_ft991)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX147%c", cat_term);
+        }
+        else if (is_ft891)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX1619%c", cat_term);
+        }
+        else if (is_ft950)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%c", cat_term);
+        }
+        else if (is_ft2000)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX042%c", cat_term);
+        }
         else
         {
             return -RIG_EINVAL;
@@ -3708,7 +3870,11 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
 
         snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP01%c", cat_term);
 
-        if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
+        if (is_ftdx9000)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP%c", cat_term);
+        }
+        else if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
         {
             priv->cmd_str[2] = main_sub_vfo;
         }
@@ -3721,14 +3887,23 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
             return -RIG_ENAVAIL;
         }
 
-        snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%c", cat_term);
+        if (is_ftdx9000)
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML%c", cat_term);
+        }
+        else
+        {
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%c", cat_term);
+        }
         break;
 
     default:
         return -RIG_EINVAL;
     }
 
-    if (RIG_OK != (err = newcat_get_cmd(rig)))
+    err = newcat_get_cmd(rig);
+
+    if (err != RIG_OK)
     {
         return err;
     }
@@ -3763,10 +3938,20 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
 
     case RIG_LEVEL_VOXGAIN:
     case RIG_LEVEL_COMP:
+        if (is_ft2000 || is_ftdx9000 || is_ftdx5000)
+        {
+            scale = 255;
+        }
+        else
+        {
+            scale = 100;
+        }
+
+        val->f = (float) atoi(retlvl) / scale;
+        break;
+
     case RIG_LEVEL_ANTIVOX:
-        scale = (is_ft950 || is_ftdx101) ? 100. : 255.;
-        scale = (is_ftdx1200 || is_ftdx101) ? 100. : scale ;
-        val->f = (float)atoi(retlvl) / scale;
+        val->f = (float) atoi(retlvl) / 100.;
         break;
 
     case RIG_LEVEL_SWR:
@@ -3891,52 +4076,71 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
         break;
 
     case RIG_LEVEL_AF:
-    case RIG_LEVEL_RF:
-    case RIG_LEVEL_SQL:
-        val->f = (float)atoi(retlvl) / 255.;
+        val->f = (float)atoi(retlvl) / 255;
         break;
 
-    case RIG_LEVEL_BKINDL:
-        val->i = atoi(retlvl);      /* milliseconds */
+    case RIG_LEVEL_RF:
+        if (is_ft891)
+        {
+            scale = 30.;
+        }
+        else
+        {
+            scale = 255.;
+        }
+
+        val->f = (float)atoi(retlvl) / scale;
+        break;
+
+    case RIG_LEVEL_SQL:
+        if (is_ft891 || is_ft991 || is_ftdx101)
+        {
+            scale = 100.;
+        }
+        else
+        {
+            scale = 255.;
+        }
+
+        val->f = (float)atoi(retlvl) / scale;
+        break;
+
+    case RIG_LEVEL_BKINDL: {
+        int raw_value = atoi(retlvl);
+        int millis;
+        value_t keyspd;
 
         if (is_ftdx101)
         {
-            switch (val->i)
+            switch (raw_value)
             {
-            case 0: val->i = 1; break;
-
-            case 1: val->i = 1; break;
-
-            case 2: val->i = 1; break;
-
-            case 3: val->i = 2; break;
-
-            case 4: val->i = 2; break;
-
-            case 5: val->i = 3; break;
-
-            case 6: val->i = 3; break;
-
-            default: val->i = (val->i - 6) + 3;
+            case 0: millis = 30; break;
+            case 1: millis = 50; break;
+            case 2: millis = 100; break;
+            case 3: millis = 150; break;
+            case 4: millis = 200; break;
+            case 5: millis = 250; break;
+            case 6: millis = 300; break;
+            default:
+                millis = (raw_value - 6) * 100 + 300;
             }
-
-            return RIG_OK;
         }
-
-        if (val->i < 1)
+        else
         {
-            val->i = 1;
+            // The rest of Yaesu rigs indicate break-in delay directly as milliseconds
+            millis = raw_value;
         }
 
-        val->i = 5000 / val->i;   /* ms -to- tenth_dots-per-second */
-
-        if (val->i < 1)
+        // Convert milliseconds to 10/ths of dots using the current key speed
+        err = newcat_get_level(rig, vfo, RIG_LEVEL_KEYSPD, &keyspd);
+        if (err != RIG_OK)
         {
-            val->i = 1;
+            return err;
         }
 
+        val->i = millis_to_dot10ths(millis, keyspd.i);
         break;
-
+    }
     case RIG_LEVEL_STRENGTH:
         if (rig->caps->str_cal.size > 0)
         {
@@ -3949,17 +4153,27 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
         {
             val->i = round(rig_raw2val(atoi(retlvl), &yaesu_default_str_cal));
         }
-        else // some Yaesu rigs return straight s-meter answers
+        else
         {
+            // Some Yaesu rigs return straight S-meter answers
             // Return dbS9 -- does >S9 mean 10dB increments? If not, add to rig driver
-            if (val->i > 0) { val->i = (atoi(retlvl) - 9) * 10; }
-            else { val->i = (atoi(retlvl) - 9) * 6; } // Return dbS9  does >S9 mean 10dB increments?
+            if (val->i > 0)
+            {
+                val->i = (atoi(retlvl) - 9) * 10;
+            }
+            else
+            {
+                val->i = (atoi(retlvl) - 9) * 6;
+            }
         }
 
         break;
 
     case RIG_LEVEL_RAWSTR:
     case RIG_LEVEL_KEYSPD:
+        val->i = atoi(retlvl);
+        break;
+
     case RIG_LEVEL_IF:
         // IS00+0400
         rig_debug(RIG_DEBUG_TRACE, "%s: ret_data=%s(%d), retlvl=%s\n", __func__,
@@ -3983,9 +4197,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
         break;
 
     case RIG_LEVEL_NR:
-
-        /*  ratio 0 - 1.0 */
-        if (newcat_is_rig(rig, RIG_MODEL_FT450))
+        if (is_ft450)
         {
             val->f = (float)(atoi(retlvl) / 11.);
         }
@@ -4028,47 +4240,94 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
 
         break;
 
-    case RIG_LEVEL_PREAMP:
+    case RIG_LEVEL_PREAMP: {
+        int preamp;
+
         if (retlvl[0] < '0' || retlvl[0] > '9')
         {
             return -RIG_EPROTO;
         }
 
-        val->i = (retlvl[0] == '0') ? 0 : state->preamp[retlvl[0] - '1'];
-        break;
+        preamp = retlvl[0] - '0';
+
+        val->i = 0;
+
+        if (preamp > 0)
+        {
+            for (i = 0; state->preamp[i] != RIG_DBLST_END; i++)
+            {
+                if (i == preamp - 1)
+                {
+                    val->i = state->preamp[i];
+                    break;
+                }
+            }
+        }
+        break;
+    }
+
+    case RIG_LEVEL_ATT: {
+        int att;
 
-    case RIG_LEVEL_ATT:
         if (retlvl[0] < '0' || retlvl[0] > '9')
         {
             return -RIG_EPROTO;
         }
 
-        val->i = (retlvl[0] == '0') ? 0 : state->attenuator[retlvl[0] - '1'];
+        att = retlvl[0] - '0';
+
+        val->i = 0;
+
+        if (att > 0)
+        {
+            for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++)
+            {
+                if (i == att - 1)
+                {
+                    val->i = state->attenuator[i];
+                    break;
+                }
+            }
+        }
         break;
+    }
 
     case RIG_LEVEL_AGC:
         switch (retlvl[0])
         {
-        case '0': val->i = RIG_AGC_OFF; break;
-
-        case '1': val->i = RIG_AGC_FAST; break;
-
-        case '2': val->i = RIG_AGC_MEDIUM; break;
-
-        case '3': val->i = RIG_AGC_SLOW; break;
-
+        case '0':
+            val->i = RIG_AGC_OFF;
+            break;
+        case '1':
+            val->i = RIG_AGC_FAST;
+            break;
+        case '2':
+            val->i = RIG_AGC_MEDIUM;
+            break;
+        case '3':
+            val->i = RIG_AGC_SLOW;
+            break;
         case '4':
         case '5':
         case '6':
             val->i = RIG_AGC_AUTO; break;
 
-        default: return -RIG_EPROTO;
+        default:
+            return -RIG_EPROTO;
         }
 
         break;
 
     case RIG_LEVEL_CWPITCH:
-        val->i = (atoi(retlvl) / 2) * 100 + 300;
+        if (is_ft950 || is_ft2000)
+        {
+            val->i = (atoi(retlvl) * 50) + 300;
+        }
+        else
+        {
+            // Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps
+            val->i = (atoi(retlvl) * 10) + 300;
+        }
         break;
 
     case RIG_LEVEL_METER:
@@ -4153,6 +4412,8 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
             priv->cmd_str[2] = main_sub_vfo;
         }
 
+        // Some Yaesu rigs reject this command in AM/FM modes
+        priv->question_mark_response_means_rejected = 1;
         break;
 
     case RIG_FUNC_MN:
@@ -4169,6 +4430,8 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
             priv->cmd_str[2] = main_sub_vfo;
         }
 
+        // Some Yaesu rigs reject this command in AM/FM modes
+        priv->question_mark_response_means_rejected = 1;
         break;
 
     case RIG_FUNC_FBKIN:
@@ -4273,6 +4536,8 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
             priv->cmd_str[2] = main_sub_vfo;
         }
 
+        // Some Yaesu rigs reject this command in AM/FM modes
+        priv->question_mark_response_means_rejected = 1;
         break;
 
     case RIG_FUNC_COMP:
@@ -4281,15 +4546,14 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
             return -RIG_ENAVAIL;
         }
 
-        if (is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101)
+        if (is_ft891 || is_ft991 || is_ftdx1200 || is_ftdx3000 || is_ftdx101)
         {
-            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR0%d%c", status ? 1 : 0,
-                     cat_term);
+            // There seems to be an error in the manuals for some of these rigs stating that values should be 1 = OFF and 2 = ON, but they are 0 = OFF and 1 = ON instead
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR0%d%c", status ? 1 : 0, cat_term);
         }
         else
         {
-            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR%d%c", status ? 1 : 0,
-                     cat_term);
+            snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR%d%c", status ? 1 : 0, cat_term);
         }
 
         break;
@@ -4342,7 +4606,12 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
         return -RIG_EINVAL;
     }
 
-    return newcat_set_cmd(rig);
+    err = newcat_set_cmd(rig);
+
+    // Clear flag after executing command
+    priv->question_mark_response_means_rejected = 0;
+
+    return err;
 }
 
 
@@ -5430,14 +5699,14 @@ ncboolean newcat_valid_command(RIG *rig, char const *const command)
     is_ft950 = newcat_is_rig(rig, RIG_MODEL_FT950);
     is_ft991 = newcat_is_rig(rig, RIG_MODEL_FT991);
     is_ft2000 = newcat_is_rig(rig, RIG_MODEL_FT2000);
-    is_ft9000 = newcat_is_rig(rig, RIG_MODEL_FT9000);
+    is_ftdx9000 = newcat_is_rig(rig, RIG_MODEL_FT9000);
     is_ftdx5000 = newcat_is_rig(rig, RIG_MODEL_FTDX5000);
     is_ftdx1200 = newcat_is_rig(rig, RIG_MODEL_FTDX1200);
     is_ftdx3000 = newcat_is_rig(rig, RIG_MODEL_FTDX3000);
     is_ftdx101 = newcat_is_rig(rig, RIG_MODEL_FTDX101D);
 
     if (!is_ft450 && !is_ft950 && !is_ft891 && !is_ft991 && !is_ft2000
-            && !is_ftdx5000 && !is_ft9000 && !is_ftdx1200 && !is_ftdx3000 && !is_ftdx101)
+        && !is_ftdx5000 && !is_ftdx9000 && !is_ftdx1200 && !is_ftdx3000 && !is_ftdx101)
     {
         rig_debug(RIG_DEBUG_ERR, "%s: '%s' is unknown\n", __func__, caps->model_name);
         return FALSE;
@@ -5496,7 +5765,7 @@ ncboolean newcat_valid_command(RIG *rig, char const *const command)
             {
                 return TRUE;
             }
-            else if (is_ft9000 && valid_commands[search_index].ft9000)
+            else if (is_ftdx9000 && valid_commands[search_index].ft9000)
             {
                 return TRUE;
             }
@@ -5933,7 +6202,15 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
         case RIG_MODE_RTTYR:
         case RIG_MODE_CW:
         case RIG_MODE_CWR:
-            if (width <= 100) { w = 3; }
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
+            else if (width <= 100) { w = 3; }
             else if (width <= 200) { w = 4; }
             else if (width <= 300) { w = 5; }
             else if (width <= 400) { w = 6; }
@@ -5943,13 +6220,20 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             else if (width <= 1400) { w = 10; }
             else if (width <= 1700) { w = 11; }
             else if (width <= 2000) { w = 12; }
-            else { w = 13; } // 2400 is the max
-
+            else { w = 13; } // 2400 Hz
             break;
 
         case RIG_MODE_LSB:
         case RIG_MODE_USB:
-            if (width <= 200) { w = 1; }
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
+            else if (width <= 200) { w = 1; }
             else if (width <= 400) { w = 2; }
             else if (width <= 600) { w = 3; }
             else if (width <= 850) { w = 4; }
@@ -5968,10 +6252,27 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             else if (width <= 2700) { w = 17; }
             else if (width <= 2800) { w = 18; }
             else if (width <= 2900) { w = 19; }
-            else { w = 20; } // 3000 is the max
-
+            else { w = 20; } // 3000 Hz
             break;
 
+        case RIG_MODE_AM:
+        case RIG_MODE_FM:
+        case RIG_MODE_PKTFM:
+        case RIG_MODE_FMN:
+            // Set roofing filter and narrow mode
+            break;
+
+        default:
+            return -RIG_EINVAL;
+        } // end switch(mode)
+
+        if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK)
+        {
+            return err;
+        }
+
+        switch (mode)
+        {
         case RIG_MODE_AM:
         case RIG_MODE_FM:
         case RIG_MODE_PKTFM:
@@ -5983,13 +6284,12 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             {
                 err = newcat_set_narrow(rig, vfo, FALSE);
             }
-
             return err;
 
-        default:
-            return -RIG_EINVAL;
-        }   // end switch(mode)
-    }   // end is_ft950 */
+        case RIG_MODE_FMN:
+            return RIG_OK;
+        }
+    } // end is_ft950 */
     else if (is_ft891)
     {
         switch (mode)
@@ -6000,204 +6300,14 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
         case RIG_MODE_RTTYR:
         case RIG_MODE_CW:
         case RIG_MODE_CWR:
-            if (width <= 50) { w = 1; }
-            else if (width <= 100) { w = 2; }
-            else if (width <= 150) { w = 3; }
-            else if (width <= 200) { w = 4; }
-            else if (width <= 250) { w = 5; }
-            else if (width <= 300) { w = 6; }
-            else if (width <= 350) { w = 7; }
-            else if (width <= 400) { w = 8; }
-            else if (width <= 450) { w = 9; }
-            else if (width <= 500) { w = 10; }
-            else if (width <= 800) { w = 11; }
-            else if (width <= 1200) { w = 12; }
-            else if (width <= 1400) { w = 13; }
-            else if (width <= 1700) { w = 14; }
-            else if (width <= 2000) { w = 15; }
-            else if (width <= 2400) { w = 16; }
-            else { w = 17; } // 3000 is the max
-
-            break;
-
-        case RIG_MODE_LSB:
-        case RIG_MODE_USB:
-            if (width <= 200) { w = 1; }
-            else if (width <= 400) { w = 2; }
-            else if (width <= 600) { w = 3; }
-            else if (width <= 850) { w = 4; }
-            else if (width <= 1100) { w = 5; }
-            else if (width <= 1350) { w = 6; }
-            else if (width <= 1500) { w = 7; }
-            else if (width <= 1600) { w = 8; }
-            else if (width <= 1800) { w = 9; }
-            else if (width <= 1950) { w = 10; }
-            else if (width <= 2100) { w = 11; }
-            else if (width <= 2200) { w = 12; }
-            else if (width <= 2300) { w = 13; }
-            else if (width <= 2400) { w = 14; }
-            else if (width <= 2500) { w = 15; }
-            else if (width <= 2600) { w = 16; }
-            else if (width <= 2700) { w = 17; }
-            else if (width <= 2800) { w = 18; }
-            else if (width <= 2900) { w = 19; }
-            else if (width <= 3000) { w = 20; }
-            else { w = 21; } // 3000 is the max
-
-            break;
-
-        case RIG_MODE_AM:
-        case RIG_MODE_FM:
-        case RIG_MODE_PKTFM:
-            if (width < rig_passband_normal(rig, mode))
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE);
+            if (err != RIG_OK)
             {
-                err = newcat_set_narrow(rig, vfo, TRUE);
-            }
-            else
-            {
-                err = newcat_set_narrow(rig, vfo, FALSE);
+                return err;
             }
 
-            return err;
-
-        default:
-            return -RIG_EINVAL;
-        }   // end switch(mode)
-    }   // end is_ft891
-    else if (is_ft991)
-    {
-        switch (mode)
-        {
-        case RIG_MODE_PKTUSB:
-        case RIG_MODE_PKTLSB:
-        case RIG_MODE_RTTY:
-        case RIG_MODE_RTTYR:
-        case RIG_MODE_CW:
-        case RIG_MODE_CWR:
-            if (width <= 50) { w = 1; }
-            else if (width <= 100) { w = 2; }
-            else if (width <= 150) { w = 3; }
-            else if (width <= 200) { w = 4; }
-            else if (width <= 250) { w = 5; }
-            else if (width <= 305) { w = 6; }
-            else if (width <= 350) { w = 7; }
-            else if (width <= 400) { w = 8; }
-            else if (width <= 450) { w = 9; }
-            else if (width <= 500) { w = 10; }
-            else if (width <= 800) { w = 11; }
-            else if (width <= 1200) { w = 12; }
-            else if (width <= 1400) { w = 13; }
-            else if (width <= 1700) { w = 14; }
-            else if (width <= 2000) { w = 15; }
-            else if (width <= 2400) { w = 16; }
-            else { w = 17; } // 3000 is the max
-
-            break;
-
-        case RIG_MODE_LSB:
-        case RIG_MODE_USB:
-            if (width <= 200) { w = 1; }
-            else if (width <= 400) { w = 2; }
-            else if (width <= 600) { w = 3; }
-            else if (width <= 850) { w = 4; }
-            else if (width <= 1100) { w = 5; }
-            else if (width <= 1350) { w = 6; }
-            else if (width <= 1500) { w = 7; }
-            else if (width <= 1660) { w = 8; }
-            else if (width <= 1800) { w = 9; }
-            else if (width <= 1950) { w = 10; }
-            else if (width <= 2100) { w = 11; }
-            else if (width <= 2200) { w = 12; }
-            else if (width <= 2300) { w = 13; }
-            else if (width <= 2400) { w = 14; }
-            else if (width <= 2500) { w = 15; }
-            else if (width <= 2600) { w = 16; }
-            else if (width <= 2700) { w = 17; }
-            else if (width <= 2800) { w = 18; }
-            else if (width <= 2900) { w = 19; }
-            else if (width <= 3000) { w = 20; }
-            else { w = 21; } // 3200 is the max
-
-            break;
-
-        case RIG_MODE_AM: //Only 1 passband each for AM or AMN
-            if (width == 0 || width == 9000)
-            {
-                err = newcat_set_narrow(rig, vfo, FALSE);
-            }
-
-            return err;
-
-        case RIG_MODE_AMN:
-            if (width == 0 || width == 6000)
-            {
-                err = newcat_set_narrow(rig, vfo, TRUE);
-            }
-
-            return err;
-
-        case RIG_MODE_FM: //Only 1 passband each for FM or FMN
-
-            if (width == 0 || width == 16000)
-            {
-                err = newcat_set_narrow(rig, vfo, FALSE);
-            }
-
-            return err;
-
-        case RIG_MODE_FMN:
-
-            if (width == 0 || width == 9000)
-            {
-                err = newcat_set_narrow(rig, vfo, TRUE);
-            }
-
-            return err;
-
-        case RIG_MODE_C4FM:
-
-            if (width == 0 || width == 16000)
-            {
-                err = newcat_set_narrow(rig, vfo, TRUE);
-            }
-            else if (width == 9000)
-            {
-                err = newcat_set_narrow(rig, vfo, FALSE);
-            }
-            else
-            {
-                return -RIG_EINVAL;
-            }
-
-            return err;
-
-        case RIG_MODE_PKTFM:
-            if (width < rig_passband_normal(rig, mode))
-            {
-                err = newcat_set_narrow(rig, vfo, TRUE);
-            }
-            else
-            {
-                err = newcat_set_narrow(rig, vfo, FALSE);
-            }
-
-            return err;
-
-        default:
-            return -RIG_EINVAL;
-        }   // end switch(mode)
-    }   // end is_ft991
-    else if (is_ftdx1200)
-    {
-        switch (mode)
-        {
-        case RIG_MODE_PKTUSB:
-        case RIG_MODE_PKTLSB:
-        case RIG_MODE_RTTY:
-        case RIG_MODE_RTTYR:
-        case RIG_MODE_CW:
-        case RIG_MODE_CWR:
-            if (width == 0) { w = 0; }
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
             else if (width <= 50) { w = 1; }
             else if (width <= 100) { w = 2; }
             else if (width <= 150) { w = 3; }
@@ -6213,13 +6323,238 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             else if (width <= 1400) { w = 13; }
             else if (width <= 1700) { w = 14; }
             else if (width <= 2000) { w = 15; }
-            else { w = 16; } // 2400 is max
-
+            else if (width <= 2400) { w = 16; }
+            else { w = 17; } // 3000 Hz
             break;
 
         case RIG_MODE_LSB:
         case RIG_MODE_USB:
-            if (width == 0) { w = 0; }
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
+            else if (width <= 200) { w = 1; }
+            else if (width <= 400) { w = 2; }
+            else if (width <= 600) { w = 3; }
+            else if (width <= 850) { w = 4; }
+            else if (width <= 1100) { w = 5; }
+            else if (width <= 1350) { w = 6; }
+            else if (width <= 1500) { w = 7; }
+            else if (width <= 1650) { w = 8; }
+            else if (width <= 1800) { w = 9; }
+            else if (width <= 1950) { w = 10; }
+            else if (width <= 2100) { w = 11; }
+            else if (width <= 2200) { w = 12; }
+            else if (width <= 2300) { w = 13; }
+            else if (width <= 2400) { w = 14; }
+            else if (width <= 2500) { w = 15; }
+            else if (width <= 2600) { w = 16; }
+            else if (width <= 2700) { w = 17; }
+            else if (width <= 2800) { w = 18; }
+            else if (width <= 2900) { w = 19; }
+            else if (width <= 3000) { w = 20; }
+            else { w = 21; } // 3000 Hz
+            break;
+
+        case RIG_MODE_AM:
+        case RIG_MODE_FM:
+        case RIG_MODE_PKTFM:
+            if (width < rig_passband_normal(rig, mode))
+            {
+                err = newcat_set_narrow(rig, vfo, TRUE);
+            }
+            else
+            {
+                err = newcat_set_narrow(rig, vfo, FALSE);
+            }
+            return err;
+
+        case RIG_MODE_FMN:
+            break;
+
+        default:
+            return -RIG_EINVAL;
+        } // end switch(mode)
+    } // end is_ft891
+    else if (is_ft991)
+    {
+        switch (mode)
+        {
+        case RIG_MODE_PKTUSB:
+        case RIG_MODE_PKTLSB:
+        case RIG_MODE_RTTY:
+        case RIG_MODE_RTTYR:
+        case RIG_MODE_CW:
+        case RIG_MODE_CWR:
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
+            else if (width <= 50) { w = 1; }
+            else if (width <= 100) { w = 2; }
+            else if (width <= 150) { w = 3; }
+            else if (width <= 200) { w = 4; }
+            else if (width <= 250) { w = 5; }
+            else if (width <= 305) { w = 6; }
+            else if (width <= 350) { w = 7; }
+            else if (width <= 400) { w = 8; }
+            else if (width <= 450) { w = 9; }
+            else if (width <= 500) { w = 10; }
+            else if (width <= 800) { w = 11; }
+            else if (width <= 1200) { w = 12; }
+            else if (width <= 1400) { w = 13; }
+            else if (width <= 1700) { w = 14; }
+            else if (width <= 2000) { w = 15; }
+            else if (width <= 2400) { w = 16; }
+            else { w = 17; } // 3000 Hz
+            break;
+
+        case RIG_MODE_LSB:
+        case RIG_MODE_USB:
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
+            else if (width <= 200) { w = 1; }
+            else if (width <= 400) { w = 2; }
+            else if (width <= 600) { w = 3; }
+            else if (width <= 850) { w = 4; }
+            else if (width <= 1100) { w = 5; }
+            else if (width <= 1350) { w = 6; }
+            else if (width <= 1500) { w = 7; }
+            else if (width <= 1650) { w = 8; }
+            else if (width <= 1800) { w = 9; }
+            else if (width <= 1950) { w = 10; }
+            else if (width <= 2100) { w = 11; }
+            else if (width <= 2200) { w = 12; }
+            else if (width <= 2300) { w = 13; }
+            else if (width <= 2400) { w = 14; }
+            else if (width <= 2500) { w = 15; }
+            else if (width <= 2600) { w = 16; }
+            else if (width <= 2700) { w = 17; }
+            else if (width <= 2800) { w = 18; }
+            else if (width <= 2900) { w = 19; }
+            else if (width <= 3000) { w = 20; }
+            else { w = 21; } // 3200 Hz
+            break;
+
+        case RIG_MODE_AM: // Only 1 passband each for AM or AMN
+            if (width == RIG_PASSBAND_NORMAL || width == 9000)
+            {
+                err = newcat_set_narrow(rig, vfo, FALSE);
+            }
+            return err;
+
+        case RIG_MODE_AMN:
+            if (width == RIG_PASSBAND_NORMAL || width == 6000)
+            {
+                err = newcat_set_narrow(rig, vfo, TRUE);
+            }
+            return err;
+
+        case RIG_MODE_FM: // Only 1 passband each for FM or FMN
+            if (width == RIG_PASSBAND_NORMAL || width == 16000)
+            {
+                err = newcat_set_narrow(rig, vfo, FALSE);
+            }
+            return err;
+
+        case RIG_MODE_FMN:
+            if (width == RIG_PASSBAND_NORMAL || width == 9000)
+            {
+                err = newcat_set_narrow(rig, vfo, TRUE);
+            }
+            return err;
+
+        case RIG_MODE_C4FM:
+            if (width == RIG_PASSBAND_NORMAL || width == 16000)
+            {
+                err = newcat_set_narrow(rig, vfo, TRUE);
+            }
+            else if (width == 9000)
+            {
+                err = newcat_set_narrow(rig, vfo, FALSE);
+            }
+            else
+            {
+                return -RIG_EINVAL;
+            }
+            return err;
+
+        case RIG_MODE_PKTFM:
+            if (width < rig_passband_normal(rig, mode))
+            {
+                err = newcat_set_narrow(rig, vfo, TRUE);
+            }
+            else
+            {
+                err = newcat_set_narrow(rig, vfo, FALSE);
+            }
+            return err;
+
+        default:
+            return -RIG_EINVAL;
+        } // end switch(mode)
+    } // end is_ft991
+    else if (is_ftdx1200 || is_ftdx3000)
+    {
+        // FTDX 1200 and FTDX 3000 have the same set of filter choices
+        switch (mode)
+        {
+        case RIG_MODE_PKTUSB:
+        case RIG_MODE_PKTLSB:
+        case RIG_MODE_RTTY:
+        case RIG_MODE_RTTYR:
+        case RIG_MODE_CW:
+        case RIG_MODE_CWR:
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
+            else if (width <= 50) { w = 1; }
+            else if (width <= 100) { w = 2; }
+            else if (width <= 150) { w = 3; }
+            else if (width <= 200) { w = 4; }
+            else if (width <= 250) { w = 5; }
+            else if (width <= 300) { w = 6; }
+            else if (width <= 350) { w = 7; }
+            else if (width <= 400) { w = 8; }
+            else if (width <= 450) { w = 9; }
+            else if (width <= 500) { w = 10; }
+            else if (width <= 800) { w = 11; }
+            else if (width <= 1200) { w = 12; }
+            else if (width <= 1400) { w = 13; }
+            else if (width <= 1700) { w = 14; }
+            else if (width <= 2000) { w = 15; }
+            else { w = 16; } // 2400 Hz
+            break;
+
+        case RIG_MODE_LSB:
+        case RIG_MODE_USB:
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
             else if (width <= 200) {  w = 1; }
             else if (width <= 400) {  w = 2; }
             else if (width <= 600) {  w = 3; }
@@ -6244,13 +6579,33 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             else if (width <= 3400) {  w = 22; }
             else if (width <= 3600) {  w = 23; }
             else if (width <= 3800) {  w = 24; }
-            else { w = 25; } // 4000Hz is max
-
+            else { w = 25; } // 4000 Hz
             break;
 
         case RIG_MODE_AM:
+        case RIG_MODE_AMN:
         case RIG_MODE_FM:
         case RIG_MODE_PKTFM:
+        case RIG_MODE_FMN:
+            // Set roofing filter and narrow mode
+            break;
+
+        default:
+            return -RIG_EINVAL;
+        } // end switch(mode)
+
+        if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK)
+        {
+            return err;
+        }
+
+        switch (mode)
+        {
+        case RIG_MODE_AM:
+        case RIG_MODE_AMN:
+        case RIG_MODE_FM:
+        case RIG_MODE_PKTFM:
+        case RIG_MODE_FMN:
             if (width < rig_passband_normal(rig, mode))
             {
                 err = newcat_set_narrow(rig, vfo, TRUE);
@@ -6259,13 +6614,116 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             {
                 err = newcat_set_narrow(rig, vfo, FALSE);
             }
-
             return err;
+        }
+    } // end is_ftdx1200 and is_ftdx3000
+    else if (is_ftdx5000)
+    {
+        switch (mode)
+        {
+        case RIG_MODE_PKTUSB:
+        case RIG_MODE_PKTLSB:
+        case RIG_MODE_RTTY:
+        case RIG_MODE_RTTYR:
+        case RIG_MODE_CW:
+        case RIG_MODE_CWR:
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
+            else if (width <= 50) { w = 1; }
+            else if (width <= 100) { w = 2; }
+            else if (width <= 150) { w = 3; }
+            else if (width <= 200) { w = 4; }
+            else if (width <= 250) { w = 5; }
+            else if (width <= 300) { w = 6; }
+            else if (width <= 350) { w = 7; }
+            else if (width <= 400) { w = 8; }
+            else if (width <= 450) { w = 9; }
+            else if (width <= 500) { w = 10; }
+            else if (width <= 800) { w = 11; }
+            else if (width <= 1200) { w = 12; }
+            else if (width <= 1400) { w = 13; }
+            else if (width <= 1700) { w = 14; }
+            else if (width <= 2000) { w = 15; }
+            else { w = 16; } // 2400 Hz
+            break;
+
+        case RIG_MODE_LSB:
+        case RIG_MODE_USB:
+            // Narrow mode must be chosen correctly before filter width
+            err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE);
+            if (err != RIG_OK)
+            {
+                return err;
+            }
+
+            if (width == RIG_PASSBAND_NORMAL) { w = 0; }
+            else if (width <= 200) {  w = 1; }
+            else if (width <= 400) {  w = 2; }
+            else if (width <= 600) {  w = 3; }
+            else if (width <= 850) {  w = 4; }
+            else if (width <= 1100) {  w = 5; }
+            else if (width <= 1350) {  w = 6; }
+            else if (width <= 1500) {  w = 7; }
+            else if (width <= 1650) {  w = 8; }
+            else if (width <= 1800) {  w = 9; }
+            else if (width <= 1950) {  w = 10; }
+            else if (width <= 2100) {  w = 11; }
+            else if (width <= 2250) {  w = 12; }
+            else if (width <= 2400) {  w = 13; }
+            else if (width <= 2500) {  w = 15; }
+            else if (width <= 2600) {  w = 16; }
+            else if (width <= 2700) {  w = 17; }
+            else if (width <= 2800) {  w = 18; }
+            else if (width <= 2900) {  w = 19; }
+            else if (width <= 3000) {  w = 20; }
+            else if (width <= 3200) {  w = 21; }
+            else if (width <= 3400) {  w = 22; }
+            else if (width <= 3600) {  w = 23; }
+            else if (width <= 3800) {  w = 24; }
+            else { w = 25; } // 4000 Hz
+            break;
+
+        case RIG_MODE_AM:
+        case RIG_MODE_AMN:
+        case RIG_MODE_FM:
+        case RIG_MODE_PKTFM:
+        case RIG_MODE_FMN:
+            // Set roofing filter and narrow mode
+            break;
 
         default:
             return -RIG_EINVAL;
-        }   // end switch(mode)
-    } // end is_ftdx1200
+        } // end switch(mode)
+
+        if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK)
+        {
+            return err;
+        }
+
+        switch (mode)
+        {
+        case RIG_MODE_AM:
+        case RIG_MODE_AMN:
+        case RIG_MODE_FM:
+        case RIG_MODE_PKTFM:
+        case RIG_MODE_FMN:
+            if (width < rig_passband_normal(rig, mode))
+            {
+                err = newcat_set_narrow(rig, vfo, TRUE);
+            }
+            else
+            {
+                err = newcat_set_narrow(rig, vfo, FALSE);
+            }
+            return err;
+        }
+    } // end is_ftdx5000
     else if (is_ftdx101)
     {
         switch (mode)
@@ -6295,7 +6753,6 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             else if (width <= 2000) { w = 16; }
             else if (width <= 2400) { w = 17; }
             else { w = 18; }
-
             break;
 
         case RIG_MODE_LSB:
@@ -6324,17 +6781,49 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             else if (width <= 3200) {  w = 21; }
             else if (width <= 3500) {  w = 22; }
             else { w = 23; } // 4000Hz
+            break;
+
+        case RIG_MODE_AM:
+        case RIG_MODE_AMN:
+        case RIG_MODE_FM:
+        case RIG_MODE_PKTFM:
+        case RIG_MODE_FMN:
+            // Set roofing filter and narrow mode
+            break;
+
+        default:
+            return -RIG_EINVAL;
         } // end switch(mode)
 
         if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK)
         {
             return err;
         }
+
+        switch (mode)
+        {
+        case RIG_MODE_AM:
+        case RIG_MODE_FM:
+        case RIG_MODE_PKTFM:
+            if (width < rig_passband_normal(rig, mode))
+            {
+                err = newcat_set_narrow(rig, vfo, TRUE);
+            }
+            else
+            {
+                err = newcat_set_narrow(rig, vfo, FALSE);
+            }
+            return err;
+
+        case RIG_MODE_AMN:
+        case RIG_MODE_FMN:
+            return RIG_OK;
+        }
     } // end is_ftdx101
     else
     {
-        // FT450, FT2000, FT5000, FT9000
-        // we need details on the widths here...manuals lack information
+        // FT-450, FT-2000, FTDX 9000
+        // We need details on the widths here, manuals lack information.
         switch (mode)
         {
         case RIG_MODE_PKTUSB:
@@ -6346,7 +6835,6 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             if (width <= 500) { w = 6; }
             else if (width <= 1800) { w = 16; }
             else { w = 24; }
-
             break;
 
         case RIG_MODE_LSB:
@@ -6354,7 +6842,6 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             if (width <= 1800) { w = 8; }
             else if (width <= 2400) { w = 16; }
             else { w = 25; } // 3000
-
             break;
 
         case RIG_MODE_AM:
@@ -6368,16 +6855,16 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
             {
                 err = newcat_set_narrow(rig, vfo, FALSE);
             }
-
             return err;
 
+        case RIG_MODE_FMN:
+            return RIG_OK;
+
         default:
             return -RIG_EINVAL;
-        }   /* end switch(mode) */
+        } /* end switch(mode) */
 
-    }
-
-    /* end else */
+    } /* end else */
 
     if (is_ftdx101)
     {
@@ -6464,7 +6951,7 @@ static int set_roofing_filter(RIG *rig, vfo_t vfo, int index)
 static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width)
 {
     struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv;
-    int index = -1;
+    int index = 0;
     int i;
 
     rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
@@ -6494,11 +6981,6 @@ static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width)
         index = current_filter->index;
     }
 
-    if (index < 0)
-    {
-        return -RIG_EINVAL;
-    }
-
     return set_roofing_filter(rig, vfo, index);
 }
 
@@ -6570,6 +7052,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
     struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
     int err;
     int w;
+    int sh_command_valid = 1;
     char narrow = '!';
     char cmd[] = "SH";
     char main_sub_vfo = '0';
@@ -6588,19 +7071,20 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
         return err;
     }
 
-    if (is_ft950)
+    if (is_ft950 || is_ftdx5000)
     {
-        // can't query SH in some modes
-        switch (rig->state.current_mode)
+        // Some Yaesu rigs cannot query SH in modes such as AM/FM
+        switch (mode)
         {
-        case RIG_MODE_FM: *width = 12000; break;
-
-        case RIG_MODE_AM: *width = 6000; break;
-
-        case RIG_MODE_AMN: *width = 2400; break;
+        case RIG_MODE_FM:
+        case RIG_MODE_FMN:
+        case RIG_MODE_PKTFM:
+        case RIG_MODE_AM:
+        case RIG_MODE_AMN:
+        case RIG_MODE_PKTAM:
+            sh_command_valid = 0;
+            break;
         }
-
-        return RIG_OK;
     }
 
     if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
@@ -6608,47 +7092,54 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
         main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0';
     }
 
-    snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo,
-             cat_term);
+    if (sh_command_valid)
+    {
+        snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo,
+                 cat_term);
 
-    /* Get RX BANDWIDTH */
-    if (RIG_OK != (err = newcat_get_cmd(rig)))
-    {
-        return err;
-    }
+        err = newcat_get_cmd(rig);
+        if (err != RIG_OK)
+        {
+            return err;
+        }
 
-    if (strlen(priv->ret_data) == 7)
-    {
-        if (sscanf(priv->ret_data, "SH%*1d0%3d", &w) != 1)
+        if (strlen(priv->ret_data) == 7)
         {
-            err = -RIG_EPROTO;
+            if (sscanf(priv->ret_data, "SH%*1d0%3d", &w) != 1)
+            {
+                err = -RIG_EPROTO;
+            }
         }
-    }
-    else if (strlen(priv->ret_data) == 6)
-    {
-        if (sscanf(priv->ret_data, "SH%*1d%3d", &w) != 1)
+        else if (strlen(priv->ret_data) == 6)
         {
-            err = -RIG_EPROTO;
+            if (sscanf(priv->ret_data, "SH%*1d%3d", &w) != 1)
+            {
+                err = -RIG_EPROTO;
+            }
         }
+        else
+        {
+            rig_debug(RIG_DEBUG_ERR, "%s: unknown SH response='%s'\n", __func__,
+                      priv->ret_data);
+            return -RIG_EPROTO;
+        }
+
+        if (err != RIG_OK)
+        {
+            rig_debug(RIG_DEBUG_ERR, "%s: unable to parse width from '%s'\n", __func__,
+                      priv->ret_data);
+            return -RIG_EPROTO;
+        }
+
+        rig_debug(RIG_DEBUG_TRACE, "%s: w=%d\n", __func__, w);
     }
     else
     {
-        rig_debug(RIG_DEBUG_ERR, "%s: unknown SH response='%s'\n", __func__,
-                  priv->ret_data);
-        return -RIG_EPROTO;
+        // Some Yaesu rigs cannot query filter width using SH command in modes such as AM/FM
+        w = 0;
     }
 
-    if (err != RIG_OK)
-    {
-        rig_debug(RIG_DEBUG_ERR, "%s: unable to parse width from '%s'\n", __func__,
-                  priv->ret_data);
-        return -RIG_EPROTO;
-    }
-
-    rig_debug(RIG_DEBUG_TRACE, "%s: w=%d\n", __func__, w);
-
-    // ft950 and ftdx1200 overlap so we'll combine them
-    if (is_ft950 || is_ftdx1200)
+    if (is_ft950)
     {
         if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0)
         {
@@ -6666,42 +7157,30 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
             switch (w)
             {
             case 0:
-                if (is_ft950) { *width = narrow ? 300 : 500; }
-                else { *width = narrow ? 500 : 2400; } // ft1200
-
+                *width = narrow ? 300 : 500;
                 break;
 
-            case 1: *width = 50; break; // ft1200 only
+            case 3: *width = 100; break;
 
-            case 2: *width = 100; break; // ft1200 only
+            case 4: *width = 200; break;
 
-            case 3: *width = is_ft950 ? 100 : 150; break;
+            case 5: *width = 300; break;
 
-            case 4: *width = is_ft950 ? 200 : 200; break;
+            case 6: *width = 400; break;
 
-            case 5: *width = is_ft950 ? 300 : 250; break;
+            case 7: *width = 5000; break;
 
-            case 6: *width = is_ft950 ? 400 : 300; break;
+            case 8: *width = 800; break;
 
-            case 7: *width = is_ft950 ? 500 : 350; break;
+            case 9: *width = 1200; break;
 
-            case 8: *width = is_ft950 ? 800 : 400; break;
+            case 10: *width = 1400; break;
 
-            case 9: *width = is_ft950 ? 1200 : 450; break;
+            case 11: *width = 1700; break;
 
-            case 10: *width = is_ft950 ? 1400 : 500; break;
+            case 12: *width = 2000; break;
 
-            case 11: *width = is_ft950 ? 1700 : 800; break;
-
-            case 12: *width = is_ft950 ? 2000 : 1200; break;
-
-            case 13: *width = is_ft950 ? 2400 : 1400; break;
-
-            case 14: *width = 1700; break; // 14+ is ft1200 only
-
-            case 15: *width = 2000; break;
-
-            case 16: *width = 2400; break;
+            case 13: *width = 2400; break;
 
             default: return -RIG_EINVAL;
             }
@@ -6710,12 +7189,10 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
 
         case RIG_MODE_LSB:
         case RIG_MODE_USB:
-            switch (w) // ft950 and ft1200 overlap
+            switch (w)
             {
             case 0:
-                if (is_ft950) { *width = narrow ? 1800 : 2400; }
-                else { *width = narrow ? 1500 : 2400; } // ft1200
-
+                *width = narrow ? 1800 : 2400;
                 break;
 
             case  1: *width =  200; break;
@@ -6758,34 +7235,30 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
 
             case 20: *width = 3000; break;
 
-            // 21+ is for the FTDX1200
-            case 21: *width = 3200; break;
-
-            case 22: *width = 3400; break;
-
-            case 23: *width = 3600; break;
-
-            case 24: *width = 3800; break;
-
-            case 25: *width = 4000; break;
-
-            default: return -RIG_EINVAL;
+            default:
+                return -RIG_EINVAL;
             }
-
             break;
 
         case RIG_MODE_AM:
+            *width = narrow ? 6000 : 9000;
+            break;
+
         case RIG_MODE_PKTFM:
         case RIG_MODE_FM:
-            return RIG_OK;
+            *width = narrow ? 9000 : 16000;
+            break;
+
+        case RIG_MODE_FMN:
+            *width = 9000;
+            break;
 
         default:
             return -RIG_EINVAL;
         }   /* end switch(mode) */
 
-    }   /* end if FT950 FTDX1200 */
-
-    else if (newcat_is_rig(rig, RIG_MODEL_FT991))
+    } /* end if is_ft950 */
+    else if (is_ft891)
     {
         if ((narrow = get_narrow(rig, vfo)) < 0)
         {
@@ -6803,9 +7276,14 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
             switch (w)
             {
             case 0:
-                if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) { *width = narrow ? 500 : 2400; }
-                else { *width = narrow ? 300 : 500; }
-
+                if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR)
+                {
+                    *width = narrow ? 500 : 2400;
+                }
+                else
+                {
+                    *width = narrow ? 300 : 500;
+                }
                 break;
 
             case 1: *width = 50; break;
@@ -6901,8 +7379,152 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
             break;
 
         case RIG_MODE_AM:
+        case RIG_MODE_FMN:
+            *width =  9000;
+            break;
+
         case RIG_MODE_AMN:
-            *width =  9000; break;
+            *width =  6000;
+            break;
+
+        case RIG_MODE_FM:
+        case RIG_MODE_PKTFM:
+            *width = 16000;
+            break;
+
+        default:
+            return -RIG_EINVAL;
+        }   /* end switch(mode) */
+
+    } /* end if is_ft891 */
+    else if (is_ft991)
+    {
+        if ((narrow = get_narrow(rig, vfo)) < 0)
+        {
+            return -RIG_EPROTO;
+        }
+
+        switch (mode)
+        {
+        case RIG_MODE_PKTUSB:
+        case RIG_MODE_PKTLSB:
+        case RIG_MODE_RTTY:
+        case RIG_MODE_RTTYR:
+        case RIG_MODE_CW:
+        case RIG_MODE_CWR:
+            switch (w)
+            {
+            case 0:
+                if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR)
+                {
+                    *width = narrow ? 500 : 2400;
+                }
+                else
+                {
+                    *width = narrow ? 300 : 500;
+                }
+                break;
+
+            case 1: *width = 50; break;
+
+            case 2: *width = 100; break;
+
+            case 3: *width = 150; break;
+
+            case 4: *width = 200; break;
+
+            case 5: *width = 250; break;
+
+            case 6: *width = 300; break;
+
+            case 7: *width = 350; break;
+
+            case 8: *width = 400; break;
+
+            case 9: *width = 450; break;
+
+            case 10: *width = 500; break;
+
+            case 11: *width = 800; break;
+
+            case 12: *width = 1200; break;
+
+            case 13: *width = 1400; break;
+
+            case 14: *width = 1700; break;
+
+            case 15: *width = 2000; break;
+
+            case 16: *width = 2400; break;
+
+            case 17: *width = 3000; break;
+
+            default: return -RIG_EINVAL;
+            }
+
+            break;
+
+        case RIG_MODE_LSB:
+        case RIG_MODE_USB:
+            switch (w)
+            {
+            case 0: *width = narrow ? 1500 : 2400; break;
+
+            case  1: *width =  200; break;
+
+            case  2: *width =  400; break;
+
+            case  3: *width =  600; break;
+
+            case  4: *width =  850; break;
+
+            case  5: *width = 1100; break;
+
+            case  6: *width = 1350; break;
+
+            case  7: *width = 1500; break;
+
+            case  8: *width = 1650; break;
+
+            case  9: *width = 1800; break;
+
+            case 10: *width = 1950; break;
+
+            case 11: *width = 2100; break;
+
+            case 12: *width = 2200; break;
+
+            case 13: *width = 2300; break;
+
+            case 14: *width = 2400; break;
+
+            case 15: *width = 2500; break;
+
+            case 16: *width = 2600; break;
+
+            case 17: *width = 2700; break;
+
+            case 18: *width = 2800; break;
+
+            case 19: *width = 2900; break;
+
+            case 20: *width = 3000; break;
+
+            case 21: *width = 3200; break;
+
+            default: return -RIG_EINVAL;
+            }
+
+            break;
+
+        case RIG_MODE_AM:
+        case RIG_MODE_FMN:
+            *width =  9000;
+            break;
+
+        case RIG_MODE_AMN:
+            *width =  6000;
+            break;
 
         case RIG_MODE_FM:
         case RIG_MODE_C4FM:
@@ -6914,9 +7536,295 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
             return -RIG_EINVAL;
         }   /* end switch(mode) */
 
-    }
+    } /* end if is_ft991 */
+    else if (is_ftdx1200 || is_ftdx3000)
+    {
+        if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0)
+        {
+            return -RIG_EPROTO;
+        }
 
-    else if (newcat_is_rig(rig, RIG_MODEL_FTDX101D))
+        switch (mode)
+        {
+        case RIG_MODE_PKTUSB:
+        case RIG_MODE_PKTLSB:
+        case RIG_MODE_RTTY:
+        case RIG_MODE_RTTYR:
+        case RIG_MODE_CW:
+        case RIG_MODE_CWR:
+            switch (w)
+            {
+            case 0:
+                *width = narrow ? 500 : 2400;
+                break;
+
+            case 1: *width = 50; break;
+
+            case 2: *width = 100; break;
+
+            case 3: *width = 150; break;
+
+            case 4: *width = 200; break;
+
+            case 5: *width = 250; break;
+
+            case 6: *width = 300; break;
+
+            case 7: *width = 350; break;
+
+            case 8: *width = 400; break;
+
+            case 9: *width = 450; break;
+
+            case 10: *width = 500; break;
+
+            case 11: *width = 800; break;
+
+            case 12: *width = 1200; break;
+
+            case 13: *width = 1400; break;
+
+            case 14: *width = 1700; break;
+
+            case 15: *width = 2000; break;
+
+            case 16: *width = 2400; break;
+
+            default: return -RIG_EINVAL;
+            }
+
+            break;
+
+        case RIG_MODE_LSB:
+        case RIG_MODE_USB:
+            switch (w)
+            {
+            case 0:
+                *width = narrow ? 1500 : 2400;
+                break;
+
+            case  1: *width =  200; break;
+
+            case  2: *width =  400; break;
+
+            case  3: *width =  600; break;
+
+            case  4: *width =  850; break;
+
+            case  5: *width = 1100; break;
+
+            case  6: *width = 1350; break;
+
+            case  7: *width = 1500; break;
+
+            case  8: *width = 1650; break;
+
+            case  9: *width = 1800; break;
+
+            case 10: *width = 1950; break;
+
+            case 11: *width = 2100; break;
+
+            case 12: *width = 2250; break;
+
+            case 13: *width = 2400; break;
+
+            case 14: *width = 2450; break;
+
+            case 15: *width = 2500; break;
+
+            case 16: *width = 2600; break;
+
+            case 17: *width = 2700; break;
+
+            case 18: *width = 2800; break;
+
+            case 19: *width = 2900; break;
+
+            case 20: *width = 3000; break;
+
+            case 21: *width = 3200; break;
+
+            case 22: *width = 3400; break;
+
+            case 23: *width = 3600; break;
+
+            case 24: *width = 3800; break;
+
+            case 25: *width = 4000; break;
+
+            default: return -RIG_EINVAL;
+            }
+
+            break;
+
+        case RIG_MODE_AM:
+            *width = narrow ? 6000 : 9000;
+            break;
+
+        case RIG_MODE_PKTFM:
+        case RIG_MODE_FM:
+            *width = narrow ? 9000 : 16000;
+            break;
+
+        case RIG_MODE_FMN:
+            *width = 9000;
+            break;
+
+        case RIG_MODE_AMN:
+            *width = 6000;
+            break;
+
+        default:
+            return -RIG_EINVAL;
+        }   /* end switch(mode) */
+
+    } /* end if is_ftdx1200 or is_ftdx3000 */
+    else if (is_ftdx5000)
+    {
+        if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0)
+        {
+            return -RIG_EPROTO;
+        }
+
+        switch (mode)
+        {
+        case RIG_MODE_PKTUSB:
+        case RIG_MODE_PKTLSB:
+        case RIG_MODE_RTTY:
+        case RIG_MODE_RTTYR:
+        case RIG_MODE_CW:
+        case RIG_MODE_CWR:
+            switch (w)
+            {
+            case 0:
+                *width = narrow ? 500 : 2400;
+                break;
+
+            case 1: *width = 50; break;
+
+            case 2: *width = 100; break;
+
+            case 3: *width = 150; break;
+
+            case 4: *width = 200; break;
+
+            case 5: *width = 250; break;
+
+            case 6: *width = 300; break;
+
+            case 7: *width = 350; break;
+
+            case 8: *width = 400; break;
+
+            case 9: *width = 450; break;
+
+            case 10: *width = 500; break;
+
+            case 11: *width = 800; break;
+
+            case 12: *width = 1200; break;
+
+            case 13: *width = 1400; break;
+
+            case 14: *width = 1700; break;
+
+            case 15: *width = 2000; break;
+
+            case 16: *width = 2400; break;
+
+            default: return -RIG_EINVAL;
+            }
+
+            break;
+
+        case RIG_MODE_LSB:
+        case RIG_MODE_USB:
+            switch (w)
+            {
+            case 0:
+                *width = narrow ? 1500 : 2400;
+                break;
+
+            case  1: *width =  200; break;
+
+            case  2: *width =  400; break;
+
+            case  3: *width =  600; break;
+
+            case  4: *width =  850; break;
+
+            case  5: *width = 1100; break;
+
+            case  6: *width = 1350; break;
+
+            case  7: *width = 1500; break;
+
+            case  8: *width = 1650; break;
+
+            case  9: *width = 1800; break;
+
+            case 10: *width = 1950; break;
+
+            case 11: *width = 2100; break;
+
+            case 12: *width = 2250; break;
+
+            case 13: *width = 2400; break;
+
+            // 14 is not defined for FTDX 5000, but leaving here for completeness
+            case 14: *width = 2400; break;
+
+            case 15: *width = 2500; break;
+
+            case 16: *width = 2600; break;
+
+            case 17: *width = 2700; break;
+
+            case 18: *width = 2800; break;
+
+            case 19: *width = 2900; break;
+
+            case 20: *width = 3000; break;
+
+            case 21: *width = 3200; break;
+
+            case 22: *width = 3400; break;
+
+            case 23: *width = 3600; break;
+
+            case 24: *width = 3800; break;
+
+            case 25: *width = 4000; break;
+
+            default: return -RIG_EINVAL;
+            }
+
+            break;
+
+        case RIG_MODE_AM:
+            *width = narrow ? 6000 : 9000;
+            break;
+
+        case RIG_MODE_PKTFM:
+        case RIG_MODE_FM:
+            *width = narrow ? 9000 : 16000;
+            break;
+
+        case RIG_MODE_FMN:
+            *width = 9000;
+            break;
+
+        case RIG_MODE_AMN:
+            *width = 6000;
+            break;
+
+        default:
+            return -RIG_EINVAL;
+        }   /* end switch(mode) */
+
+    } /* end if is_ftdx5000 */
+    else if (is_ftdx101)
     {
         rig_debug(RIG_DEBUG_TRACE, "%s: is_ftdx101 w=%d, mode=%s\n", __func__, w,
                   rig_strrmode(mode));
@@ -6942,7 +7850,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
         case RIG_MODE_CWR:
             switch (w)
             {
-            case 0: *width = 50; break; /* this is the default but 50 is probably wrong */
+            case 0: break; /* use roofing filter width */
 
             case 1: *width = 50; break;
 
@@ -6989,7 +7897,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
         case RIG_MODE_USB:
             switch (w)
             {
-            case 0: *width = 300; break; /* this is the default but 300 is probably wrong */
+            case 0: break; /* use roofing filter width */
 
             case 1: *width = 300; break;
 
@@ -7047,14 +7955,17 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
         case RIG_MODE_AM:
         case RIG_MODE_FMN:
         case RIG_MODE_PKTFMN:
-            *width = 9000; break;
+            *width = 9000;
+            break;
 
         case RIG_MODE_AMN:
-            *width = 6000; break;
+            *width = 6000;
+            break;
 
         case RIG_MODE_FM:
         case RIG_MODE_PKTFM:
-            *width = 16000; break;
+            *width = 16000;
+            break;
 
         default:
             rig_debug(RIG_DEBUG_TRACE, "%s: bad mode\n", __func__);
@@ -7062,11 +7973,10 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
         }   /* end switch(mode) */
 
         rig_debug(RIG_DEBUG_TRACE, "%s: end if FTDX101D\n", __func__);
-
-    }   /* end if FTDX101D */
-    else      /* end if FT991 */
+    } /* end if is_ftdx101 */
+    else
     {
-        /* FT450, FT2000, FT5000, FT9000 */
+        /* FT450, FT2000, FT9000 */
         switch (mode)
         {
         case RIG_MODE_PKTUSB:
@@ -7089,7 +7999,6 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
             {
                 *width = rig_passband_normal(rig, mode);
             }
-
             break;
 
         case RIG_MODE_AM:
@@ -7100,7 +8009,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
         default:
             return -RIG_EINVAL;
         }   /* end switch (mode) */
-    }   /* end else */
+    } /* end else */
 
     rig_debug(RIG_DEBUG_TRACE, "%s: return RIG_OK\n", __func__);
     return RIG_OK;
@@ -7464,18 +8373,25 @@ int newcat_get_cmd(RIG *rig)
                 break;            /* retry */
 
             case '?':
-                if (priv->question_mark_response_means_rejected)
-                {
-                    /* Some commands, like MR and MC return "?;" when choosing a channel that doesn't exist */
-                    rig_debug(RIG_DEBUG_ERR, "%s: Command rejected: '%s'\n", __func__,
-                              priv->cmd_str);
-                    return -RIG_ERJCTED;
-                }
-
-                /* Rig busy wait please */
-                rig_debug(RIG_DEBUG_ERR, "%s: Rig busy\n", __func__);
-                rc = -RIG_BUSBUSY;
-                break;            /* retry read only */
+                /* The ? response is ambiguous and undocumented by Yaesu, but for get commands it seems to
+                 * indicate that the rig rejected the command because the state of the rig is not valid for the command
+                 * or that the command parameter is invalid. Retrying the command does not fix the issue,
+                 * as the error is caused by the an invalid combination of rig state.
+                 *
+                 * For example, the following cases have been observed:
+                 * - MR and MC commands are rejected when referring to an _empty_ memory channel even
+                 *   if the channel number is in a valid range
+                 * - BC (ANF) and RL (NR) commands fail in AM/FM modes, because they are
+                 *   supported only in SSB/CW/RTTY modes
+                 * - MG (MICGAIN) command fails in RTTY mode, as it's a digital mode
+                 *
+                 * There are many more cases like these and they vary by rig model.
+                 *
+                 * So far, "rig busy" type situations with the ? response have not been observed for get commands.
+                 */
+                rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig: '%s'\n", __func__,
+                          priv->cmd_str);
+                return -RIG_ERJCTED;
             }
 
             continue;
@@ -7595,10 +8511,25 @@ int newcat_set_cmd(RIG *rig)
                 break;            /* retry */
 
             case '?':
+                /* The ? response is ambiguous and undocumented by Yaesu. For set commands it seems to indicate:
+                 * 1) either that the rig is busy and the command needs to be retried
+                 * 2) or that the rig rejected the command because the state of the rig is not valid for the command
+                 *    or that the command parameter is invalid. Retrying the command does not fix the issue
+                 *    in this case, as the error is caused by the an invalid combination of rig state.
+                 *    The latter case is consistent with behaviour of get commands.
+                 *
+                 * For example, the following cases have been observed:
+                 * - MR and MC commands are rejected when referring to an _empty_ memory channel even
+                 *   if the channel number is in a valid range
+                 * - BC (ANF) and RL (NR) commands fail in AM/FM modes, because they are
+                 *   supported only in SSB/CW/RTTY modes
+                 * - MG (MICGAIN) command fails in RTTY mode, as it's a digital mode
+                 *
+                 * There are many more cases like these and they vary by rig model.
+                 */
                 if (priv->question_mark_response_means_rejected)
                 {
-                    /* Some commands, like MR and MC return "?;" when choosing a channel that doesn't exist */
-                    rig_debug(RIG_DEBUG_ERR, "%s: Command rejected: '%s'\n", __func__,
+                    rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig: '%s'\n", __func__,
                               priv->cmd_str);
                     return -RIG_ERJCTED;
                 }
diff --git a/src/misc.c b/src/misc.c
index b867c9f39..d4f5e6814 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -49,6 +49,7 @@
 #endif
 
 #include <unistd.h>
+#include <math.h>
 
 #include <hamlib/rig.h>
 #include <hamlib/amplifier.h>
@@ -230,6 +231,48 @@ unsigned long long HAMLIB_API from_bcd_be(const unsigned char bcd_data[],
     return f;
 }
 
+/**
+ * \brief Convert duration of one morse code dot (element) to milliseconds at the given speed.
+ * \param wpm morse code speed in words per minute
+ * \return double duration in milliseconds
+ *
+ * The morse code speed is calculated using the standard based on word PARIS.
+ *
+ * "If you send PARIS 5 times in a minute (5WPM) you have sent 250 elements (using correct spacing).
+ * 250 elements into 60 seconds per minute = 240 milliseconds per element."
+ *
+ * Source: http://kent-engineers.com/codespeed.htm
+ */
+double morse_code_dot_to_millis(int wpm)
+{
+    return 240.0 * (5.0 / (double) wpm);
+}
+
+/**
+ * \brief Convert duration of tenths of morse code dots to milliseconds at the given speed.
+ * \param tenths_of_dots number of 1/10ths of dots
+ * \param wpm morse code speed in words per minute
+ * \return int duration in milliseconds
+ *
+ * The morse code speed is calculated using the standard based on word PARIS.
+ */
+int dot10ths_to_millis(int dot10ths, int wpm)
+{
+    return ceil(morse_code_dot_to_millis(wpm) * (double) dot10ths / 10.0);
+}
+
+/**
+ * \brief Convert duration in milliseconds to tenths of morse code dots at the given speed.
+ * \param millis duration in milliseconds
+ * \param wpm morse code speed in words per minute
+ * \return int number of 1/10ths of dots
+ *
+ * The morse code speed is calculated using the standard based on word PARIS.
+ */
+int millis_to_dot10ths(int millis, int wpm)
+{
+    return ceil(millis / morse_code_dot_to_millis(wpm) * 10.0);
+}
 
 //! @cond Doxygen_Suppress
 #ifndef llabs
diff --git a/src/misc.h b/src/misc.h
index 5378f1da7..de88ec683 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -72,6 +72,10 @@ extern HAMLIB_EXPORT(unsigned long long) from_bcd_be(const unsigned char
                                                      bcd_data[],
                                                      unsigned bcd_len);
 
+extern HAMLIB_EXPORT(double) morse_code_dot_to_millis(int wpm);
+extern HAMLIB_EXPORT(int) dot10ths_to_millis(int dot10ths, int wpm);
+extern HAMLIB_EXPORT(int) millis_to_dot10ths(int millis, int wpm);
+
 extern HAMLIB_EXPORT(int) sprintf_freq(char *str, freq_t);
 
 /* flag that determines if AI mode should be restored on exit on