TL;DR: the AnyTone AT-778UV (aka Retevis RT95, CRT Micron UV, Midland DBR2500, Yedro YC-M04VUS) has no CAT port, but there's an undocumented command set in its firmware that lets you tune it live from software over an ordinary programming cable. Writeup, firmware notes and a Python library below.
CHIRP talks to it over a serial interface in the mic port with five commands, all for reading and writing the codeplug.
I wanted to know whether the radio could be driven live over that same port, so I pulled the LCD-processor firmware off the vendor's own download page and read it (finding that was a mission in itself...)
I found that the command dispatcher in the LCD firmware has twenty-two arms, not five. One of them, the "D" command, sets a live parameter during normal operation: frequency, offset, bandwidth, both tones, squelch, volume or power, in one short frame. And the radio acknowledges these in about 130 ms. It needs no programming mode and does not reboot the radio, and the display does not even change. Your bog standard programming cable (the one CHIRP already uses) is all you need.
So you can tune this radio from a PC or a Pi over its mic bus. Here is the frame that sets the frequency:
44 00 44 60 06 25 06 -> 06 tune to 446.00625 MHz
There is a real race condition that I can't resolve. In memory mode that same command overwrites the stored memory channel instead of the VFO, silently, and there is no way on this bus to lock the mode or address the VFO directly. I've implemented a guard that shrinks the window but cannot close it. That's (one of the reasons) why I have not shipped a clean Hamlib backend. Something that can corrupt an operator's memories under a race is not what I would want to give to, say, WSJT-X. It is buildable if you agree to keep hands off the front panel while software is driving the radio, and I may turn my attention back to it in the future.
PTT and the S-meter are not on this bus either. PTT stays on the discrete pin, and the RF processor never forwards signal strength to the mic side.
I wrote the whole thing up in github so you can see how it was found in the firmware, the frame formats, the full command map (including eleven more commands locked behind a factory-mode gate I've yet to fully explore), and a Python library to make use of what's now known about this command structure.
I enlisted Claude to help put together a web console to sit on top of this library, to give a sense of what can be done (the console UI is Claude's work and came out nicer than my scrappy notes deserved).
My code, notes and writeups (and dead ends) are all here: https://github.com/muurk/at778uv-rt95-mic-bus
One question for anyone here who runs one of these radios: would live software control actually be useful to you? I can see it being handy for satellite Doppler tracking or a headless setup, but I'd rather hear whether that matches how you'd actually use the radio.