这么多寄存器,只有一个端口0x3D5,怎么来操作其中某一个呢?这就用到Address Register了。我们看到表7.5中每一个寄存器都对应一个索引值,当想要访问其中一个时,只需要先向Address Register写对应的索引值 (通过端口0x3D4),然后再通过端口0x3D5进行的操作就是针对索引值对应的寄存器了。如果我们把Data Registers看作一个数组,那么 Address Register就相当于数组的下标。
举个例子,假如想把索引号为idx的寄存器的值改为new_value,可以这样来做:
out_byte (0x3D4, idx);
out_byte (0x3D5, new_value);
可以看到,只是多了一次端口操作而已。
/*======================================================================*
in_process
*======================================================================*/
PUBLIC void in_process(u32 key)
{
char output[2] = {'\0', '\0'};
if (!(key & FLAG_EXT)) {
output[0] = key & 0xFF;
disp_str(output);
disable_int();
out_byte(CRTC_ADDR_REG, CURSOR_H);
out_byte(CRTC_DATA_REG, ((disp_pos/2)>>8)&0xFF);
out_byte(CRTC_ADDR_REG, CURSOR_L);
out_byte(CRTC_DATA_REG, (disp_pos/2)&0xFF);
enable_int();
}
else {
int raw_code = key & MASK_RAW;
switch(raw_code) {
case UP:
if ((key & FLAG_SHIFT_L) || (key & FLAG_SHIFT_R)) {
disable_int();
out_byte(CRTC_ADDR_REG, START_ADDR_H);
out_byte(CRTC_DATA_REG, ((80*15) >> 8) & 0xFF);
out_byte(CRTC_ADDR_REG, START_ADDR_L);
out_byte(CRTC_DATA_REG, (80*15) & 0xFF);
enable_int();
}
break;
case DOWN:
if ((key & FLAG_SHIFT_L) || (key & FLAG_SHIFT_R)) {
/* Shift+Down, do nothing */
}
break;
default:
break;
}
}
}
Start Address High Register和Start Address Low Register两个寄存器可以用来设置从显存的某个位置开始显示。这个特性允许我们把显存划分成不同的部分,然后只需要简单的寄存器设置就可以显示相应位置的内容。