11.2 端口译码、查询与状态
第 11.1 节已经把端口地址与端口中传送的数据区分开来。现在,硬件必须把地址转换成唯一的片选(chip select)信号;软件也必须避免在设备准备好数据之前就读取它。
译码周期类型、寄存器编号和地址位
端口译码器应检查三类信息:
- 当前总线周期是否为方向正确的 I/O 周期。
- 高位地址是否与接口分配到的基地址匹配。
- 低位地址选择接口内部的哪个寄存器。
假设一个接口占用 0300H–0303H。A15…A2 标识这个四端口窗口,A1…A0 则选择数据、状态、命令或配置寄存器。读取 0301H 时,只应选择状态寄存器。在独立编址设计中,读取物理存储器地址 00301H 不能误选该接口。
正在绘制图表…
如果设计者忽略了本应检查的高位,同一组物理寄存器就会出现在多个别名地址(alias address)上。不完全译码可能减少硬件,但会让系统地图变得含糊,也可能与以后加入的设备冲突。当地址空间并不紧张时,完全译码是更稳妥的默认选择。
正在加载交互实验...
正在加载概念检查...
正在加载本节练习...
查询状态位,同时保留其他信息
速度较慢的设备通常提供状态寄存器(status register)。其中每一位报告一种条件,例如就绪、忙、错误或有数据可读。查询(polling)是反复读取状态寄存器,直到目标位达到所需状态。
若第 3 位是 READY,软件可以用掩码(mask)把它单独取出:
asm
wait_ready:
IN AL, DX
TEST AL, 08H
JZ wait_ready08H 只有第 3 位为 1。TEST 像 AND 一样计算标志,但不修改 AL。第 3 位变为 1 时,循环结束。若直接要求整个字节等于 08H,程序就很脆弱:即使 READY 有效,另一个错误位或模式位也可能同时为 1。
正在绘制图表…
查询方法简单,却会消耗总线周期和 CPU 时间。循环越紧,越能迅速发现就绪,但无效读取也越多;在两次读取之间增加等待可以减少总线流量,却会提高响应延迟。后续章节会介绍中断和直接存储器访问,用于等待成本无法接受的场景。
正在加载交互实验...
正在加载概念检查...
正在加载本节练习...
查询能够可靠工作,前提是设备会保持就绪状态,直到软件发现它。第 11.3 节将加入明确的请求与应答信号,处理双方不能假定彼此时序的传送。