import struct, sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') DUMP = r"C:/Users/vikto/Documents/Claude/rt-4d/radio-spi-dump.bin" data = open(DUMP, "rb").read() CT_BASE = 0x05C000; ZN_BASE=0x01C000 def hx(b): return " ".join(f"{x:02X}" for x in b) def parse_bcd(bcd): if all(b==0xFF for b in bcd): return 0 r=0 for bv in reversed(bcd): hi=(bv>>4)&0xF; lo=bv&0xF if hi==0xF: hi=0 if lo==0xF: lo=0 r=r*100+hi*10+lo return r # Scan contacts region for any non-FF records print("CONTACTS scan (non-0xFF b0):") cnt=0 for i in range(2048): off = CT_BASE + i*32 d = data[off:off+32] if all(b==0xFF for b in d): continue name = bytes(b for b in d[0x10:0x20] if b!=0xFF).decode('gbk','ignore').strip() dmr = parse_bcd(d[0x02:0x06]) print(f"ct{i} @0x{off:06X} b0={d[0]:02X} type(b1)={d[1]} dmr(BCD@2)={dmr} name={name!r}") print(" raw:", hx(d)) cnt+=1 if cnt>=8: break print("total non-FF contact records:", sum(1 for i in range(2048) if not all(b==0xFF for b in data[CT_BASE+i*32:CT_BASE+i*32+32]))) print("\nZONES:") for i in range(256): off=ZN_BASE+i*512 d=data[off:off+512] if d[0]==0xFF: continue name=bytes(b for b in d[0x04:0x14] if b!=0xFF).decode('gbk','ignore') count=d[0]|(d[1]<<8) print(f"zone{i} @0x{off:06X} count={count} curA={d[2]} curB={d[3]} name={name!r}") print(" head:", hx(d[0:0x14])) chans=[d[0x14+k*2]|(d[0x15+k*2]<<8) for k in range(min(count,30))] print(" chans:", chans) print(" scan@0x1A4:", hx(d[0x1A4:0x1A4+25])) # dump any nonzero bytes between end of chan list and scan print(" 0x194-0x1A4:", hx(d[0x194:0x1A4]))