Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package chirp for openSUSE:Factory checked 
in at 2026-06-13 18:47:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/chirp (Old)
 and      /work/SRC/openSUSE:Factory/.chirp.new.1981 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "chirp"

Sat Jun 13 18:47:34 2026 rev:74 rq:1359040 version:20260612

Changes:
--------
--- /work/SRC/openSUSE:Factory/chirp/chirp.changes      2026-06-08 
14:24:58.096181826 +0200
+++ /work/SRC/openSUSE:Factory/.chirp.new.1981/chirp.changes    2026-06-13 
18:49:34.695015016 +0200
@@ -1,0 +2,8 @@
+Fri Jun 12 18:20:24 UTC 2026 - Andreas Stieger <[email protected]>
+
+- Update to version 20260612:
+  * Add test image for Bajeton BJ7800
+  * Update RT-920 test image for FM,AM & HF memories
+  * Add new model Bajeton BJ7800 as a sub-class of  RT-920
+
+-------------------------------------------------------------------

Old:
----
  chirp-20260605.obscpio

New:
----
  chirp-20260612.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ chirp.spec ++++++
--- /var/tmp/diff_new_pack.pel5pF/_old  2026-06-13 18:49:36.399085811 +0200
+++ /var/tmp/diff_new_pack.pel5pF/_new  2026-06-13 18:49:36.403085978 +0200
@@ -20,7 +20,7 @@
 
 %define pythons python3
 Name:           chirp
-Version:        20260605
+Version:        20260612
 Release:        0
 Summary:        Tool for programming amateur radio sets
 License:        GPL-3.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.pel5pF/_old  2026-06-13 18:49:36.487089468 +0200
+++ /var/tmp/diff_new_pack.pel5pF/_new  2026-06-13 18:49:36.491089633 +0200
@@ -4,8 +4,8 @@
     <param name="scm">git</param>
     <param name="changesgenerate">enable</param>
     <param name="filename">chirp</param>
-    <param name="versionformat">20260605</param>
-    <param name="revision">f624f55513514636081bfdd5736f067e666628fd</param>
+    <param name="versionformat">20260612</param>
+    <param name="revision">6dadd6b206c59a0fd1093198a0405051c585dfbf</param>
   </service>
   <service mode="manual" name="set_version"/>
   <service name="tar" mode="buildtime"/>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.pel5pF/_old  2026-06-13 18:49:36.515090630 +0200
+++ /var/tmp/diff_new_pack.pel5pF/_new  2026-06-13 18:49:36.535091462 +0200
@@ -1,7 +1,7 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">https://github.com/kk7ds/chirp.git</param>
-    <param 
name="changesrevision">f624f55513514636081bfdd5736f067e666628fd</param>
+    <param 
name="changesrevision">6dadd6b206c59a0fd1093198a0405051c585dfbf</param>
   </service>
 </servicedata>
 (No newline at EOF)

++++++ chirp-20260605.obscpio -> chirp-20260612.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260605/chirp/drivers/radtel_rt900.py 
new/chirp-20260612/chirp/drivers/radtel_rt900.py
--- old/chirp-20260605/chirp/drivers/radtel_rt900.py    2026-06-02 
02:42:11.000000000 +0200
+++ new/chirp-20260612/chirp/drivers/radtel_rt900.py    2026-06-11 
00:42:23.000000000 +0200
@@ -2,6 +2,7 @@
 # Derived from prior copyrighted work:
 # Copyright 2024 Pavel Moravec, OK2MOP <[email protected]>
 # Copyright 2023 Jim Unroe <[email protected]>
+#
 # CHIRP driver for Ratel RT-900 Series radios
 #
 # This program is free software: you can redistribute it and/or modify
@@ -40,13 +41,13 @@
     RadioSettingValueString,
     RadioSettingValueMap,
     MemSetting,
-    InvalidValueError
+    InvalidValueError,
 )
 from textwrap import dedent
 from chirp.drivers import (
     baofeng_uv17Pro,
     mml_jc8810,
-    baofeng_common as bfc
+    baofeng_common as bfc,
 )
 
 import struct
@@ -217,13 +218,14 @@
   u8 unknown_9025;    // 9025 Always 0x01 on all RT-900 variants
   u8 unknown_9026;    // 9026
   u8 unknown_9027;    // 9027
-  u8 unknown_9028;    // 9028
+  u8 zone_or_channel; // 9028 Zone or Channel (RT-920 fw V0.16)
+                      //        0: Zone mode, 1: Channel mode
   u8 unused_9029:6,   // 9029
      qtsave:2;        //      QT Save Type
-  u8 skey2_sp;        // 902A Skey2 Short
-  u8 skey2_lp;        // 902B Skey2 Long
-  u8 skey3_sp;        // 902C Skey3 Short
-  u8 skey3_lp;        // 902D Skey3 Long
+  u8 skey2_sp0;       // 902A Skey2 Short RT-900BT
+  u8 skey2_sp1;       // 902B Skey2 Short, Long RT-900BT
+  u8 skey2_lp;        // 902C Skey2 Long, Skey3 Short RT-900BT
+  u8 skey3_sp;        // 902D Skey3 Short
   u8 topkey_sp;       // 902E Top Key (RT-470L)
   u8 unused_902f:6,   // 902F
      rxendtail:2;     //      RX END TAIL (RT-470)
@@ -231,7 +233,7 @@
   u8 noise_reduction; // 9031 NOISE REDUCTION
   u8 unknown_9032;    // 9032
   u8 unknown_9033;    // 9033
-  u8 unknown_9034;    // 9034
+  u8 fm_interrupt;    // 9034
   u8 unknown_9035;    // 9035
   u8 unknown_9036;    // 9036
   u8 unknown_9037;    // 9037
@@ -253,8 +255,8 @@
 
 #seekto 0xA020;
 struct {
-  u8 code[5];         //      5-character DTMF Encoder Groups
-  u8 unused[11];
+  u8 code[6];         //      6-character DTMF PTT-IDs
+  u8 unused[10];
 } pttid[15];
 
 #seekto 0xD000; // radio operationg mode
@@ -458,12 +460,12 @@
         ("Default", 0xff), ("GMRS", 0xa5),
         ("PMR", 0x66), ("144-146/430-440", 0x55),
         ("Super", 0x56), ("Factory", 0x00),
-        ("unknown Mode 2", 0x28)
+        ("unknown Mode 2", 0x28),
     ]
     POWER_LEVELS = [
         chirp_common.PowerLevel("High", watts=8.00),
         chirp_common.PowerLevel("Middle", watts=4.00),
-        chirp_common.PowerLevel("Low", watts=1.00)
+        chirp_common.PowerLevel("Low", watts=1.00),
     ]
 
     SKEY_LIST = ["Radio",
@@ -473,7 +475,7 @@
                  "NOAA",
                  "SOS",
                  "Switch AM/FM",
-                 "Bluetooth"]
+                 "Bluetooth",]
     SKEY_SP_LIST = SKEY_LIST
 
     _upper = 999  # fw 1.20 expands from 512 to 999 channels_steps,
@@ -496,7 +498,7 @@
         (0x8000, 0x8040),
         (0x9000, 0x9040),
         (0xA000, 0xA140),
-        (0xD000, 0xD040)  # Radio mode hidden setting
+        (0xD000, 0xD040),  # Radio mode hidden setting
      ]
 
     _calibration = (0xF000, 0xF250)  # Calibration data
@@ -506,13 +508,18 @@
     _has_am_per_channel = True
     _has_am_switch = not _has_am_per_channel
     _has_single_mode = True
+    _has_zone_or_channel = False
+    _has_zone_names = False
+    _has_sp0 = True  # spkey addresses are shifted -1
+    _has_hf = False
+
     _valid_chars = chirp_common.CHARSET_ALPHANUMERIC + \
         "`~!@#$%^&*()-=_+[]\\{}|;':\",./<>?"
 
     _steps = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0, 8.33]
     _step_map = [("2.5 K", 0), ("5.0 K", 1), ("6.25 K", 2), ("8.33 K", 8),
                  ("10.0 K", 3), ("12.5 K", 4), ("20.0 K", 5), ("25.0 K", 6),
-                 ("50.0 K", 7)]
+                 ("50.0 K", 7),]
     _bandwidth_list = ["Wide (25 KHz)", "Narrow (12.5 KHz)"]
     _offset_list = ["Off", "+", "-"]
     _rx_modulation_list = ["FM", "AM"]
@@ -571,139 +578,181 @@
         # Menu 12: TOT
         rs = RadioSettingValueList(TOT_LIST, current_index=_settings.tot)
         rset = MemSetting("settings.tot", "Time Out Timer", rs)
+        rset.set_doc("Set the Time Out Timer for transmit (Seconds).")
         basic.append(rset)
 
         # Menu 00: SQL
         rs = RadioSettingValueInteger(0, 9, _settings.sql)
         rset = MemSetting("settings.sql", "Squelch Level", rs)
+        rset.set_doc("Set the receive squelch level. Setting to zero will "
+                     "disable the squlech.")
         basic.append(rset)
 
         # Menu 13: VOX
         rs = RadioSettingValueList(OFF1TO9_LIST, current_index=_settings.vox)
         rset = MemSetting("settings.vox", "VOX", rs)
+        rset.set_doc("Set the VOX sensitivity level.")
         basic.append(rset)
 
         # Menu 39: VOX DELAY
         rs = RadioSettingValueList(VOXD_LIST, current_index=_settings.voxd)
         rset = MemSetting("settings.voxd", "VOX Delay", rs)
+        rset.set_doc("Set the VOX delay time (Seconds).")
         basic.append(rset)
 
         # Menu 15: VOICE
         rs = RadioSettingValueBoolean(_settings.voice)
         rset = MemSetting("settings.voice", "Voice Prompts", rs)
+        rset.set_doc("Set the radio voice prompts.")
         basic.append(rset)
 
         # Menu 17: LANGUAGE
         rs = RadioSettingValueList(LANGUAGE_LIST,
                                    current_index=_settings.language)
         rset = MemSetting("settings.language", "Language", rs)
+        rset.set_doc("Set the radio menu and voice promopts language.")
         basic.append(rset)
 
         # Menu 23: ABR
         rs = RadioSettingValueList(ABR_LIST, current_index=_settings.abr)
         rset = MemSetting("settings.abr", "Auto BackLight", rs)
+        rset.set_doc("Set the radio Backlight auto switch off time (Seconds).")
         basic.append(rset)
 
         # Menu 19: SC-REV
         rs = RadioSettingValueList(SCREV_LIST, current_index=_settings.screv)
         rset = MemSetting("settings.screv", "Scan Resume Method", rs)
+        rset.set_doc("Set the Scan Resume method: TO (time scanning), "
+                     "CO (carrier detect), SE (search scanning).")
         basic.append(rset)
 
         # Menu 10: SAVE
         rs = RadioSettingValueList(SAVE_LIST,
                                    current_index=_settings.save)
         rset = MemSetting("settings.save", "Battery Save Mode", rs)
+        rset.set_doc("Set the Battery power save mode.")
         basic.append(rset)
 
         # Menu 42: MDF-A
         rs = RadioSettingValueList(MDF_LIST, current_index=_settings.mdfa)
         rset = MemSetting("settings.mdfa", "Memory Display Format A", rs)
+        rset.set_doc("Set A band display mode.")
         basic.append(rset)
 
         # Menu 43: MDF-B
         rs = RadioSettingValueList(MDF_LIST, current_index=_settings.mdfb)
         rset = MemSetting("settings.mdfb", "Memory Display Format B", rs)
+        rset.set_doc("Set B band display mode.")
         basic.append(rset)
 
         # Menu 33: DTMFST (DTMF ST)
         rs = RadioSettingValueList(DTMFST_LIST, current_index=_settings.dtmfst)
         rset = MemSetting("settings.dtmfst", "DTMF Side Tone", rs)
+        rset.set_doc("Set how DTMF tones are heard when a PTT ID DTMF Code "
+                     "is sent.")
         basic.append(rset)
 
         # Menu 37: PTT-LT
         rs = RadioSettingValueList(PTTLT_LIST, current_index=_settings.pttlt)
         rset = MemSetting("settings.pttlt", "PTT Delay", rs)
+        rset.set_doc("Set the PTT delay time.")
         basic.append(rset)
 
         # Menu 36: TONE
         rs = RadioSettingValueList(TONE_LIST, current_index=_settings.tone)
         rset = MemSetting("settings.tone", "Tone-burst Frequency", rs)
+        rset.set_doc("Set the Tone-burst Frequency.")
         basic.append(rset)
 
         # Mneu 29: POWER ON MSG
         rs = RadioSettingValueList(PONMSG_LIST, current_index=_settings.ponmsg)
         rset = MemSetting("settings.ponmsg", "Power On Message", rs)
+        rset.set_doc("Set the Power On Message.")
         basic.append(rset)
 
         # Menu 46: STE
         rs = RadioSettingValueBoolean(_settings.ste)
         rset = MemSetting("settings.ste",
                           "Squelch Tail Eliminate (HT to HT)", rs)
+        rset.set_doc("Set the Squelch Tail Eliminate for HT to HT "
+                     "communication.")
         basic.append(rset)
 
         # Menu 40: RP-STE
         rs = RadioSettingValueList(RPSTE_LIST, current_index=_settings.rpste)
         rset = MemSetting("settings.rpste",
                           "Squelch Tail Eliminate (repeater)", rs)
+        rset.set_doc("Set the Squelch Tail Eliminate time for repeater "
+                     "communication.")
         basic.append(rset)
 
         # Menu 41: RPT-RL
         rs = RadioSettingValueList(RPSTE_LIST, current_index=_settings.rptrl)
         rset = MemSetting("settings.rptrl", "STE Repeater Delay", rs)
+        rset.set_doc("Set the delay time for Squelch Tail Eliminate "
+                     "when using a repeater.")
         basic.append(rset)
 
         # Menu 38: MENU EXIT TIME
         rs = RadioSettingValueList(MENUQUIT_LIST,
                                    current_index=_settings.menuquit)
         rset = MemSetting("settings.menuquit", "Menu Auto Quit", rs)
+        rset.set_doc("Set the time for the radio to automatically exit the "
+                     "menu system.")
         basic.append(rset)
 
         # Menu 34: AUTOLOCK
         rs = RadioSettingValueList(AUTOLK_LIST, current_index=_settings.autolk)
         rset = MemSetting("settings.autolk", "Key Auto Lock", rs)
+        rset.set_doc("Set the time for the radio to automatically lock "
+                     "the keypad.")
         basic.append(rset)
 
-        # Menu 28: CDCSS SAVE MODE
+        # Menu 28: CTCSS SAVE MODE
         rs = RadioSettingValueList(QTSAVE_LIST, current_index=_settings.qtsave)
         rset = MemSetting("settings.qtsave", "QT Save Type", rs)
+        rset.set_doc("Set how the CTCSS/DCS codes are saved to a channel.")
         basic.append(rset)
 
         # Menu 47: AL-MODE
         rs = RadioSettingValueList(ALMODE_LIST, current_index=_settings.almode)
         rset = MemSetting("settings.almode", "Alarm Mode", rs)
+        rset.set_doc("Set how the radio will send an Alarm.")
         basic.append(rset)
 
         # Menu 11: ROGER
         rs = RadioSettingValueList(ROGER_LIST, current_index=_settings.roger)
         rset = MemSetting("settings.roger", "Roger", rs)
+        rset.set_doc("Set the Roger Beep mode for when the PTT is released.")
         basic.append(rset)
 
-        # Menu 44: Alarm Mode
+        # Menu 44: Alarm ON/OFF
         rs = RadioSettingValueBoolean(_settings.alarmsound)
         rset = MemSetting("settings.alarmsound", "Alarm Sound", rs)
+        rset.set_doc("Enable to allow the radio to send an alarm.")
         basic.append(rset)
 
+        if self._has_hf:
+            s1 = "FM/AM/SSB Radio"
+            s2 = "Allow access to FM/AM/SSB RX channels on radio."
+        else:
+            s1 = "FM Radio"
+            s2 = "Allow access to FM broadcast RX channels on radio."
+
         rs = RadioSettingValueInvertedBoolean(not _settings.fmradio)
-        rset = MemSetting("settings.fmradio", "FM Radio", rs)
+        rset = MemSetting("settings.fmradio", s1, rs)
+        rset.set_doc(s2)
         basic.append(rset)
 
         rs = RadioSettingValueBoolean(_settings.kblock)
         rset = MemSetting("settings.kblock", "KB Lock", rs)
+        rset.set_doc("Enable radio keypad locked by default.")
         basic.append(rset)
 
         # Menu 16: BEEP PROMPT
         rs = RadioSettingValueBoolean(_settings.beep)
         rset = MemSetting("settings.beep", "Beep", rs)
+        rset.set_doc("Enable radio keypad Beep when pressing keys.")
         basic.append(rset)
 
         dtmf = RadioSettingGroup("dtmf", "DTMF Settings")
@@ -721,26 +770,31 @@
         for i in range(0, 15):
             _codeobj = self._memobj.pttid[i].code
             _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F])
-            rs = RadioSettingValueString(0, 5, _code, False)
+            rs = RadioSettingValueString(0, 6, _code, False)
             rs.set_charset(DTMF_CHARS)
             rset = RadioSetting("pttid/%i.code" % i,
                                 "PTT-ID Code %i" % (i + 1), rs)
-            rset.set_apply_callback(apply_code, self._memobj.pttid[i], 5)
+            rset.set_apply_callback(apply_code, self._memobj.pttid[i], 6)
+            rset.set_doc("Set the PTT-ID % i Code DTMF sequence." % (i + 1))
             dtmf.append(rset)
 
         rs = RadioSettingValueList(DTMFSPEED_LIST,
                                    current_index=_dtmf.dtmfon)
-        rset = MemSetting("dtmf.dtmfon", "DTMF Speed (on)", rs)
+        rset = MemSetting("dtmf.dtmfon", "DTMF Speed (On)", rs)
+        rset.set_doc("Set the duration for how long each DMTF tone is ON.")
         dtmf.append(rset)
 
         rs = RadioSettingValueList(DTMFSPEED_LIST,
                                    current_index=_dtmf.dtmfoff)
-        rset = MemSetting("dtmf.dtmfoff", "DTMF Speed (off)", rs)
+        rset = MemSetting("dtmf.dtmfoff", "DTMF Speed (Off)", rs)
+        rset.set_doc("Set the duration for how long the pause is between "
+                     "DTMF tones.")
         dtmf.append(rset)
 
         rs = RadioSettingValueList(
             PTTID_LIST, current_index=_settings.pttid)
         rset = MemSetting("settings.pttid", "PTT ID", rs)
+        rset.set_doc("Set when the PTT-ID is to be sent.")
         dtmf.append(rset)
 
         spec = RadioSettingGroup("spec", self.MODEL + " Specific")
@@ -762,6 +816,7 @@
             'and back ON to have the MODE changes take full effect.\n'
             'DO NOT attempt to edit any settings until uploading to and '
             'downloading from the radio with the new operating MODE.')
+        rset.set_doc("Set the radio's Operating Mode.")
         spec.append(rset)
 
         if self._has_bt_denoise:
@@ -769,29 +824,57 @@
             rs = RadioSettingValueBoolean(_settings.noise_reduction)
             rset = MemSetting("settings.noise_reduction",
                               "Noise reduction", rs)
+            rset.set_doc("Set the radio's automatic Noise Reduction feature.")
             spec.append(rset)
 
             # Menu 47: Bluetooth
             rs = RadioSettingValueBoolean(_settings.bluetooth)
             rset = MemSetting("settings.bluetooth", "Bluetooth", rs)
+            rset.set_doc("Enable Bluetooth (BLE). "
+                         "Bluetooth can be used to program the radio over a "
+                         "BLE connection.")
             spec.append(rset)
 
         # Menu 23: PF2 Short
+        if self._has_sp0:
+            skey2_sp = _settings.skey2_sp0
+            key = "settings.skey2_sp0"
+        else:
+            skey2_sp = _settings.skey2_sp1
+            key = "settings.skey2_sp1"
+
         rs = RadioSettingValueList(self.SKEY_SP_LIST,
-                                   current_index=_settings.skey2_sp)
-        rset = MemSetting("settings.skey2_sp", "PF2 Key (Short Press)", rs)
+                                   current_index=skey2_sp)
+        rset = MemSetting(key, "PF2 Key (Short Press)", rs)
+        rset.set_doc("Set what a Short Press on the PF2 Key will do.")
         spec.append(rset)
 
         # Menu 24: PF2 Long
+        if self._has_sp0:
+            skey2_lp = _settings.skey2_sp1
+            key = "settings.skey2_sp1"
+        else:
+            skey2_lp = _settings.skey2_lp
+            key = "settings.skey2_lp"
+
         rs = RadioSettingValueList(
-            self.SKEY_LIST, current_index=_settings.skey2_lp)
-        rset = MemSetting("settings.skey2_lp", "PF2 Key (Long Press)", rs)
+            self.SKEY_LIST, current_index=skey2_lp)
+        rset = MemSetting(key, "PF2 Key (Long Press)", rs)
+        rset.set_doc("Set what a Long Press on the PF2 Key will do.")
         spec.append(rset)
 
         # Menu 25: PF3 Short
+        if self._has_sp0:
+            skey3_sp = _settings.skey2_lp
+            key = "settings.skey2_lp"
+        else:
+            skey3_sp = _settings.skey3_sp
+            key = "settings.skey3_sp"
+
         rs = RadioSettingValueList(
-            self.SKEY_LIST, current_index=_settings.skey3_sp)
-        rset = MemSetting("settings.skey3_sp", "PF3 Key (Short Press)", rs)
+            self.SKEY_LIST, current_index=skey3_sp)
+        rset = MemSetting(key, "PF3 Key (Short Press)", rs)
+        rset.set_doc("Set what a Short Press on the PF3 Key will do.")
         spec.append(rset)
 
         if self.MODEL not in ["RT-900_BT", "RT-920"]:
@@ -799,17 +882,44 @@
             if self._has_am_switch:
                 rs = RadioSettingValueBoolean(_settings.am_mode)
                 rset = MemSetting("settings.am_mode", "AM Mode", rs)
+                rset.set_doc("Enable to set the RX modulation mode to AM.")
                 spec.append(rset)
 
         # Menu 7: TDR - Dual freq standby
         rs = RadioSettingValueBoolean(_settings.tdr)
         rset = MemSetting("settings.tdr", "TDR - Dual frequency standby", rs)
+        rset.set_doc("Set Dual Frequency Standby (Dual Watch).")
         spec.append(rset)
 
         if self._has_single_mode:
-            # Menu 51: Single Mode - Single fre channel display
+            # Menu 51: Single Mode - Single freq channel display
             rs = RadioSettingValueBoolean(_settings.single_mode)
             rset = MemSetting("settings.single_mode", "Single Mode", rs)
+            rset.set_doc("Set radio to display a single frequency/channel.")
+            spec.append(rset)
+
+        if self.MODEL in ["RT-920"]:
+            # Menu 53: FM Interupt
+            rs = RadioSettingValueBoolean(_settings.fm_interrupt)
+            rset = MemSetting("settings.fm_interrupt", "FM Interrupt", rs)
+            rset.set_doc("While using broadcast FM, "
+                         "allow incoming RX to interrupt the FM "
+                         "broadcast audio.")
+            spec.append(rset)
+
+        if self._has_zone_or_channel:
+            # Menu 10: Zone or Channel
+            rs = RadioSettingValueList(self._zone_or_channel_list,
+                                       current_index=_settings.zone_or_channel)
+            rset = MemSetting("settings.zone_or_channel",
+                              "Zone or Channel", rs)
+            rset.set_warning(
+                 "Changing this setting requires saving the .IMG file and "
+                 "opening it back up to enable/disable the Banks (Zones) "
+                 "preview tab.")  # and the Zone Name sub-menu.")
+            rset.set_doc(
+                "Set Zone Mode (static banks) or Full Channel "
+                "(flat) memmory channel mode.")
             spec.append(rset)
 
         # VFO A/B settings
@@ -821,6 +931,8 @@
         # Menu 21: VFO A/B BCL (Busy lock)
         rs = RadioSettingValueBoolean(_settings.busy_lock)
         rset = MemSetting("settings.busy_lock", "BCL", rs)
+        rset.set_doc("Set Busy Channel Lockout. When selected, disables PTT "
+                     "when the current frequency is busy.")
         abblock.append(rset)
 
         # Menu 30 VFO DTMF code
@@ -829,12 +941,14 @@
             current_index=_settings.pttid
         )
         rset = MemSetting("settings.pttid", "DTMF Code", rs)
+        rset.set_doc("Set when to send PTT-ID DTMF codes")
         abblock.append(rset)
 
         # Menu 42: TX-A/B
         rs = RadioSettingValueList(
             DUALTX_LIST, current_index=_settings.dualtx)
         rset = MemSetting("settings.dualtx", "TX-A/B", rs)
+        rset.set_doc("Set which Band will be used for TX when PTT is pressed.")
         abblock.append(rset)
 
         # VFO A channel sub menu
@@ -845,6 +959,7 @@
         rs = RadioSettingValueList(WORKMODE_LIST,
                                    current_index=_settings.vfomra)
         rset = MemSetting("settings.vfomra", "Work Mode", rs)
+        rset.set_doc("Set A Band Work Mode.")
         achannel.append(rset)
 
         # VFO A Freq
@@ -887,23 +1002,27 @@
         rs.set_validate_callback(freq_validate)
         rset = RadioSetting("vfo.a.freq", "Frequency", rs)
         rset.set_apply_callback(apply_freq, vfo.a)
+        rset.set_doc("Set A Band VFO frequency.")
         achannel.append(rset)
 
         # Menu 01: A Step
         rs = RadioSettingValueMap(self._step_map, vfo.a.step)
         rset = MemSetting("vfo.a.step", "Tuning Step", rs)
+        rset.set_doc("Set A Band frequency Tuning Step.")
         achannel.append(rset)
 
         # Menu 02: TX Power
         rs = RadioSettingValueList([str(x) for x in self.POWER_LEVELS],
                                    current_index=vfo.a.txpower)
         rset = MemSetting("vfo.a.txpower", "TX Power", rs)
+        rset.set_doc("Set A Band TX Power.")
         achannel.append(rset)
 
         # Menu 05: Wide/Narrow Band
         rs = RadioSettingValueList(self._bandwidth_list,
                                    current_index=vfo.a.widenarr)
         rset = MemSetting("vfo.a.widenarr", "Bandwidth", rs)
+        rset.set_doc("Set A Band Bandwidth.")
         achannel.append(rset)
 
         # Menu 12,13: RX ctcss/dtsc
@@ -913,6 +1032,7 @@
         rset = RadioSetting("vfo.a.rxtone", "RX CTCSS/DCS", rs)
         rset.set_apply_callback(self.apply_vfo_tone,
                                 self._memobj.vfo.a, "rxtone")
+        rset.set_doc("Set A Band RX CTCSS or DCS code.")
         achannel.append(rset)
 
         # Menu 14,15: TX ctcss/dtsc
@@ -922,6 +1042,7 @@
         rset = RadioSetting("vfo.a.txtone", "TX CTCSS/DCS", rs)
         rset.set_apply_callback(self.apply_vfo_tone,
                                 self._memobj.vfo.a, "txtone")
+        rset.set_doc("Set A Band TX CTCSS or DCS code.")
         achannel.append(rset)
 
         # Menu 16: Voice Privacy (encryption)
@@ -929,6 +1050,7 @@
                                    current_index=vfo.a.voicepri)
         rset = RadioSetting("vfo.a.voicepri",
                             "Voice Privacy - Subtone Encryption", rs)
+        rset.set_doc("Set A Band Voice Privacy - subtone voice encryption.")
         achannel.append(rset)
 
         def convert_bytes_to_offset(bytes):
@@ -948,23 +1070,27 @@
                                      convert_bytes_to_offset(vfo.a.offset))
         rset = RadioSetting("vfo.a.offset", "Offset (MHz)", rs)
         rset.set_apply_callback(apply_offset, vfo.a)
+        rset.set_doc("Set A Band TX frequency offset value.")
         achannel.append(rset)
 
         # Menu 27: Offset direction
         rs = RadioSettingValueList(self._offset_list,
                                    current_index=vfo.a.sftd)
         rset = MemSetting("vfo.a.sftd", "Offset Direction", rs)
+        rset.set_doc("Set A Band TX frequency offset direction.")
         achannel.append(rset)
 
         # Menu 29: S-Code DTMF 1-15
         rs = RadioSettingValueList(self._scode_list,
                                    current_index=vfo.a.scode)
         rset = MemSetting("vfo.a.scode", "S-CODE", rs)
+        rset.set_doc("Set the A Band DTMF code ID to use for PTT ID.")
         achannel.append(rset)
 
         # Menu 45: Scramble
         rs = RadioSettingValueMap(self._scramble_map, vfo.a.scramble)
         rset = MemSetting("vfo.a.scramble", "Scramble", rs)
+        rset.set_doc("Set A Band voice Scramble.")
         achannel.append(rset)
 
         # Menu 50: RX Modulation
@@ -972,6 +1098,7 @@
             rs = RadioSettingValueList(self._rx_modulation_list,
                                        current_index=vfo.a.rxmod)
             rset = MemSetting("vfo.a.rxmod", "RX Modulation", rs)
+            rset.set_doc("Set A Band RX Modulation.")
             achannel.append(rset)
 
         # VFO B channel sub menu
@@ -982,6 +1109,7 @@
         rs = RadioSettingValueList(WORKMODE_LIST,
                                    current_index=_settings.vfomrb)
         rset = MemSetting("settings.vfomrb", "Work Mode", rs)
+        rset.set_doc("Set B Band Work Mode.")
         bchannel.append(rset)
 
         # VFO B Freq
@@ -990,23 +1118,27 @@
         rs.set_validate_callback(freq_validate)
         rset = RadioSetting("vfo.b.freq", "Frequency", rs)
         rset.set_apply_callback(apply_freq, vfo.b)
+        rset.set_doc("Set B Band VFO frequency.")
         bchannel.append(rset)
 
         # Menu 01: B Step
         rs = RadioSettingValueMap(self._step_map, vfo.b.step)
         rset = MemSetting("vfo.b.step", "Tuning Step", rs)
+        rset.set_doc("Set B Band frequency Tuning Step.")
         bchannel.append(rset)
 
         # Menu 02: TX Power
         rs = RadioSettingValueList([str(x) for x in self.POWER_LEVELS],
                                    current_index=vfo.b.txpower)
         rset = MemSetting("vfo.b.txpower", "TX Power", rs)
+        rset.set_doc("Set B Band TX Power.")
         bchannel.append(rset)
 
         # Menu 05: Wide/Narrow Band
         rs = RadioSettingValueList(self._bandwidth_list,
                                    current_index=vfo.b.widenarr)
         rset = MemSetting("vfo.b.widenarr", "Bandwidth", rs)
+        rset.set_doc("Set B Band Bandwidth.")
         bchannel.append(rset)
 
         # Menu 12,13: RX ctcss/dtsc
@@ -1016,6 +1148,7 @@
         rset = RadioSetting("vfo.b.rxtone", "RX CTCSS/DCS", rs)
         rset.set_apply_callback(self.apply_vfo_tone,
                                 self._memobj.vfo.b, "rxtone")
+        rset.set_doc("Set B Band RX CTCSS or DCS code.")
         bchannel.append(rset)
 
         # Menu 14,15: TX ctcss/dtsc
@@ -1025,6 +1158,7 @@
         rset = RadioSetting("vfo.b.txtone", "TX CTCSS/DCS", rs)
         rset.set_apply_callback(self.apply_vfo_tone,
                                 self._memobj.vfo.b, "txtone")
+        rset.set_doc("Set B Band TX CTCSS or DCS code.")
         bchannel.append(rset)
 
         # Menu 16: Voice Privacy (encryption)
@@ -1032,6 +1166,7 @@
                                    current_index=vfo.b.voicepri)
         rset = MemSetting("vfo.b.voicepri",
                           "Voice Privacy - Subtone Encryption", rs)
+        rset.set_doc("Set B Band Voice Privacy - subtone voice encryption.")
         bchannel.append(rset)
 
         # Menu 26: Offset
@@ -1039,22 +1174,26 @@
                                      convert_bytes_to_offset(vfo.b.offset))
         rset = RadioSetting("vfo.b.offset", "Offset (MHz)", rs)
         rset.set_apply_callback(apply_offset, vfo.b)
+        rset.set_doc("Set B Band TX frequency offset value.")
         bchannel.append(rset)
 
         # Menu 27: Offset direction
         rs = RadioSettingValueList(self._offset_list, current_index=vfo.b.sftd)
         rset = MemSetting("vfo.b.sftd", "Offset Direction", rs)
+        rset.set_doc("Set B Band TX frequency offset direction.")
         bchannel.append(rset)
 
         # Menu 29: S-Code DTMF 1-15
         rs = RadioSettingValueList(
             self._scode_list, current_index=vfo.b.scode)
         rset = MemSetting("vfo.b.scode", "S-CODE", rs)
+        rset.set_doc("Set the B Band DTMF code ID to use for PTT ID.")
         bchannel.append(rset)
 
         # Menu 45: Scramble
         rs = RadioSettingValueMap(self._scramble_map, vfo.b.scramble)
         rset = MemSetting("vfo.b.scramble", "Scramble", rs)
+        rset.set_doc("Set B Band voice Scramble.")
         bchannel.append(rset)
 
         # Menu 50: RX Modulation
@@ -1062,8 +1201,83 @@
             rs = RadioSettingValueList(self._rx_modulation_list,
                                        current_index=vfo.b.rxmod)
             rset = MemSetting("vfo.b.rxmod", "RX Modulation", rs)
+            rset.set_doc("Set B Band RX Modulation.")
             bchannel.append(rset)
 
+        # SSB Settings, RT-920, BJ7800 Only
+        if self._has_hf:
+            ssbblock = RadioSettingGroup("ssbblock", "FM/AM/SSB Modulation")
+            spec.append(ssbblock)
+
+            # HF mode submenu
+            modes = RadioSettingSubGroup("modes", "Modes")
+            ssbblock.append(modes)
+
+            # SSB Work Mode
+            ssbwm = self._memobj.ssb_settings
+            rs = RadioSettingValueList(
+                self._ssb_workmode_list,
+                current_index=ssbwm.workmode
+            )
+            rset = MemSetting("ssb_settings.workmode", "Work Mode", rs)
+            rset.set_doc("Set HF Workmode.")
+            modes.append(rset)
+
+            # SSB Modulation Mode
+            ssb = self._memobj.ssb
+            rs = RadioSettingValueList(
+                self._ssb_modulation_list,
+                current_index=ssb.modulation
+            )
+            rset = MemSetting("ssb.modulation", "Modulation Mode", rs)
+            rset.set_doc("Set HF RX Modulation Mode.")
+            modes.append(rset)
+
+            # AM mode submenu
+            amsettings = RadioSettingSubGroup("amsettings", "AM Settings")
+            ssbblock.append(amsettings)
+
+            # AM Step Freq
+            stepfreq = self._memobj.stepfreq
+            rs = RadioSettingValueList(
+                self._am_step_freq_list,
+                current_index=stepfreq.am
+            )
+            rset = MemSetting("stepfreq.am", "Step Freq", rs)
+            rset.set_doc("Set HF AM RX Step Frequency.")
+            amsettings.append(rset)
+
+            # AM RX Gain
+            rs = RadioSettingValueList(
+                self._rx_gain_list,
+                current_index=ssb.am_rxgain
+            )
+            rset = MemSetting("ssb.am_rxgain", "RX Gain", rs)
+            rset.set_doc("Set HF AM RX Gain value.")
+            amsettings.append(rset)
+
+            # SSB mode submenu
+            ssbsettings = RadioSettingSubGroup("ssbsettings", "SSB Settings")
+            ssbblock.append(ssbsettings)
+
+            # SSB Step Freq
+            rs = RadioSettingValueList(
+                self._ssb_step_freq_list,
+                current_index=stepfreq.ssb
+            )
+            rset = MemSetting("stepfreq.ssb", "Step Freq", rs)
+            rset.set_doc("Set HF SSB RX Step Frequency.")
+            ssbsettings.append(rset)
+
+            # SSB RX Gain
+            rs = RadioSettingValueList(
+                self._rx_gain_list,
+                current_index=stepfreq.ssb_rxgain
+            )
+            rset = MemSetting("stepfreq.ssb_rxgain", "RX Gain", rs)
+            rset.set_doc("Set HF SSB RX Gain value.")
+            ssbsettings.append(rset)
+
         return group
 
     @classmethod
@@ -1116,7 +1330,7 @@
         """Parse the tone data to encode from UI to mem"""
         match mode:
             case "" | None:
-                memval.set_raw("\x00\x00")
+                memval.fill_raw(b"\x00")
             case "Tone" | "TSQL":
                 memval.set_value(int(value * 10))
             case "DTCS":
@@ -1198,7 +1412,7 @@
         # Memory number
         mem.number = number
 
-        if _mem.get_raw()[:1] == b"\xFF":
+        if _mem.get_raw()[:1] == b"\xff":
             mem.empty = True
             return mem
 
@@ -1207,7 +1421,7 @@
         if mem.freq == 0:
             mem.empty = True
         # tx freq can be blank
-        if _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF":
+        if _mem.txfreq.get_raw() == b"\xff\xff\xff\xff":
             # TX freq not set
             mem.offset = 0
             mem.duplex = "off"
@@ -1279,13 +1493,16 @@
         # BCL (Busy Channel Lockout)
         rs = RadioSettingValueBoolean(_mem.bcl)
         rset = RadioSetting("bcl", "BCL", rs)
+        rset.set_doc("Set Busy Channel Lockout. When selected, disables PTT "
+                     "when the current channel is busy.")
         mem.extra.append(rset)
 
         # LearnFHSS (per-channel learn / FHSS flag). The OEM CPS labels
         # this column "LearnFHSS"; the open-source firmware reads the
         # same bit as chFlag3.b0 / fhssFlag (Core/Radio.c).
         rs = RadioSettingValueBoolean(_mem.learning)
-        rset = RadioSetting("learning", "LearnFHSS", rs)
+        rset = RadioSetting("learning", "Learn FHSS", rs)
+        rset.set_doc("Enable to allow automatic FHSS code selection.")
         mem.extra.append(rset)
 
         # FHSS Code (24-bit little-endian, range 0x000000-0x7FFFFF).
@@ -1296,16 +1513,19 @@
         rs = RadioSettingValueString(0, 6, _fhss_code_to_text(_mem.code))
         rs.set_validate_callback(_validate_fhss_code)
         rset = RadioSetting("fhss_code", "FHSS Code (hex)", rs)
+        rset.set_doc("Enter manual FHSS Code using HEX digits.")
         mem.extra.append(rset)
 
         # PTT-ID
         rs = RadioSettingValueList(PTTID_LIST, current_index=_mem.pttid)
         rset = RadioSetting("pttid", "PTT ID", rs)
+        rset.set_doc("Set when the PTT-ID is to be sent.")
         mem.extra.append(rset)
 
         # Signal (DTMF Encoder Group #)
         rs = RadioSettingValueList(PTTIDCODE_LIST, current_index=_mem.scode)
         rset = RadioSetting("scode", "PTT ID Code", rs)
+        rset.set_doc("Set the DTMF code ID to use for PTT ID.")
         mem.extra.append(rset)
 
         return mem
@@ -1314,15 +1534,15 @@
         _mem = self._memobj.memory[mem.number - 1]
 
         if mem.empty:
-            _mem.set_raw("\xff" * 32)
+            _mem.fill_raw(b"\xff")
             return
 
-        _mem.set_raw("\x00" * 16 + "\xFF" * 16)
+        _mem.set_raw("\x00" * 16 + "\xff" * 16)
 
         _mem.rxfreq = mem.freq / 10
 
         if mem.duplex == "off":
-            _mem.txfreq.fill_raw(b"\xFF")
+            _mem.txfreq.fill_raw(b"\xff")
         elif mem.duplex == "split":
             _mem.txfreq = mem.offset / 10
         elif mem.duplex == "+":
@@ -1337,7 +1557,7 @@
             try:
                 _mem.name[i] = mem.name[i]
             except IndexError:
-                _mem.name[i] = "\xFF"
+                _mem.name[i] = "\xff"
 
         txmode = rxmode = ''
         txval = rxval = 0
@@ -1431,8 +1651,8 @@
     _has_bt_denoise = False
     _has_am_per_channel = False
     _has_am_switch = not _has_am_per_channel
-    _has_single_mode = False    # Fw V0.14P has single mode, but no menu for it
-    #                             it's toggled by Menu 7, TDR
+    _has_single_mode = False
+    _has_hf = False
 
     _upper = 999  # fw V1.14P expands from 512 to 999 channels
 
@@ -1558,6 +1778,7 @@
     _has_am_per_channel = True
     _has_am_switch = not _has_am_per_channel
     _has_single_mode = True
+    _has_hf = False
 
     def get_bank_model(self):
         return chirp_common.StaticBankModel(self, banks=15)
@@ -1567,7 +1788,7 @@
         rp = super().get_prompts()
         rp.experimental = \
             ('This driver is a beta version for the RT-910'
-             ' Non Bluetooth running Firmware V0.11\n'
+             ' Non-Bluetooth running Firmware V0.11\n'
              '\n'
              'Please save an unedited copy of your first successful\n'
              'download to a CHIRP Radio Images(*.img) file.\n\n'
@@ -1576,19 +1797,47 @@
         return rp
 
 
+class RT920Bank(chirp_common.NamedBank):
+    """RT-920 Bank"""
+    def get_name(self):
+        """decode bank name from char array into string"""
+        _bank = self._model._radio._memobj.zones[self._index - 1]
+        name = str(_bank.name).rstrip(" \n\t\x00\xff")  # remove filler chars
+
+        if len(name) == 0:
+            name = "ZONE %i" % self._index
+
+        return name
+
+    def set_name(self, name):
+        """encode bank name into \xff filled char array"""
+        _bank = self._model._radio._memobj.zones[self._index - 1]
+        _bank.name = name[:len(_bank.name)].rstrip()\
+            .ljust(len(_bank.name), "\xff")
+
+
+class RT920BankModel(chirp_common.StaticBankModel):
+    """RT-920 Bank Model"""
+    def __init__(self, radio, name, banks):
+        super(RT920BankModel, self).__init__(radio, name, banks)
+        self._num_banks = banks
+        self._rf = radio.get_features()
+        self._banks = []
+        for i in range(self._num_banks):
+            self._banks.append(RT920Bank(self, i + 1, "ZONE %i" % (i + 1)))
+
+
 @directory.register
 class RT920(RT900BT):
     # ==========
     # Notice to developers:
-    # The RT-920 support in this driver is currently based upon V0.14P
-    # firmware with 15 banks/zones of 64 channels steps.
-    # Also known to work on the SHJ H28Y Pro V0.07 firmware
+    # The RT-920 support in this driver is currently based upon V0.18
+    # firmware with 10 banks/zones of 99 channels.
     # ==========
     """Radtel RT-920"""
     VENDOR = "Radtel"
     MODEL = "RT-920"
 
-    # _magic = b"PROGRAMBT80U"  # RT-900
     _magic = b"PROGRAMBT11U"  # RT-920
     #  step of 1.25 to allow UK CB Freqs
     _steps = [1.25, 2.5, 5.0, 6.25, 8.33, 10.0, 12.5, 20.0, 25.0, 50.0]
@@ -1601,41 +1850,178 @@
                  "SOS",
                  "Spectrum"]
     SKEY_SP_LIST = SKEY_LIST + ["PTTB"]
+    _zone_or_channel_list = ["Zone Mode", "Full Channel"]
+    _ssb_modulation_list = [
+        "FM",
+        "AM",
+        "LSB",
+        "USB",
+        "CW",
+    ]
+    _ssb_workmode_list = [
+        "VFO Mode",
+        "CH Mode",
+    ]
+    _am_step_freq_list = [
+        "1K",
+        "5K",
+        "9K",
+        "10K",
+        "100K",
+    ]
+    _ssb_step_freq_list = [
+        "1K",
+        "5K",
+        "10K",
+        "100K",
+        "500K",
+        "1000K",
+    ]
+    _rx_gain_list = ["AGC"] + \
+        ["%ddB" % x for x in range(0, -36, -1)]
 
-    _upper = 960  # fw V0.24P supports 960 channels
+    _upper = 990  # fw V0.18 supports 990 channels
     _mem_params = (_upper,  # number of channels
                    )
+    _banks = 10
     _ranges = [
-        (0x0000, 0x7800),  # 15 zones of 64 frequencies,
-                           # equals 960 channels of 32 bytes each
-                           # 15 * 64 * 32 = 0x7800
+        (0x0000, 0x7BC0),  # 10 zones of 99 frequencies,
+                           # equals 990 channels of 32 bytes each
+                           # 10 * 99 * 32 = 0x7BC0
         (0x8000, 0x8040),
         (0x9000, 0x9040),
         (0xA000, 0xA140),
-        (0xD000, 0xD040)  # Radio mode hidden setting
+        (0xB000, 0xB400),  # FM, AM, HF frequencies
+        (0xC000, 0xC400),  # FM, AM, HF names
+        (0xC800, 0XC8A0),  # static bank names, 10 banks * 16 bytes ea = 0xA0
+        (0xD000, 0xD040),  # Radio mode hidden setting
     ]
 
+    _rt920_specific_fmt = """
+    #seekto 0xb000;
+    // 2 byte fm vfo freq
+    struct {
+        ul16 freq;
+    } fm_vfo;
+    // 15ea 2 byte fm chan freq
+    struct {
+        ul16 freq;
+    } fm_freqs[%d];
+
+    #seekto 0xb021; // SSB settings
+    struct {
+        u8 workmode; // VFO/Ch
+    } ssb_settings;
+
+    #seekto 0xb022;
+    // 2 byte am vfo freq
+    struct {
+        ul16 freq;
+    } am_vfo;
+    // 15ea 2 byte am chan freq
+    struct {
+        ul16 freq;
+    } am_freqs[%d];
+
+    #seekto 0xb043; // ssb
+    struct {
+        u8 modulation; // modulation mode
+        u8 am_rxgain; // AM RX gain
+    } ssb;
+
+    #seekto 0xb045;
+    // 5 byte hf vfo chan
+    struct {
+        ul16 freq;
+        u8 bandwidth;
+        il16 beatfreq; // can be negitive
+    } hf_vfo;
+    // 15ea 5 byte hf chans
+        struct {
+        ul16 freq;
+        u8 bandwidth;
+        il16 beatfreq; // can be negitive
+    } hf_freqs[%d];
+
+    #seekto 0xb096;
+    struct {
+        u8 ssb;
+        u8 am;
+        u8 ssb_rxgain;
+    } stepfreq;
+
+    #seekto 0xc010; // 15ea 16 byte fm chan names
+    struct {
+        char name[12];
+        u8 unused[4];
+    } fm_names[%d];
+
+    #seekto 0xc110; // 15ea 16 byte am chan names (RT-920 fw v 0.xx)
+    struct {
+        char name[12];
+        u8 unused[4];
+    } am_names[%d];
+
+    #seekto 0xc210; // 15ea 16 byte ssb chan names (RT-920 fw v 0.xx)
+    struct {
+        char name[12];
+        u8 unused[4];
+    } hf_names[%d];
+
+    #seekto 0xC800; // 10ea 16 byte zone names (RT-920 fw V0.17)
+    struct {
+      char name[10];
+      u8 unused[6];
+    } zones[%d];
+    """
+
     _has_bt_denoise = True
     _has_am_per_channel = True
     _has_am_switch = not _has_am_per_channel
-    _has_single_mode = False
+    _has_single_mode = True
+    _has_zone_or_channel = True
+    _has_zone_names = True
+    _has_sp0 = False  # spkey addresses are not shifted
+    _has_hf = True
 
     def get_bank_model(self):
-        return chirp_common.StaticBankModel(self, banks=15)
+        return RT920BankModel(self, "Zones", self._banks)
 
     def get_features(self):
         rf = super().get_features()
-        rf.has_bank = True  # Firmware V0.14P supports 15
-        #                     "static zones" of 64 frequencies
+        # Firmware V0.18 supports 10
+        # optional "static zones" of 99 frequencies
+        # or 990 flat chanels
+        if self._memobj is not None and hasattr(self._memobj, "settings"):
+            rf.has_bank = not self._memobj.settings.zone_or_channel
+        else:
+            rf.has_bank = False  # default to flat mode if settings not init'ed
+
+        rf.has_bank_names = self._has_zone_names
         rf.valid_tuning_steps = self._steps
+        rf.has_sub_devices = self._has_hf
         return rf
 
+    def process_mmap(self):
+        AUX_CHANS_FM = AUX_CHANS_AM = AUX_CHANS_HF = 15
+        mem_format = MEM_FORMAT % self._mem_params + \
+            self._rt920_specific_fmt % (
+                AUX_CHANS_FM,
+                AUX_CHANS_AM,
+                AUX_CHANS_HF,
+                AUX_CHANS_FM,
+                AUX_CHANS_AM,
+                AUX_CHANS_HF,
+                self._banks,
+            )
+        self._memobj = bitwise.parse(mem_format, self._mmap)
+
     @classmethod
     def get_prompts(cls):
         rp = super().get_prompts()
         rp.experimental = \
             ('This driver is a beta version for the RT-920'
-             ' running Firmware V0.14P\n'
+             ' running Firmware V0.18\n'
              '\n'
              'Please save an unedited copy of your first successful\n'
              'download to a CHIRP Radio Images(*.img) file.\n\n'
@@ -1643,6 +2029,287 @@
              )
         return rp
 
+    def get_sub_devices(self):
+        return [RT920VhfUfh(self._mmap),
+                RT920FM(self._mmap),
+                RT920AM(self._mmap),
+                RT920HF(self._mmap),
+                ]
+
+
+class RT920VhfUfh(RT920):
+    """Radtel RT-920 VHF/UHF subdevice"""
+    VENDOR = "Radtel"
+    MODEL = "RT-920"
+    VARIANT = "VHF/UHF"
+
+
+class RT920FM(RT920):
+    """Radtel RT-920 FM broadcast subdevice"""
+    VENDOR = "Radtel"
+    MODEL = "RT-920"
+    VARIANT = "FM Broadcast"
+
+    _upper = 15
+    _mem_params = (_upper,  # number of channels
+                   )
+    _valid_bands = [(64000000, 108000000)]  # in Mhz, 64.0-108 MHz
+    SPECIAL_CHANNELS = ["VFO"]
+
+    def get_features(self):
+        rf = chirp_common.RadioFeatures()
+        rf.valid_bands = self._valid_bands
+        rf.memory_bounds = (1, self._upper)
+        rf.can_delete = True
+        rf.can_odd_split = False
+        rf.has_bank = False
+        rf.has_bank_index = False
+        rf.has_bank_names = False
+        rf.has_comment = False
+        rf.has_cross = False
+        rf.has_ctone = False
+        rf.has_dtcs = False
+        rf.has_dtcs_polarity = False
+        rf.has_mode = True
+        rf.has_offset = False
+        rf.has_settings = False
+        rf.has_sub_devices = False
+        rf.has_tuning_step = False
+        rf.valid_characters = RT900._valid_chars
+        rf.valid_cross_modes = []
+        rf.valid_dtcs_codes = []
+        rf.valid_dtcs_pols = []
+        rf.valid_duplexes = []
+        rf.valid_modes = ["AM", "WFM", "Auto"]
+        rf.valid_name_length = 12
+        rf.valid_skips = []
+        rf.valid_special_chans = self.SPECIAL_CHANNELS
+        rf.valid_tuning_steps = [
+            1.0, 2.5, 5.0, 6.25, 8.33, 10.0, 12.5, 20.0, 25.0, 50.0,
+            ]
+        rf.valid_tmodes = []
+        rf.valid_tones = []
+        return rf
+
+    def get_raw_memory(self, number):
+        if isinstance(number, str):
+            return repr(self._memobj.fm_vfo)
+        else:
+            return (repr(self._memobj.fm_freqs[number - 1]) +
+                    repr(self._memobj.fm_names[number - 1]))
+
+    def get_memory(self, number):
+        mem = chirp_common.Memory()
+
+        if isinstance(number, str):
+            mem.number = self._upper + self.SPECIAL_CHANNELS.index(number) + 1
+            mem.extd_number = number
+            _mem = self._memobj.fm_vfo
+        else:
+            mem.number = number
+            _mem = self._memobj.fm_freqs[number - 1]
+            _name = self._memobj.fm_names[number - 1]
+
+        freq = int(_mem.freq) * 10000
+
+        if freq == 0:
+            mem.empty = True
+            return mem
+
+        mem.freq = freq
+
+        if mem.number > self._upper:
+            mem.immutable += ["name"]
+        else:
+            mem.name = str(_name.name).rstrip("\xff ")
+
+        mem.mode = "WFM"
+
+        mem.immutable += ["mode", "ctone", "rtone"]
+        return mem
+
+    def set_memory(self, mem):
+
+        if mem.number > self._upper:
+            _mem = self._memobj.fm_vfo
+        else:
+            _mem = self._memobj.fm_freqs[mem.number - 1]
+            _name = self._memobj.fm_names[mem.number - 1]
+
+        if mem.empty:
+            _mem.freq.fill_raw(b"\x00")
+            if mem.number <= self._upper:
+                _name.name.fill_raw(b"\xff")
+            return
+
+        _mem.freq = int(mem.freq / 10000)
+
+        if mem.number <= self._upper:
+            _name.name = mem.name.ljust(12, "\xff")
+
+
+class RT920AM(RT920FM):
+    """Radtel RT-920 AM broadcast subdevice"""
+    VENDOR = "Radtel"
+    MODEL = "RT-920"
+    VARIANT = "AM Broadcast"
+
+    _valid_bands = [(153000, 279000),     # in Mhz, 153-279 KHz
+                    (520000, 1710000),    # 520-1710 KHz
+                    (2300000, 26100000),  # 2300-26100 KHz
+                    ]
+
+    def get_raw_memory(self, number):
+        if isinstance(number, str):
+            return repr(self._memobj.am_vfo)
+        else:
+            return (repr(self._memobj.am_freqs[number - 1]) +
+                    repr(self._memobj.am_names[number - 1]))
+
+    def get_memory(self, number):
+        mem = chirp_common.Memory()
+
+        if isinstance(number, str):
+            mem.number = self._upper + self.SPECIAL_CHANNELS.index(number) + 1
+            mem.extd_number = number
+            _mem = self._memobj.am_vfo
+        else:
+            mem.number = number
+            _mem = self._memobj.am_freqs[number - 1]
+            _name = self._memobj.am_names[number - 1]
+
+        freq = int(_mem.freq) * 1000
+
+        if freq == 0:
+            mem.empty = True
+            return mem
+
+        mem.freq = freq
+
+        if mem.number > self._upper:
+            mem.immutable += ["name"]
+        else:
+            mem.name = str(_name.name).rstrip("\xff ")
+
+        mem.mode = "AM"
+
+        mem.immutable += ["mode", "ctone", "rtone"]
+        return mem
+
+    def set_memory(self, mem):
+
+        if mem.number > self._upper:
+            _mem = self._memobj.am_vfo
+        else:
+            _mem = self._memobj.am_freqs[mem.number - 1]
+            _name = self._memobj.am_names[mem.number - 1]
+
+        if mem.empty:
+            _mem.freq.fill_raw(b"\x00")
+            if mem.number <= self._upper:
+                _name.name.fill_raw(b"\xff")
+            return
+
+        _mem.freq = int(mem.freq / 1000)
+
+        if mem.number <= self._upper:
+            _name.name = mem.name.ljust(12, "\xff")
+
+
+class RT920HF(RT920FM):
+    """Radtel RT-920 HF LSB, USB, CW subdevice"""
+    VENDOR = "Radtel"
+    MODEL = "RT-920"
+    VARIANT = "HF"
+
+    _valid_bands = [(150000, 30000000)]  # in Mhz, 150-30000 KHz
+
+    _ssb_bandwidth_list = [
+        "0.5K", "1.0K", "1.2K", "2.2K", "3.0K", "4.0K",
+    ]
+
+    def get_raw_memory(self, number):
+        if isinstance(number, str):
+            return repr(self._memobj.hf_vfo)
+        else:
+            return (repr(self._memobj.hf_freqs[number - 1]) +
+                    repr(self._memobj.hf_names[number - 1]))
+
+    def get_memory(self, number):
+        mem = chirp_common.Memory()
+
+        if isinstance(number, str):
+            mem.number = self._upper + self.SPECIAL_CHANNELS.index(number) + 1
+            mem.extd_number = number
+            _mem = self._memobj.hf_vfo
+        else:
+            mem.number = number
+            _mem = self._memobj.hf_freqs[number - 1]
+            _name = self._memobj.hf_names[number - 1]
+
+        freq = int(_mem.freq) * 1000
+
+        if freq == 0:
+            mem.empty = True
+            return mem
+
+        mem.freq = freq
+
+        if mem.number > self._upper:
+            mem.immutable += ["name"]
+        else:
+            mem.name = str(_name.name).rstrip("\xff ")
+
+        # use Modulation Mode from SSB settings to determine Mode
+        #   defaut to LSB if AM or FM is selected as SSB Modulation Mode
+        _ssb_mod = self._memobj.ssb.modulation
+        mem.mode = "LSB" if self._ssb_modulation_list[_ssb_mod] \
+            in ["AM", "FM"] else \
+            self._ssb_modulation_list[_ssb_mod]
+
+        mem.immutable += ["mode", "ctone", "rtone"]
+
+        mem.extra = RadioSettingGroup("Extra", "extra")
+
+        # Bandwidth
+        rs = RadioSettingValueList(
+            self._ssb_bandwidth_list,
+            current_index=int(_mem.bandwidth)
+        )
+        rset = RadioSetting("bandwidth", "Bandwidth", rs)
+        rset.set_doc("SSB Channel Bandwidth (KHz).")
+        mem.extra.append(rset)
+
+        # Beat Freq
+        rs = RadioSettingValueInteger(-32760, 27240, int(_mem.beatfreq), 1)
+        rset = RadioSetting("beatfreq", "Beat Freq Offset (Hz)", rs)
+        rset.set_doc("SSB Beat Frequency Offset (Hz).")
+        mem.extra.append(rset)
+
+        return mem
+
+    def set_memory(self, mem):
+
+        if mem.number > self._upper:
+            _mem = self._memobj.hf_vfo
+        else:
+            _mem = self._memobj.hf_freqs[mem.number - 1]
+            _name = self._memobj.hf_names[mem.number - 1]
+
+        if mem.empty:
+            _mem.fill_raw(b"\x00")
+            if mem.number <= self._upper:
+                _name.name.fill_raw(b"\xff")
+            return
+
+        _mem.freq = int(mem.freq / 1000)
+
+        if mem.number <= self._upper:
+            _name.name = mem.name.ljust(12, "\xff")
+
+        for setting in mem.extra:
+            setattr(_mem, setting.get_name(), int(setting.value))
+
 
 @directory.register
 class RadioddityGS10B(RT900BT):
@@ -1682,3 +2349,81 @@
              'PROCEED AT YOUR OWN RISK!'
              )
         return rp
+
+
[email protected]
+class BJ7800(RT920):
+    # ==========
+    # Notice to developers:
+    # The BJ7800 support in this driver is currently based upon V0.15P
+    # firmware with 15 banks/zones of 64 channels.
+    # Should also work with the SHU H28Y Pro
+    # ==========
+    """Bajeton BJ7800"""
+    VENDOR = "Bajeton"
+    MODEL = "BJ7800"
+
+    _upper = 960  # fw V0.15P supports 960 channels
+    _mem_params = (_upper,  # number of channels
+                   )
+    _banks = 15
+    _ranges = [
+        (0x0000, 0x7800),  # 15 zones of 64 frequencies,
+                           # equals 960 channels of 32 bytes each
+                           # 15 * 64 * 32 = 0X7800
+        (0x8000, 0x8040),
+        (0x9000, 0x9040),
+        (0xB000, 0xB400),  # FM, AM, HF frequencies
+        (0xC000, 0xC400),  # FM, AM, HF names
+        (0xA000, 0xA140),
+        (0xD000, 0xD040),   # Radio mode hidden setting
+    ]
+
+    _has_bt_denoise = True
+    _has_am_per_channel = True
+    _has_am_switch = not _has_am_per_channel
+    _has_single_mode = False
+    _has_zone_or_channel = False
+    _has_zone_names = False  # dosen't have named zones like the RT-920
+    _has_hf = True
+
+    def get_bank_model(self):
+        return chirp_common.StaticBankModel(self, banks=self._banks)
+
+    def get_features(self):
+        rf = super().get_features()
+        # Firmware V0.15P supports 15
+        # "static zones" of 64 frequencies
+        # for 960 channels
+        rf.has_bank = True
+        rf.has_bank_names = self._has_zone_names
+        rf.valid_tuning_steps = self._steps
+        rf.has_sub_devices = self._has_hf
+        return rf
+
+    @classmethod
+    def get_prompts(cls):
+        rp = super().get_prompts()
+        rp.experimental = \
+            ('This driver is a beta version for the BJ7800'
+             ' running Firmware V0.15P\n'
+             '\n'
+             'Please save an unedited copy of your first successful\n'
+             'download to a CHIRP Radio Images(*.img) file.\n\n'
+             'PROCEED AT YOUR OWN RISK!'
+             )
+        return rp
+
+    def get_sub_devices(self):
+        return [BJ7800VhfUfh(self._mmap),
+                RT920FM(self._mmap),
+                RT920AM(self._mmap),
+                RT920HF(self._mmap),
+                ]
+
+
+class BJ7800VhfUfh(BJ7800):
+    """Bajeton BJ7800 VHF/UHF subdevice"""
+    VENDOR = "Bajeton"
+    MODEL = "BJ7800"
+    VARIANT = "VHF/UHF"
Binary files old/chirp-20260605/tests/images/Bajeton_BJ7800.img and 
new/chirp-20260612/tests/images/Bajeton_BJ7800.img differ
Binary files old/chirp-20260605/tests/images/Radtel_RT-920.img and 
new/chirp-20260612/tests/images/Radtel_RT-920.img differ

++++++ chirp.obsinfo ++++++
--- /var/tmp/diff_new_pack.pel5pF/_old  2026-06-13 18:49:37.979151456 +0200
+++ /var/tmp/diff_new_pack.pel5pF/_new  2026-06-13 18:49:37.983151621 +0200
@@ -1,5 +1,5 @@
 name: chirp
-version: 20260605
-mtime: 1780360931
-commit: f624f55513514636081bfdd5736f067e666628fd
+version: 20260612
+mtime: 1781131343
+commit: 6dadd6b206c59a0fd1093198a0405051c585dfbf
 

Reply via email to