return.gif返回博客索引

简介

0.jpg

截至撰写本文时,Zilog Z80 处理器于 50 年前正式发布,即 1976 年 7 月,距离人类最后一次踏上月球不到 4 年,比现在更接近二战几十年,大致位于肯尼迪遇刺和柏林墙倒塌之间的中点,比朝鲜战争更接近 9/11,而 9/11 本身已是四分之一个世纪前的事件。(抱歉……)

该处理器极为成功,被用于许多 8 位微型计算机,包括早期的个人计算机、家用和业余爱好计算机,以及许多嵌入式和工业应用。

与它二进制兼容的 8080 和 8085 一起,它促成了 8 位微型计算机的事实上的硬件标准,进而形成了 CP/M 和 Microsoft BASIC 的事实上的软件标准。

Z80 本身在随后几年还衍生出许多克隆和派生架构,其中最著名的包括用于原版 GameBoy 的 Sharp LR35902。Zilog 最终放弃了其 16 位和 32 位派生架构系列,转而回归基于 Z80 的微控制器和变体,例如流水线化且更高时钟频率的 eZ80,主要用于工业应用的持续使用。

我本人太年轻,没有亲历家用计算机时代(忽略前面提到的 GameBoy),但其在工业应用中的广泛使用意味着原版 Z80 仍在使用,直到 Zilog 仅在 2 年前才最终停产。

我第一次接触 Z80 是在青少年晚期,当时我在浏览一家电子公司的产品目录,惊讶地发现它们仍在销售。我设计了自己的小型 Z80 计算机,并说服一位学校老师让我在晚上使用摄影实验室,以便蚀刻一些 PCB。

1.jpg

由于几位以前的老师对我在做什么产生了好奇,我最终听到了许多关于老式家用计算机、游戏机以及在一个 Tupperware 盒子里用 DIY 线绕计算机运行 CP/M 和 WordStar,并连接到一台“借来的”IBM 终端用于撰写论文的有趣轶事。随着时间的推移,我最终收到了许多来自尘封抽屉的旧芯片作为礼物,这些芯片最终进入了我自己的 DIY 项目,包括一批 MCS-85 部件、若干 Z80、8085、6502 和 6522。

这整个过程确实让我学到了许多关于系统工程的有趣经验,以及一些意想不到的经验(可靠的上电复位出奇地难;编写链接器比编写汇编器难得多,编写编译器是你真正可以做到的事)。

无论如何,这就是我有资格缅怀 Z80 的理由。虽然我原本只想根据自己的经验限制在一些技术细节上,将 Z80 与它所源自的 8080 进行比较,但我最终深入研究了计算机历史博物馆的口述历史小组讨论,其中参与者回忆了更多关于这些芯片开发轶事。“我将尝试写一篇博客文章(再次)”的想法很快膨胀了范围。

从 2200 到 8008

很久以前, 计算机终端公司(CTC) 制造了一款新的可编程终端, Datapoint 2200,配备了一个由单个 TTL 芯片构建的 8 位处理器。当时英特尔正在向 CTC 供应移位寄存器和存储芯片。

有人提出用定制 IC 替换部分 TTL 逻辑,最终考虑尝试将整个 8 位 CPU 集成到单个芯片上。最终有两家公司被委托完成这项任务:德州仪器和英特尔。

两家公司都没有按时完成设计。当英特尔准备好芯片时,最初根据系统命名惯例命名为 1201,CTC 已经在销售基于 TTL 设计的终端。

CTC 的工程师也对芯片的性能不满意,而且他们已经为下一代终端对架构进行了修改。

虽然 TI 最终放弃了他们的设计,但英特尔继续推进,并成功地将他们的版本商业化,命名为 8008(与 4004 一样,由市场营销部门重新命名)。

8008 架构

        ___   ___
-9V ---|1  |_| 18|- IRQ
AD7 ->|2      17|- READY
AD6 ->|3      16|- CLK1
AD5 ->|4      15|- CLK2
AD4 ->|5      14|-> SYNC __
AD3 ->|6      13|-> S0     |
AD2 ->|7      12|-> S1      > State
AD1 ->|8      11|-> S2   __|
AD0 ->|9      10|-- +5V
       |_________|
         
A
B
C
D
E
H L
PC
C P Z S

8008 有 7 个寄存器:ABCDEHL。其中 A 是指定的累加器,其他寄存器可用作操作数或暂存器。正如名称所暗示的,HL 一起构成内存指针的部分。内存访问通过第 8 个伪寄存器 M 完成,代表 HL 指向的内存字节。

处理器内部在几个标志位中跟踪 ALU 状态 (Carry、Parity、Zero、Sign),在其上可以执行条件跳转(包括调用和返回)。

程序计数器 PC 几乎从不直接可见。有专门的函数调用和返回指令,但处理器使用一个内部返回地址堆栈,深度为 8 级。这样做的原因是 Datapoint 2200 最初计划使用串行内存,内存中的调用堆栈被认为会成为性能瓶颈。

内存地址为 14 位宽,有一个单独的 I/O 地址空间,总共 32 个 I/O 端口(地址始终是立即数并按位填充到操作码中)。

对于中断处理,有一个特殊的“重启”指令,实际上调用地址空间开头的 8 个槽位之一(0x00、0x08、0x10、0x18、...、0x38)。槽位索引按位填充到 RST 操作码中。当中断发生时,处理器向外围设备发出信号表示已收到提示,然后盲目执行数据总线的当前内容,该内容最好是一条 RST 指令。

从这里开始,事情变得有点棘手。CPU 没有通用的堆栈可以保存寄存器,所有内存访问都需要 HL,但你不想在中断处理程序中破坏 HL。解决此问题的预期方式是通过 I/O 总线上的外部锁存器,作为暂存寄存器。

总之,该架构相当简单,需要大约 3500 个晶体管,并使用 DIP18 封装。地址和数据被多路复用,需要外部锁存。内部解码/执行状态被暴露,需要解码以驱动锁存器并确定处理器正在尝试做什么(从内存或 I/O 总线读取或写入)。

处理器需要两个相移时钟信号(运行频率为 500kHz),一个 +5V 正电源和一个 -9V 负电源。

从 8008 到 8080

Datapoint 2200 衍生而来的 8008 架构的缺点在开发过程中已为人所知,按照典型的工程方式,在开发结束之前,就已经有人提出改进架构的想法。

Federico Faggin, 从 4004 项目调来的工程师,推动启动改进版本的工作,但管理层坚持要先看看市场对他们两款微处理器的反应。竞争对手最终宣布他们正在开发自己的 8 位设计,延误最终使英特尔失去了总共 9 个月的领先时间。

甚至在项目最终获批之前,Federico Faggin 就获得批准从 Busicom 聘请 Masatoshi Shima 离开英特尔,参与 8080 设计。在许多方面类似于 CTC 对 8008 开发的参与,Busicom 参与了 4004 的开发,最初希望为其计算器定制一组芯片。

向其演示 8008 的潜在客户的批评和反馈也影响了 8080 的设计,并很早就决定放弃二进制兼容性。

8080 架构

A F
B C
D E
H L
SP
PC

8080 本质上与 8008 具有相同的寄存器集,但它用位于内存中的外部堆栈替换了内部返回地址堆栈,并通过堆栈指针寄存器(SP)访问。

堆栈指针可以在 HL 之间交换或移入/移出,寄存器可以成对压入或弹出堆栈。除了 HL,其他寄存器对还有 BCDEAF(累加器和 ALU 标志),但 8080 汇编更倾向于将后者称为“程序状态字”PSW

内存地址增加到完整的 16 位,为机器提供 64k 地址空间。I/O 端口增加到 256。BCDE 现在也允许基本的间接寻址(加载/存储累加器),累加器和 HL 可以加载/存储到立即数目标。

添加了一些双字节算术运算,可以在寄存器对上工作(例如增量/减量),主要用于允许指针算术和 16 位计数器。在 AF 上使用这些指令实际上会作用于 SP

中断处理的工作方式大致相同,使用重启指令,但增加了可以在软件中启用/禁用中断的功能。显式堆栈也不再需要使用 I/O 硬件保存寄存器。

以下是来自维基百科页面的略微修改的内存复制示例,它将 DE 中的若干字节(存储在 BC 中)复制到 HL。

memcpy:
    PUSH    B           ; pushes BC
    PUSH    D           ; pushes DE
    PUSH    H           ; pushes HL

loop:
    LDAX    D           ; A := *(DE)
    MOV     M, A        ; *(HL) := A
    INX     D           ; ++DE
    INX     H           ; ++HL
    DCX     B           ; --BC

    MOV     A, B        ; A := B
    ORA     C           ; A |= C
    JNZ     loop        ; jump if not zero

    POP     H
    POP     B
    POP     D
    RET
    

这里值得注意的几点:作用于寄存器对的指令总是使用单个寄存器作为两个的助记符,“X”在“INX”中区分双字节增量与单个寄存器字节的“INC”。Intel 8080 汇编的助记符与操作码几乎是一对一映射,并且非常容易解析,使得汇编器易于实现。在某种程度上,这以牺牲人类可读性为代价。

此外,双字节算术对 ALU 标志没有影响,它是一个独立的、独立的功能块。在 递减 BC 后,我们需要手动检查两个寄存器是否都为零。

电气接口

为了提高速度,8080 使用了 NMOS 逻辑。这样做的缺点是 CPU 现在需要 3 种不同的电源电压(-5V、+5V 和 +12V)。它还继续使用 2 个相移时钟信号(在 9V 到 12V 范围内),使得围绕芯片的电气设计有些 cumbersome。

多亏了 40 引脚封装(Faggin 回忆说这是一场艰苦的批准战斗),CPU 不再需要多路复用数据和地址线。但与 8008 一样,它仍将内部处理器状态暴露在外部,将实际控制状态多路复用到数据总线上,需要外部锁存和解码。

英特尔当然会销售用于状态解码、时钟生成等的支持芯片。此外,你可能还想购买配套的中断控制器和可编程间隔定时器,至少用于驱动 DRAM 刷新,可能使用其中一个方便的英特尔 DMA 控制器。

英特尔通过 8085 解决了至少一些这些缺点,只需要单一 5V 电源和单一 5V 时钟信号。释放的引脚暴露了一些额外的控制信号。但仍然需要一些专用支持芯片。

Zilog 和 Z80

对在英特尔的经历感到不满,包括延误以及为获得 8080 项目批准而与管理层进行的艰苦斗争,Federico Faggin 最终决定离开英特尔,与当时微处理器部门负责人 Ralph Ungermann 一起创办自己的公司。

最初有些方向不明,Faggin 最初考虑设计微控制器,但意识到对于一家无晶圆厂半导体初创公司来说,利润率太低,无法实现经济效益。

他最终决定设计 8080 的改进版本,绰号“Super 80”,后来成为 Zilog Z80。他们从埃克森美孚获得资金,并从英特尔带走了 Masatoshi Shima 参与设计,后来将团队规模扩大到总共 11 人,负责布局、软件仿真等工作。

Z80 的设计旨在与 8080 二进制兼容,同时添加寄存器、寻址模式、新指令,借鉴其他同时代产品如 6800 的灵感。它还旨在实现更简单的电气接口和比 8080 更高的速度。

处理器从开发到第一个工作原型,整个开发成本约为 40 万美元,按时完成且低于预算(他们从埃克森美孚获得了 50 万美元)。

Zilog 依靠 Mostek 制造他们的处理器(在与最初签约的 Synertek 发生一些敌对事件后)。他们最终从埃克森美孚获得进一步资金建造自己的晶圆厂,但继续二次采购 Z80。

Z80 架构

A F A' F'
B C B' C'
D E D' E'
H L H' L'
IX
IY
SP
PC

Z80 与 8080 指令集完全二进制兼容。

受 6800 启发,它添加了两个索引寄存器 IXIY,可以用作 HL 的替代(相同的编码但带有操作码前缀)并带有立即数偏移。

AFBCDEHL 寄存器对是组切换的,允许更简单、更快的中断处理。

说到中断,Z80 有 3 种不同的处理方式:8080 兼容方式(模式 0)、始终调用到固定位置的方式(模式 1),以及通过调用表分派的方式(模式 2),使用总线上的数字作为索引。使用一个额外的寄存器来定位内存中的表基址。

Z80 还添加了一堆位旋转、位测试和设置指令、BCD 算术,以及内置循环指令(使用 BC 作为计数器)、自重复块传输、块比较和字符串操作。

因为英特尔声称对汇编助记符拥有版权,Z80 最终使用了自己的汇编语言,具有可以说更清晰的语法。Z80 汇编更明确地表达操作数,并使用基本助记符的重载变体。

这与上面的程序本质上相同,但使用更具表达力的 Z80 汇编:

memcpy:
    PUSH    BC             ; full name of the register pair
    PUSH    DE
    PUSH    HL

loop:
    LD      A, (DE)        ; explicit 2 argument syntax
    LD      (HL), A
    INC     DE
    INC     HL
    DEC     BC

    LD      A, B            ; overloaded name
    OR      C
    JP      NZ, loop        ; overloaded name, condition is an argument

    POP     HL
    POP     BC
    POP     DE
    RET
    

当然,在 Z80 上,整个字节复制循环也可以用一条单一的自重复指令替换:LDIR

改进的总线设计

Z80 只需单一 5V 电源和单一时钟信号。8080 的许多外部锁存/解码状态都被芯片明确暴露,例如 MREQIORQ 表示内存或 I/O 访问,RD/WR 信号明确表示名称所暗示的内容,以及 M1 信号表示当前内存访问是取指令。这些信号可以连接到像单个 74xx138 这样简单的东西来驱动 (E)EPROM、某种形式的 RAM 和 UART 控制器。将地址和数据线直接连接到 Z80,你基本上就拥有了一台可工作的计算机!

如果使用的 RAM 恰好是 DRAM,Z80 还可以处理 DRAM 刷新,使用内部刷新计数器,在指令解码周期将其置于地址总线上,断言控制线以告知外部解码逻辑进行 DRAM 刷新。

使用中断模式 1,CPU 始终调用到硬连线位置,简单设计无需任何外部中断控制器,将单个设备连接到中断引脚,或使用像 74xx148(优先级编码器)这样简单的东西和一个锁存器。

故事的后续

甚至在 Z80 于 1976 年 7 月最终发布之前,16 位 Z8000 架构的粗略设计工作就已经开始。Z8000 于 1979 年发布,晚于 Intel 8086,但早于 Motorola 68000。

与 8086 一样,它使用分段内存,但与 8086 不同的是,它在总线上暴露段号,外部 MMU 芯片应将其转换为线性地址(并检查边界和权限)。

虽然 8080 的共同遗产在 8086 指令集中清晰可见,但 Z80 的许多特性也被继承,例如自重复块和字符串操作或循环指令。Z8000 MMU 的设计也影响了 286 的 16 位保护模式基于描述符表的设计。

尽管 Zilog 最初将产品定位于计算机导向的市场,当时微处理器被视为逻辑替代品,但他们与埃克森美孚的联系最终成为 IBM 最终决定不选择 Zilog 处理器用于其 PC 的原因之一,而是选择了 Intel 8088。

埃克森美孚对 Zilog 感兴趣的部分原因是他们打算建立自己的计算帝国,与 IBM 竞争。他们战略投资了其他一些公司(例如打字机、文字处理器或打印机制造商),其中一些甚至围绕 Zilog 部件设计产品,都在蚕食 IBM 竞争产品的市场份额。

与埃克森美孚的密切联系最终也在 Faggin 和 Ungermann 之间造成了摩擦,后者在 1980 年成为埃克森美孚全资子公司之前离开了 Zilog。

Zilog 最终于 1989 年从埃克森美孚分拆出来,并于 1991 年上市,随后多次易手,在私募股权和实际电子公司之间来回跳动,目前由 Littelfuse 拥有。

Z80 作为嵌入式处理器经历了漫长的生命周期,最终于 2024 年 6 月停产。

链接和参考