视频:
如果本次课程对应的 Coursera 的视频打不开,可以点击下面链接
P1W4U4.5 - Input/Output
软件:
全课程所需软件项目包官方下载:
https://www.nand2tetris.org/software
备了一份软件项目包放在CSDN了,版本2.6支持Mac、Linux、Windows:
https://download.csdn.net/download/shazizm/11268147
回顾:之前的课程详细说明了下图绿色部分。
外设:Hack小电脑还有两个外部设备。
一个显示器 (Output 输出设备,显示数据给用户)
一个键盘(Input 输入设备,获取用户数据)
外设还可以有很多,不过本课程的Hack就用这两个。
如果写过高级语言,例如 java 或者 python,它们都会提供很多库,来供用户操作控制各种外设。(这一部分,事实是我们要在 Part2 的课程里讲解)
但是我们现在基本就是在计算机的最底层,我们只有“位”来用。。。
(这一部分,就是Part1 现在要讲解的。)
那么如何来操作呢,先说显示器吧。
显示器
其实就是有 一行行和一列列的像素组成的。
于是可以在RAM里面,指定一个区域的存储(例如 下图中 Screen Memory map 黄色部分),让每一个此区域的一个位,都对应一个显示器的像素。
然后在每秒內,显示器都会去读取好几次这一区域的每“位”的值(例如1 是黑,0是白)
然后让显示器的像素对应显示。
那么是如何具体映射的呢。
假设 Hack小电脑 有一个 256 行,512列 的黑白显示器。如下图右上角。
那么就用RAM里一段8K的存储区域来映射。
为什么是 8K呢? 8k = 8192 个寄存器
8192 x 16 位 = 131072个“位”。
显示器是 256行 x 512列 = 131072个像素。
完美对应。
另外可以看出每32 个寄存器(32x16=512个“位”),就对应 显示器的一行(512个像素)
那么我们如何选取指定位置的像素用来读或写呢?
注意:因为寄存器是16位的,每次读或写,都是16位一起操作的。所以第一步是找到需要修改的 像素 对应 8k(8192)中的 第几个寄存器。
例如要修改 第row行,的第col列的像素。
第一步: 对应8k里的第几个寄存器 = 32xrow + col/16
注:col/16 是取结果 的整数部分,假如col等于9,col/16 为 0。
注:col%16 是取结果 的余数部分,假如col等于9,col%16 为 9。
这里如图有一个概念,需要说明,因为显示器的存储映射也是在RAM里的。
所以还要加上显示映射区域的起始地址,例如图中显示是 16384。
所以我们要找的 row行 ,col列的像素。在RAM里就是
RAM的第几个寄存器 = 16384 + 32xrow + col/16
第二步: 取出这RAM的寄存器后,修改对应“位”(col%16)
第三步:把修改后的16位值,在写回找出的寄存器。
课程视频里有一段视频演示
从 13分20 到 18分02
加载 tools/builtInChips/Screen.hdl
下图演示了,修改屏幕第3行 前16位 全为1(-1的二进制就是 1111 1111 1111 1111)
于是黄箭头指的就是 第三行前16位像素全置1的样子。
键盘
键盘原理就和屏幕其实是一样的了。
区别是,键盘只需要 一个寄存器就可以满足映射需求了。如下图
工作原理大概如下图:
当点击K建时,有一个提前规定好的Code,比如75,就会通过键盘的数据线传入 计算机映射到那个键盘寄存器。
当没有按下的任何建的时候,就是 0000xxx。
那么在Hack小电脑里,老师替我们提前规定好的对照表如下:
键盘上每一个键对应一个Code。
这个Code的二进制形式,就是键盘存储映射寄存器里的内容。
这样电脑只要探知某时刻键盘映射寄存器的值。就知道我们按下了什么键。
和屏幕映射存储区一样,当然都是老师提前设计好的,键盘映射寄存器,在整个RAM里也有一个门牌号。
键盘映射寄存器 老师设计在 RAM[24576]。
课程视频里有一段视频演示
从 23分10 到 26分15
加载 tools/builtInChips/Keyboard.hdl
注意:要点一下右侧 的 键盘图表,使之激活(按钮外围有蓝框显示)。
然后按住例如"g",这时 out 就显示了 71
松手就恢复了 0
这节课 讲了 屏幕 和 键盘 两个外设,如何通过 映射存储区域的方法 与 Hack小电脑交互。