(2017.03.03) I have added a second answer with diagrams and more technical details. This answer is already huge and self-contained; the other focuses on the complexities due to hardware.
Why does the C128 perform poorly when running CP/M?
- The Z80A was sort of an after-thought in the C128 design. Before release it had been touted as "fully C64 compatible" (which the earlier C= Plus/4 was not). However, the C64 had a Z80 cartridge allowing it to run CP/M. For whatever reason the cartridge could not work on the C128, so they added the Z80 directly to the motherboard. At that point, they were already 2 months into their 5-month development cycle. (see reference #3 below)
- I/O was doubly indirect. Actions such as reading from the keyboard and writing to the screen first went thru the CP/M BIOS layer. Then it had to switch CPUs! From the Commodore 128 Programmer's Reference Guide (PRG), page 500:
The 8502 is responsible for most of the low-level I/O functions. The request for these functions is made through a set of mailboxes. Once the mailboxes are set up, the Z80 shuts down and the 8502 starts up (BIOS85). The 8502 looks at the command in the mailbox and performs the required task, sets the command status and shuts down. The Z80 is re-enabled; it then looks at the command status and takes the appropriate actions. 3. Updates to the screen were s-l-o-w. I believe this was due to the impact #2 had on interacting with the 8563 video controller. Although a block mode character transfer was possible, apparently the complexity of the dual-BIOS layers led to only one character being written to the screen per BIOS call. To write a character, two 8563 registers needed to be updated, which were the hardware pipeline to the 80-column video memory. That all amounts to a heckuva lot of overhead per character. 4. Some users only had the classic C64 model 1541 disk drive. This was already known for being very slow (to be fair, "faster than cassette"). The newer 1571 drive, released with the C128, was three to six times faster, had double the capacity, and supported several CP/M formats used by other manufacturers.
Some of these issues were clearly not due to hardware limitations, but stemmed from a lack of optimization for the drivers used in CP/M. The engineers were on a tight schedule and implementing something that wasn't even part of the original C128 design. They would have had to rewrite the 8502 BIOS code in Z80 assembly language, but they were primarily hardware guys. I'm sure Commodore didn't want to spend extra money to optimize a feature they hadn't even asked for. So the simplest, most reliable route was to make calls to the already working and well-tested 8502 BIOS.
A 1999 update to C128 CP/M, by Linards Ticmanis, addresses some of the CP/M driver performance limitations of the original and purports to improve 80-column screen updates by 75%.
(speculation added 2017.03.01)
After fully reading reference #2, my understanding of the development bottleneck for the CP/M BIOS was clarified. The C128 team did have an excellent CP/M expert working off-site. It was never his goal to have the CP/M BIOS call the 8502 BIOS. Unfortunately the Commodore MOS group (the chip developers) had long-standing major problems delivering a working, stable, and reliable 8563 80-column video controller. This chip had been part of a Z8000 (16-bit version of Z80) Unix computer, the "C900", Commodore had once worked on, and apparently the chip had never been completed even for that use. Thus the 8563's fundamental design was based on an entirely different bus structure than the C128 offered.
The 8563 samples the C128 team received would tend to burn themselves up, arrive with documented deficiencies, and, in general, be altogether unreliable throughout most of the development process. The CP/M guy could not use current hardware. He had a board with an older 8563 revision that wouldn't burn itself up and mostly worked. (He had to keep it cool with an ice cube sat in a tray above it, though.) But ongoing changes to the chip must have kept invalidating his BIOS. My guess is at the last minute he was told something like, "Look, we'll eventually get the I/O working in house with the 8502 BIOS. You just make calls to that, and we'll make sure on our end that it eventually works right."
Z80A only runs at 4MHz half the time. Why should this be the case?
From page 575 of the PRG:
SYSTEM DESCRIPTION
The Z80A, a 4MHz version of Zilog's standard Z80 processor, is included as an alternate processor in the C128 system. This allows the C128 to run the CPM 3.0 operating system at an effective speed of 2 MHz. The Z80 is interfaced to the 8502 bus interface and can access all the devices that the Z80 can access. The bus interface for the Z80 (the most complex part of the Z80 implementation) is described in this section, along with Z80's operation as a coprocessor in the C128 system.
BUS INTERFACE
Because a Z80 bus cycle is much different than a 65xx family bus cycle, a certain amount of interfacing is required for a Z80 to control a 65xx-type bus. Since the Z80 has built-in bus arbitration control lines, it is possible to isolate the Z80 by tri-stating its address lines. Thus, both the Z80 and the 8502 share common address lines.
The interfacing of the data lines is more complex. Because of the shared nature of the bus during Z80 mode, the Z80 must be isolated from the bus during AEC low. Thus, a tri-statable buffer must drive the processor bus during Z80 data writes. The reverse situation occurs during a Z80 read—the Z80 must not read things that are going on during AEC low; it must latch the data that was present during AEC high. Thus, a transparent latch drives the data input to the Z80. It is gated by the Z80 read-enable output, and latched when the 1 MHz clock is low. It will be seen that the Z80 actually runs during AEC low, but that the data bus interfaces with it only during AEC high.
The AEC is a signal pin of the C128's memory management unit. It is defined on pages 584 and 585 of the PRG:
AEC: Address Enable Control. Indicates whether the 8502 processor or the VIC has access to the shared bus. When low, VIC or an external DMA has the bus and VA16 have the processor bus, and no pointer or BIOS translation takes place. This signal occupies pin 16.
To put it bluntly, "It's complicated." The Z80A slowdown may be thought of as something like "wait states". Wait states are to allow a CPU running faster than memory to still operate, especially in an era before on-chip CPU caches alleviated the need for the CPU to access memory every (other) cycle. The problem on the C128 is that a 8502 CPU expects different things from its bus than a Z80 does. In the modern era, you can think of different motherboards being needed for different (yet current) '86 family CPUs. They can't just run the motherboards at slower and faster speeds and expect everything to work. Bil Herd and his team had to work with one motherboard and two entirely different CPUs.
Performance benchmarks?
I was not able to find actual benchmarks. There were several accounts of users lamenting the C128's CP/M speed, and especially its screen updating. IMO the perception of this mode being slow was much more to do with the I/O bottleneck than the effective 2 MHz clock rate of the Z80A. There had been lots of actual 2 MHz CP/M machines using the original Z80; there were few complaints about their speed. But imagine using a CP/M spreadsheet and actually observing o n e c h a r a c t e r a t a t i m e being written to the screen. It'd be kind of annoying.
Cool References
- THE REAL STORY OF HACKING TOGETHER THE C128 by Bil Herd, lead designer
- The C128 Story, aggregated CompuServe postings by Bil Herd
- HEY EVERYONE! IT'S BIL HERD!!! :) 1998 usenet post to comp.sys.cbm
Bil describes why, how, and problems in adding a Z80 to the C128 - CP/M-cartridge for the C64, a README by Ruud Baltissen
detailed explanation of interfacing a Z80 to a 6502 bus - Platform Wiki: Commodore 128, backstory, design, and marketing for the C128
- CPM Z80 Cartridge for the Commodore VIC-40, (from early 1980s)
timing and other diagrams for interfacing a Z80 to a planned successor to the VIC-20