There’s probably another CPU meeting your criteria which beats this, but as a data-point, a number of x86 CPUs fit the bill. One is the 80C188 (introduced in 1987) which was available at frequencies up to 25MHz, and the compatible Am188ER CPU was available at frequencies up to 50MHz. These have an 8-bit data bus, but a 16-bit ALU. Another is the 80486, introduced just before your cut-off; see below. Like all x86 CPUs these support the following minimal 16-to-32-bit multiplication:
BX, unsigned, and stores the result in
AX. If you want to read the operands from memory and write them back:
MOV AX, [op1]
MOV BX, [op2]
MOV [resh], DX
MOV [resl], AX
op2 point to the operands,
resh points to the high word of the result, and
resl to the low word.
The timings are as follows (
MOV is slightly slower on the Am188ER):
MUL r16: 35–37 cycles
MOV: 12 cycles on the 80188, 13 on the Am188ER for a 16-bit transfer between a register and memory (in either direction)
resulting in a total of at most 89 cycles, i.e. 1.8µs at 50Mhz.
A complete multiply-accumulate would look like this, courtesy of supercat, multiplying ranges of words starting at
BX+SI+2 respectively, over
lp: IMUL [BX+SI]
ADD DI, AX
ADC BP, DX
The result is accumulated in
BP (high word) and
DI (low word).
This takes advantage of prefetching to shave cycles off the overall execution time. The reference 80188 timings are 18 cycles per
LODSW, 3 per addition, 34–37 per
IMUL, 15 per loop taken (including instruction queue reinitialisation and target instruction prefetch). The effective address calculations would add a lot more cycles on an 8086/8088 but are handled by a dedicated hardware unit on the 80188, with no additional (visible) cost.
Raffzahn pointed out that the 80486 can also run with an 8-bit data bus; while it has a 32-bit data bus natively, if BS8 and BS16 are pulled low, it will split up data transfers into 8-bit units. The 486 greatly reduces the base number of cycles required for all the instructions above: 1 cycle per register-to-memory
MOV, 13–26 cycles per 16-bit register-based multiplication, 1 cycle per register-based addition, 5 cycles per
LODSW, 7 per loop taken. I imagine the transfer splits add a number of additional cycles, although those might be hidden by the cache. The 486’s clock maxed out at 50MHz externally (in 1989), but the CPU was clock-doubled and then tripled during the 90s, up to 100MHz in Intel variants and 160MHz in AMD variants.