In addition to Supercat's spot on technical description it might be helpful to look at requirements during ISA design:
Registers are Specialized
Z80 registers are specialized. Much like A, X and Y have different features on a 6502.
Inherited Basics
Most of this is inherited straight from the 8080:
- A - General purpose accumulator
- HL - Primary memory pointer
- DE - Secondary memory pointer (
XCHG
/EX HL,DE
)
- DE/BC - Ìndex pointer (
STAX
, LDAX
)
H, D and B are always the higher byte of any 16 bit value.
Faggin had to arrange any new features around this.
Finding a 16 bit Counter
Having a 16 bit counter for the repeated instructions will of course make them more versatile than only 8 bit. Doing so will require use of either one of the register pairs or the new IX/IY register. While it would have easy to use either, doing so would negating the advantage of the second register set for interrupt routines (*1), at least when they need to use any of the repeating instructions, like INIR
/INDR
, which are especially great during interrupts.
Of all 16 bit register pairs BC is the least versatile, so naturally the best to be used as counter for block operations.
Finding a 16 Bit I/O Register
Faggin put a great emphasis on improving the 8080 for embedded application (*2). Here the focus was faster, more versatile I/O and of course faster interrupts. Beside allowing to direct in-/output any 8 bit registers and fast block I/O, Faggin extended the I/O address space from 8 to 16 bit address size.
This could have been done by simply defining an IN and OUT instruction with immediate 16 bit address (*3). Then again, working with dynamic addresses would be a great plus for systems with several ports of the same kind, like multiple serial interfaces. So using a register pair it was. And like before BC was the optimal choice.
But Where to Put a Counter for Block IN/OUT
Those block instructions are a real great thing - even more for I/O where they can, supported by fast interrupt handling, save the need for a DMA controller. But this brings the need for a counter register. As before HL/DE are otherwise prioritised, so BC is again the only viable choice. Which conflicts with the use of BC as 16 bit counter. So what to do without screwing speed gained?
Since 8080 I/O was based on an 8 bit address space, a way out of this dilemma was to make the block I/O using only an 8 bit port address and use B as counter for up to 256 bytes to be transferred. Yes, this would mean that any system using block-I/O-instructions could not use the full 16 bit I/O address space. But I guess that was seen as a minor inconvenience - at least when keeping in mind that the main (and only) competition, Intel's 8080, had only 8 bit I/O address space anyway.
Isn't There One Opcode Left for a Relative Jump?
When looking at the new relative jumps (18h/29h/28h/30h/38h) shows one empty spot at 10h, where a jump never would be. Perfect for adding a simple loop mechanic: DJNZ. For this an 8 bit register is is not only enough, but the best choice. Most loops take less than 256 rounds - and if they have to, any overhead is minor, occurring only every 256 iterations (*4).
B ist predestined again. Not only as the sequence to decrement and test B is already needed for block-I/O, but it as well keeps C available for a variable I/O address. Essentially the DJNZ comes for free, as its mechanic is already part of all repeating I/O instructions.
Bottom Line: It's a compromise between various requirements while preferring flexible I/O
*1 - Speeding up an interrupt routine is the reason for the second register set to exist. By executing only two instructions (EX AF
/EXX
) the whole register set of any foreground process gets saved - that's why these also got two of the very rare single byte opcodes (80h/D9h).
*2 - After all, control applications, what we call nowadays 'Embedded', are what essentially all early micro processors were intended for. No matter if Motorola (6800), Intel (8080), MOS (6500) or Zilog (Z80), they all made their business not with PCs, not even with consoles, but control. Of the 5-10 billion 65xx cores, less then 20% ended up in such devices.
*3 - See below why usually only C is attributed as I/O address (in addition to 8080 compatibility).
*4 - Quite the same idea why the 6502 had only 8 bit wide index registers.
djnz
seem to be supported by 8080, so Z80 had to useB
for compatibility to 8080 because Z80 is intended to be compatible to 8080.