Chuck Guzis wrote:
Other than the relative jumps, the enhanced
instruction set of the Z80
rarely brought much speed increase by itself. For example, moving a block
Many of the Z80 opcodes are slower than 8085. Even the JP's and
JR's have to be used carefully if you're penny-pinching T-states.
of bytes using LDIR isn't really much faster than
using a MOV A,M/STAX D
type of loop. On the other hand, the INI and OTI instructions was very
welcome when one had to deal with a peripheral whose I/O port addresses
weren't known in advance. The alternative on the 8080/8085 was
hot-patching code--an impossiblity if one was executing out of ROM--one had
to copy the applicable code into RAM and execute it there. Not a great
feature if the I/O ports in question controlled the bank-switching hardware
and you were trying to do a RAM diagnostic.
I've wondered about something for years, however. Did anyone ever make use
of the fact that an INI or OTI instruction placed the contents of both the
B and C registers on the Z80 address bus? It would seem to be a simple way
of expanding the I/O space to 64K ports.
Yes. If you search comp.arch.embedded you'll see I've had
arguments about this with "unbelievers" in the past :>
Some CPUs actually *rely* on this. E.g, the 64180 family
('180, '7180, NPU?, etc.) locate certain IO registers in
"page 0". To access them, you must either set B to 0 beforehand
*or* use the special "OUT0" opcode, etc.
Having B appear on the address bus is a nice way of combining
an IN and OUT instruction into a single operation. I often
exploit this when decoding key matrixes, etc. (i.e. set
B to whatever you want to appear on the row drivers, C to
the IO address for the "keyboard" and do an IN A,C)