Raspberry Pi Input02

实验目标

在实验Input 01的基础上建立一个命令行接口,计算机可以中断并显示它们。

终端

具体操作行为步骤如下: 1. 启动计算机,显示欢迎信息 2. 计算机表明它准备好工作 3. 使用者在键盘上键入指令和参数 4. 当敲下回车键时表示提交一条指令 5. 计算机解析并执行指令如果该指令没有错误 6. 计算机显示指令正确以及接下来发生了什么 7. 返回到步骤2

在终端的命令行输入输出操作都具有一定的统一性,因此我们不再需要去绘制出每一个像素点(计算机在此处的额操作是以字符为单位的),我们将每一个字符的图案信息、颜色信息等都保存起来,再按照需要通过DrawCharacter函数调用每一个字符即可。

.section .data
.align 4
terminalStart:
.int terminalBuffer
terminalStop:
.int terminalBuffer
terminalView:
.int terminalBuffer
terminalColour:
.byte 0xf
.align 8
terminalBuffer:
.rept 128*128
.byte 0x7f
.byte 0x0
.endr
terminalScreen:
.rept 1024/8 * 768/16
.byte 0x7f
.byte 0x0
.endr

terminalBuffer

可以保存我们所有需要显示的文本信息,这里定义了最多可以保存128行并且每个保存了128个字符,每个字符又保存了ASCII字符以及颜色信息,使用buffer的优点如下: 1. 我们可以轻易看哪个字符不同,从而区分出来 2. 我们可以回滚到历史版本因为buffer里面可以保存到历史信息

terminalScreen

保存当前显示的文本信息

terminalStart terminalStop

由于在这里的buffer是环形结构的,类似于数据结构的循环链表,因此需要用Start和Stop来进行标识起始于中止位置,因此当中止超过起始的时候就能发觉是否要更替字母或者其它操作

.

terminalColor

综合前景文字与背景各16种颜色,一共256组合,每个字符中低位保存的是前景颜色,高位保存的是背景颜色,

文本显示

terminalDisplay

该函数是从terminalBuffer中复制当前的数据到terminalScreen中,首先要比较二者是否不同,如果不同要数据更新。

  1. 加载 terminalView terminalStop terminalDisplay 函数
  2. 对于每一行来说(先行遍历)
    1. 对于每一列来说(再列遍历)
      1. 如果view视图中不为stop,则加载view当前字符与颜色
      2. 否在加载字符0x7f与颜色0
      3. terminalDisplay加载当前字符
      4. 如果二者相同则跳转到步骤10
      5. 二者不同则需要将加载到的字符与颜色保存到terminalDisplay
      6. 调用 TerminalColor 函数,获取背景颜色
      7. 调用 DrawCharacter 函数,r0 = 0x7f(空白),r1=x, r2 = y
      8. 调用 TerminalColor 函数,获取前景颜色
      9. 调用 DrawCharacter 函数,r0 = 当前显示字符,r1=x, r2 = y
      10. terminalDisplay 函数显示的位置加2
      11. 如果view 与 stop 不相同(没有将所有空间填满),view的位置也加2
      12. 否则要将end替换掉start的位置
      13. x的坐标要加8
    2. y的坐标要加16

打印行信息

该函数在r0寄存器中保存了串地址,在r1中保存了串长度,然后将内容写出到当前的地址中,并显示到显示器上。

  1. 检测串长度是否为0,如果为0则返回
  2. 加载 terminalStopterminalView 函数
  3. 计算并确认x坐标的位置(目的是为了确定要显示串的位置)
  4. 对于每一个字符有以下操作
    1. 检查换行符
    2. 如果需要换行将bufferStop标识更新到行尾
    3. 如果不需要换行将字符复制到当前的terminalColour中
    4. 检查是否在行尾
    5. 如果在行尾就需要检查在terminalView与terminalStop中的字符数量是否超过了当前屏幕所能容纳的数量
    6. 如果超出当前屏幕就需要换行
    7. 检查 terminalView 如果在buffer尾,则需要将start更新
    8. 检查 terminalStop 如果在buffer尾,则需要将start更新
    9. 检查 terminalStopterminalStart 是否相等,如果相等则需要增加 terminalStart的值来换行
    10. 检查 terminalStart 是否在buffer尾,如果是这样则用start来更新当前值
  5. 保存 terminalStopterminalView

标准输入

ReadLine

  1. 如果最大长度是0(即没有输入),那么返回0
  2. 取回 terminalStopterminalView 当前值
  3. 如果最大长度大于buffer大小的一半,将长度置为buffer大小的一半
  4. 从最大长度减去以保证能实现下划线闪烁与空终端的实现
  5. 在字符串中加上下划线
  6. 写回 terminalViewterminalStop 地址
  7. 对当前字符串调用 Print 函数
  8. 调用 terminalDisplay
  9. 调用 KeyboardUpdate
  10. 调用 KeyboardGetChar
  11. 如果是新的行字符,到步骤16
  12. 如果是空格并且长度大于1则在长度上减1
  13. 如果是常规字符并且长度小于最大长度那么将字符写入到串中
  14. 如果字符串以下划线结尾,加一个空格否则加一个下划线
  15. 回到步骤6
  16. 在已有的字符串后面增加一个新行
  17. 调用 PrintTerminalDisplay 函数
  18. 将新行用空终端来代替
  19. 返回字符串的长度