Modern approach: Write this in VHDL/Verilog for a CPLD or use an RP2040 with PIO state machines.
In a normal microcomputer (like the Apple II), these tasks are split across separate chips. In the Spectrum, the ULA ate them all:
Think of a ULA as a breadboard of unconnected NAND and NOR gates. You, the designer, pay for a metal mask that connects these gates into whatever logic function you need. It is a semi-custom ASIC. For a low-volume product (relative to Commodore), it was perfect.