Description: Revert the bitarray 3 bump
Author: Keir Fraser <keir.xen@gmail.com>
Forwarded: not-needed

This reverts 6d806059ad7a9323435fdfef0d711bb2b38d2dd0.

diff --git c/setup.py i/setup.py
index 9013214..155b53a 100644
--- c/setup.py
+++ i/setup.py
@@ -18,7 +18,7 @@ setup(name = 'greaseweazle',
       version = version(),
       install_requires = [
           'crcmod',
-          'bitarray>=3',
+          'bitarray<3',
           'pyserial',
           'requests'
       ],
diff --git c/src/greaseweazle/codec/amiga/amigados.py i/src/greaseweazle/codec/amiga/amigados.py
index 7c8e3f9..69784dc 100644
--- c/src/greaseweazle/codec/amiga/amigados.py
+++ i/src/greaseweazle/codec/amiga/amigados.py
@@ -84,7 +84,7 @@ class AmigaDOS(codec.Codec):
                        clock = self.clock, data = track, pll = pll)
         bits, _ = raw.get_all_data()
 
-        for offs in bits.search(sync):
+        for offs in bits.itersearch(sync):
 
             if self.nr_missing() == 0:
                 break
diff --git c/src/greaseweazle/codec/apple2/apple2_gcr.py i/src/greaseweazle/codec/apple2/apple2_gcr.py
index e660e57..7c3913c 100644
--- c/src/greaseweazle/codec/apple2/apple2_gcr.py
+++ i/src/greaseweazle/codec/apple2/apple2_gcr.py
@@ -98,7 +98,7 @@ class Apple2GCR(codec.Codec):
                        lowpass_thresh = 2.5e-6)
         bits, _ = raw.get_all_data()
 
-        for offs in bits.search(addr_sync):
+        for offs in bits.itersearch(addr_sync):
 
             if self.nr_missing() == 0:
                 break
@@ -131,7 +131,7 @@ class Apple2GCR(codec.Codec):
 
             # Find data
             offs += 8*8
-            dat_offs = list(bits[offs:offs+100*8].search(data_sync))
+            dat_offs = bits[offs:offs+100*8].search(data_sync)
             if len(dat_offs) != 1:
                 continue
             offs += dat_offs[0]
diff --git c/src/greaseweazle/codec/commodore/c64_gcr.py i/src/greaseweazle/codec/commodore/c64_gcr.py
index d40a9ce..9402bb0 100644
--- c/src/greaseweazle/codec/commodore/c64_gcr.py
+++ i/src/greaseweazle/codec/commodore/c64_gcr.py
@@ -94,7 +94,7 @@ class C64GCR(codec.Codec):
                        lowpass_thresh = 2.5e-6)
         bits, _ = raw.get_all_data()
 
-        for offs in bits.search(sector_sync):
+        for offs in bits.itersearch(sector_sync):
 
             if self.nr_missing() == 0:
                 break
@@ -128,7 +128,7 @@ class C64GCR(codec.Codec):
 
             # Find data
             offs += 8*8
-            dat_offs = list(bits[offs:offs+100*8].search(data_sync))
+            dat_offs = bits[offs:offs+100*8].search(data_sync)
             if len(dat_offs) != 1:
                 continue
             offs += dat_offs[0]
diff --git c/src/greaseweazle/codec/hp/hp_mmfm.py i/src/greaseweazle/codec/hp/hp_mmfm.py
index 63fdc13..c875dde 100644
--- c/src/greaseweazle/codec/hp/hp_mmfm.py
+++ i/src/greaseweazle/codec/hp/hp_mmfm.py
@@ -136,7 +136,7 @@ class HPMMFM(codec.Codec):
                        clock = self.clock, data = track, pll = pll)
         bits, _ = raw.get_all_data()
 
-        for offs in bits.search(sector_sync):
+        for offs in bits.itersearch(sector_sync):
 
             if self.nr_missing() == 0:
                 break
@@ -160,7 +160,7 @@ class HPMMFM(codec.Codec):
 
             # Find data
             offs += 8*16
-            dat_offs = list(bits[offs:offs+50*16].search(data_sync))
+            dat_offs = bits[offs:offs+50*16].search(data_sync)
             if len(dat_offs) != 1:
                 continue
             offs += dat_offs[0] + 2*16
diff --git c/src/greaseweazle/codec/ibm/ibm.py i/src/greaseweazle/codec/ibm/ibm.py
index 2d8dab7..019e9f1 100644
--- c/src/greaseweazle/codec/ibm/ibm.py
+++ i/src/greaseweazle/codec/ibm/ibm.py
@@ -241,11 +241,11 @@ class DEC_MMFM:
         pre_bits.frombytes(pre)
         post_bits = bitarray(endian='big')
         post_bits.frombytes(mfm_encode(encode(pre)))
-        for x in pre_bits.search(self.encode_search):
+        for x in pre_bits.itersearch(self.encode_search):
             post_bits[x*2+1:x*2+12] = self.encode_replace
         return post_bits.tobytes()
     def decode(self, bits: bitarray) -> bytes:
-        for x in bits.search(self.decode_search):
+        for x in bits.itersearch(self.decode_search):
             if x&1 != 0: # Only matches starting on a data bit
                 bits[x:x+3] = self.decode_replace
         return decode(bits.tobytes())
@@ -448,14 +448,14 @@ class IBMTrack(codec.Codec):
 
         ## 1. Calculate offsets within dump
         
-        for offs in bits.search(mfm_iam_sync):
+        for offs in bits.itersearch(mfm_iam_sync):
             if len(bits) < offs+4*16:
                 continue
             mark = decode(bits[offs+3*16:offs+4*16].tobytes())[0]
             if mark == Mark.IAM:
                 areas.append(IAM(offs, offs+4*16))
 
-        for offs in bits.search(mfm_sync):
+        for offs in bits.itersearch(mfm_sync):
 
             if len(bits) < offs+4*16:
                 continue
@@ -515,18 +515,18 @@ class IBMTrack(codec.Codec):
 
         if mmfm_raw is not None:
             mmfm_bits, mmfm_times = mmfm_raw.get_all_data()
-            mmfm_iter = mmfm_bits.search(dec_mmfm.sync_prefix)
+            mmfm_iter = mmfm_bits.itersearch(dec_mmfm.sync_prefix)
             mmfm_offs = next(mmfm_iter, None)
             fm_time, prev_fm_offs = 0.0, 0
             mmfm_time, prev_mmfm_offs = 0.0, 0
 
         ## 1. Calculate offsets within dump
         
-        for offs in bits.search(fm_iam_sync):
+        for offs in bits.itersearch(fm_iam_sync):
             offs += 16
             areas.append(IAM(offs, offs+1*16))
 
-        for offs in bits.search(fm_sync_prefix):
+        for offs in bits.itersearch(fm_sync_prefix):
 
             # DEC MMFM track: Ensure this looks like an FM mark even at
             # double rate. This also finds the equivalent point in the
diff --git c/src/greaseweazle/codec/macintosh/mac_gcr.py i/src/greaseweazle/codec/macintosh/mac_gcr.py
index 51d09ee..f6448fe 100644
--- c/src/greaseweazle/codec/macintosh/mac_gcr.py
+++ i/src/greaseweazle/codec/macintosh/mac_gcr.py
@@ -101,7 +101,7 @@ class MacGCR(codec.Codec):
                        clock = self.clock, data = track, pll = pll)
         bits, _ = raw.get_all_data()
 
-        for offs in bits.search(sector_sync):
+        for offs in bits.itersearch(sector_sync):
 
             if self.nr_missing() == 0:
                 break
@@ -130,7 +130,7 @@ class MacGCR(codec.Codec):
 
             # Find data
             offs += 5*8
-            dat_offs = list(bits[offs:offs+100*8].search(data_sync))
+            dat_offs = bits[offs:offs+100*8].search(data_sync)
             if len(dat_offs) != 1:
                 continue
             offs += dat_offs[0]
diff --git c/src/greaseweazle/codec/northstar/northstar.py i/src/greaseweazle/codec/northstar/northstar.py
index 4cbcb37..28970fb 100644
--- c/src/greaseweazle/codec/northstar/northstar.py
+++ i/src/greaseweazle/codec/northstar/northstar.py
@@ -132,9 +132,9 @@ class NorthStar(codec.Codec):
 
                 s, e = hardsector_bits[sec_id], hardsector_bits[sec_id+1]
                 offs = bits[s:e].search(self.sync)
-                if (off := next(offs, None)) is None:
+                if len(offs) == 0:
                     continue
-                off += (1 + self.sync_bytes) * 16
+                off = offs[0] + (1 + self.sync_bytes) * 16
                 data = decode(bits[s+off:s+off+(self.bps+1)*16].tobytes())
                 if csum(data[:-1]) == data[-1]:
                     self.add(sec_id, data[:-1])
diff --git c/src/greaseweazle/image/caps.py i/src/greaseweazle/image/caps.py
index e1871c3..928e356 100644
--- c/src/greaseweazle/image/caps.py
+++ i/src/greaseweazle/image/caps.py
@@ -283,7 +283,7 @@ class IPFTrack(MasterTrack):
             raw_area = raw_bits[max(self.splice + s - self.tolerance, 0)
                                 : self.splice + s + l + self.tolerance]
             # All we care about is at least one match (this is a bit fuzzy)
-            if next(raw_area.search(sector), None) is None:
+            if next(raw_area.itersearch(sector), None) is None:
                 return False
         return True
 
diff --git c/src/greaseweazle/image/edsk.py i/src/greaseweazle/image/edsk.py
index c78d995..937006c 100644
--- c/src/greaseweazle/image/edsk.py
+++ i/src/greaseweazle/image/edsk.py
@@ -117,8 +117,8 @@ class EDSKTrack:
         track.verify = self
         return track
 
-    def _find_sync(self, bits: bitarray, sync, start) -> Optional[int]:
-        for offs in bits.search(sync):
+    def _find_sync(self, bits, sync, start) -> Optional[int]:
+        for offs in bits.itersearch(sync):
             if offs >= start:
                 return offs
         return None
diff --git c/src/greaseweazle/track.py i/src/greaseweazle/track.py
index cbe7fdd..330488c 100644
--- c/src/greaseweazle/track.py
+++ i/src/greaseweazle/track.py
@@ -59,20 +59,20 @@ class Precomp:
               scale: float) -> None:
         t = self.ns * scale
         if self.type == Precomp.MFM:
-            for i in bits.search(bitarray('10100', endian='big')):
+            for i in bits.itersearch(bitarray('10100', endian='big')):
                 bit_ticks[i+2] -= t
                 bit_ticks[i+3] += t
-            for i in bits.search(bitarray('00101', endian='big')):
+            for i in bits.itersearch(bitarray('00101', endian='big')):
                 bit_ticks[i+2] += t
                 bit_ticks[i+3] -= t
         # This is primarily for GCR and FM which permit adjacent 1s (and
         # have correspondingly slower bit times). However it may be useful
         # for illegal MFM sequences too, especially on Amiga (custom syncwords,
         # 4us-bitcell tracks). Normal MFM should not trigger these patterns.
-        for i in bits.search(bitarray('110', endian='big')):
+        for i in bits.itersearch(bitarray('110', endian='big')):
             bit_ticks[i+1] -= t
             bit_ticks[i+2] += t
-        for i in bits.search(bitarray('011', endian='big')):
+        for i in bits.itersearch(bitarray('011', endian='big')):
             bit_ticks[i+1] += t
             bit_ticks[i+2] -= t
 
