4. 智能键盘 (ikbd) 协议

4.1. 简介

Atari Corp. 的智能键盘 (ikbd) 是一种通用的键盘控制器,具有足够的灵活性,可以在各种产品中无需修改即可使用。 该键盘及其微控制器为鼠标和开关式操纵杆提供了方便的连接点。 ikbd 处理器还维护一个分辨率为一秒的实时时钟。 ikbd 的设计具有足够的通用性,可以与各种新的计算机产品一起使用。 可以适应许多按键开关,鼠标分辨率等方面的产品变化。 ikbd 通过高速双向串行接口与主处理器通信。 它可以在多种模式下运行,以方便键盘,操纵杆或鼠标的不同应用。 在仅具有单向通信介质的应用中,可以通过仔细设计默认模式来实现对控制器的有限使用。

4.2. 键盘

键盘始终返回按键按下/释放扫描码。ikbd 为每次按键和释放生成键盘扫描码。按键扫描码(按键闭合)从 1 开始,并在附录 A 中定义。 例如,即使特定键盘上的该位置没有按键开关,扫描码表中的 ISO 按键位置也应该存在。 每个按键的释放码是通过将 0x80 与按下码进行“或”运算得到的。

特殊代码 0xF6 到 0xFF 保留作以下用途

代码

命令

0xF6

状态报告

0xF7

绝对鼠标位置记录

0xF8-0xFB

相对鼠标位置记录(lsb 由鼠标按键状态确定)

0xFC

实时时间

0xFD

操纵杆报告(两个摇杆)

0xFE

操纵杆 0 事件

0xFF

操纵杆 1 事件

在此模式下,两个 shift 键返回不同的扫描码。 ENTER 键和 RETurn 键也是不同的。

4.3. 鼠标

鼠标端口应能够支持分辨率约为每英寸移动 200 个计数(相位变化或“点击”)的鼠标。鼠标应以允许在速度高达每秒 10 英寸的情况下进行精确跟踪的速率进行扫描。 ikbd 可以以三种截然不同的方式报告鼠标移动。它可以报告相对运动,ikbd 中维护的坐标系中的绝对运动,或通过将鼠标运动转换为键盘光标控制键等效项。鼠标按键可以被视为鼠标的一部分或附加的键盘按键。

4.3.1. 相对位置报告

在相对位置模式下,只要发生鼠标事件,ikbd 就会返回相对鼠标位置记录。鼠标事件包括按下或释放鼠标按钮,或者任一轴上的运动超过可设置的运动阈值。 无论阈值如何,所有分辨率位都会返回到主机。请注意,ikbd 返回的鼠标相对位置报告可能明显大于阈值 delta x 或 y。 这可能发生,因为不会生成任何相对鼠标移动事件:(a)当键盘“暂停”时(事件将被存储,直到恢复键盘通信)(b)当正在传输任何事件时。

相对鼠标位置记录是形式为三个字节的记录(无论键盘模式如何)

%111110xy           ; mouse position record flag
                    ; where y is the right button state
                    ; and x is the left button state
X                   ; delta x as twos complement integer
Y                   ; delta y as twos complement integer

请注意,即使 MOUSE BUTTON ACTION 已将按钮设置为像键盘的一部分一样,按键状态位的值也应有效。 如果在生成报告数据包之前累积的运动量超过 +127...-128 范围,则该运动将分解为多个数据包。 请注意,报告的 delta y 的符号是所选 Y 原点的函数。

4.3.2. 绝对位置报告

ikbd 还可以维护绝对鼠标位置。存在用于重置鼠标位置,设置 X/Y 缩放以及查询当前鼠标位置的命令。

4.3.3. 鼠标光标按键模式

ikbd 可以将鼠标移动转换为等效的光标按键。 每个轴上每次按键的鼠标点击次数是独立可编程的。ikbd 在内部以最高可用分辨率维护鼠标移动信息,并且仅为每个缩放因子的倍数生成一对光标按键事件。 鼠标移动会生成光标按键按下码,紧接着是相应光标按键的释放码。 鼠标按钮生成高于为最大设想键盘正常分配的扫描码(即 LEFT=0x74 & RIGHT=0x75)。

4.4. 操纵杆

4.4.1. 操纵杆事件报告

在此模式下,每当操纵杆位置更改时(即,对于操纵杆开关或触发器的每次打开或关闭),ikbd 都会生成一条记录。

操纵杆事件记录是两个字节的形式

%1111111x           ; Joystick event marker
                    ; where x is Joystick 0 or 1
%x000yyyy           ; where yyyy is the stick position
                    ; and x is the trigger

4.4.2. 操纵杆查询

在此模式下,可以通过向 ikbd 发送“查询操纵杆”命令来随时查询操纵杆端口的当前状态。

ikbd 对操纵杆查询的响应是形式为三个字节的报告

0xFD                ; joystick report header
%x000yyyy           ; Joystick 0
%x000yyyy           ; Joystick 1
                    ; where x is the trigger
                    ; and yyy is the stick position

4.4.3. 操纵杆监控

有一种模式可用,它几乎将所有键盘通信时间都用于以用户可指定速率报告操纵杆端口的状态。它将保持在此模式下,直到重置或命令进入另一种模式。 此模式下的 PAUSE 命令不仅停止输出,还会暂时停止扫描操纵杆(不排队采样)。

4.4.4. 火力按钮监控

提供了一种模式,允许以高速率监控单个输入位。在此模式下,ikbd 以串行通信通道允许的最大速率监控操纵杆 1 火力按钮的状态。 数据打包为每字节 8 位,用于传输到主机。ikbd 将保持在此模式下,直到重置或命令进入另一种模式。 此模式下的 PAUSE 命令不仅停止输出,还会暂时停止扫描按钮(不排队采样)。

4.4.5. 操纵杆按键代码模式

可以命令 ikbd 将任一操纵杆的使用转换为等效的光标控制按键。ikbd 提供了一个单断点速度操纵杆光标。操纵杆事件生成按下码,紧接着是相应光标移动键的释放码。操纵杆的触发器或火力按钮生成高于设想的最大按键矩阵所使用的伪按键扫描码(即 JOYSTICK0=0x74,JOYSTICK1=0x75)。

4.5. 实时时钟

ikbd 还为系统维护一个实时时钟。 可以使用命令来设置和查询实时时钟。 时间保持精度可达一秒。

4.6. 状态查询

可以通过发送与 ikbd 设置命令相对应的状态查询命令来查找 ikbd 模式和参数的当前状态。

4.7. 上电模式

键盘控制器将在上电时执行一个简单的自检,以检测主要的控制器故障(ROM 校验和和 RAM 测试)以及诸如卡住的按键之类的问题。在上电时按下的任何键都被认为是卡住的,并且返回它们的 BREAK (sic) 代码(没有之前的 MAKE 代码,这是一个键盘错误的标志)。 如果控制器自检完成且没有错误,则返回代码 0xF0。(此代码将用于指示 ikbd 控制器的版本/发行版。ikbd 的第一个版本是 0xF0,如果有第二个版本,它将是 0xF1,依此类推。) ikbd 默认为鼠标位置报告,两个轴的阈值为 1 个单位,并且 Y=0 原点在屏幕顶部,操纵杆 1 的操纵杆事件报告模式,并且两个按钮都逻辑分配给鼠标。 在任何操纵杆命令之后,ikbd 会假定操纵杆已连接到 Joystick0 和 Joystick1。 然后,任何鼠标命令(MOUSE DISABLE 除外)都会导致再次扫描端口 0,就好像它是鼠标一样,并且两个按钮都逻辑连接到它。 如果在假定端口 0 是鼠标时收到鼠标禁用命令,则该按钮将逻辑分配给 Joystick1(直到通过另一个鼠标命令重新启用鼠标)。

4.8. ikbd 命令集

本节包含可以发送到 ikbd 的命令列表。 未指定的命令代码(例如 0x00)应不执行任何操作 (NOP)。

4.8.1. 重置

0x80
0x01

注意:RESET 命令是 ikbd 唯一能识别的双字节命令。除了 0x01 之外,任何跟随 0x80 命令字节的字节都会被忽略(并导致 0x80 被忽略)。也可以通过向 ikbd 发送至少 200 毫秒的断开信号来触发复位。执行 RESET 命令会将键盘恢复到其默认(上电)模式和参数设置。它不会影响时间日期时钟。RESET 命令或功能会导致 ikbd 执行简单的自检。如果测试成功,ikbd 将在收到 RESET 命令(或断开信号结束或上电)后的 300 毫秒内发送代码 0xF0。然后,ikbd 将扫描按键矩阵,检查是否有卡住(闭合)的按键。如果发现有闭合的按键,将生成断开扫描码(断开代码在没有紧随其后的生成代码的情况下到达,是按键矩阵错误的标志)。

4.8.2. 设置鼠标按键动作

0x07
%00000mss           ; mouse button action
                    ;       (m is presumed = 1 when in MOUSE KEYCODE mode)
                    ; mss=0xy, mouse button press or release causes mouse
                    ;  position report
                    ;  where y=1, mouse key press causes absolute report
                    ;  and x=1, mouse key release causes absolute report
                    ; mss=100, mouse buttons act like keys

此命令设置 ikbd 应如何处理鼠标上的按键。默认鼠标按键动作模式为 %00000000,按键在逻辑上被视为鼠标的一部分。当按键像按键一样起作用时,LEFT=0x74 和 RIGHT=0x75。

4.8.3. 设置相对鼠标位置报告

0x08

设置相对鼠标位置报告。(默认)只要任何轴上的移动超过可设置的阈值(请参阅设置鼠标阈值),ikbd 就会异步生成鼠标位置数据包。根据鼠标按键模式,当按下或释放任何鼠标按键时,也可能会生成鼠标位置报告。否则,鼠标按键的行为就像键盘按键一样。

4.8.4. 设置绝对鼠标定位

0x09
XMSB                ; X maximum (in scaled mouse clicks)
XLSB
YMSB                ; Y maximum (in scaled mouse clicks)
YLSB

设置绝对鼠标位置维护。重置 ikbd 维护的 X 和 Y 坐标。在此模式下,内部维护的坐标值不会在 0 和较大的正数之间环绕。小于 0 的过度移动将被忽略。该命令设置缩放坐标系统中可以达到的最大正值。超出该值的移动也会被忽略。

4.8.5. 设置鼠标按键码模式

0x0A
deltax              ; distance in X clicks to return (LEFT) or (RIGHT)
deltay              ; distance in Y clicks to return (UP) or (DOWN)

设置鼠标监控例程,使其返回光标移动键码,而不是相对或绝对移动记录。在鼠标移动超过用户在任一轴中指定的增量后,ikbd 将返回相应的光标键码。当键盘处于按键扫描码模式时,鼠标移动将导致生成代码紧随其后的断开代码。请注意,此命令不受鼠标移动原点的影响。

4.8.6. 设置鼠标阈值

0x0B
X                   ; x threshold in mouse ticks (positive integers)
Y                   ; y threshold in mouse ticks (positive integers)

此命令设置生成鼠标事件之前的阈值。请注意,它不会影响返回到主机的数据的分辨率。此命令仅在相对鼠标定位模式下有效。阈值在复位(或上电)时默认为 1。

4.8.7. 设置鼠标缩放

0x0C
X                   ; horizontal mouse ticks per internal X
Y                   ; vertical mouse ticks per internal Y

此命令设置绝对鼠标定位模式的比例因子。在此模式下,必须发生指定数量的鼠标相位变化(“点击”),内部维护的坐标才会改变 1(每个轴独立缩放)。请记住,只有在绝对鼠标定位模式下查询 ikbd,才能获得鼠标位置信息,除非已命令 ikbd 报告按键按下或释放(请参阅设置鼠标按键动作)。

4.8.8. 查询鼠标位置

0x0D
Returns:
        0xF7       ; absolute mouse position header
BUTTONS
        0000dcba   ; where a is right button down since last interrogation
                   ; b is right button up since last
                   ; c is left button down since last
                   ; d is left button up since last
        XMSB       ; X coordinate
        XLSB
        YMSB       ; Y coordinate
        YLSB

无论鼠标按键动作的设置如何,查询鼠标位置命令在绝对鼠标定位模式下有效。

4.8.9. 加载鼠标位置

0x0E
0x00                ; filler
XMSB                ; X coordinate
XLSB                ; (in scaled coordinate system)
YMSB                ; Y coordinate
YLSB

此命令允许用户预设内部维护的绝对鼠标位置。

4.8.10. 设置 Y=0 在底部

0x0F

此命令使 Y 轴的原点位于 ikbd 内部逻辑坐标系的底部,用于所有相对或绝对鼠标移动。这会导致朝向用户的鼠标移动为负号,而远离用户的移动为正号。

4.8.11. 设置 Y=0 在顶部

0x10

使 Y 轴的原点位于 ikbd 内逻辑坐标系的顶部,用于所有相对或绝对鼠标移动。(默认)这会导致朝向用户的鼠标移动为正号,而远离用户的移动为负号。

4.8.12. 恢复

0x11

恢复向主机发送数据。由于 ikbd 在其输出被暂停后收到的任何命令也会导致隐式恢复,因此该命令可以被视为无操作命令。如果 ikbd 收到此命令,并且它未处于暂停状态,则会直接忽略它。

4.8.13. 禁用鼠标

0x12

禁用所有鼠标事件报告(并且可能在内部禁用扫描)。任何有效的鼠标模式命令都会恢复鼠标移动监控。(有效的鼠标模式命令包括设置相对鼠标位置报告、设置绝对鼠标定位和设置鼠标按键码模式。)注意:如果已命令鼠标按键像键盘按键一样起作用,则此命令会影响它们的动作。

4.8.14. 暂停输出

0x13

停止向主机发送数据,直到收到另一个有效命令。按键矩阵活动仍然会被监控,并且扫描码或 ASCII 字符会排队(达到微控制器支持的最大值),以便在主机允许恢复输出时发送。如果在操纵杆事件报告模式下,操纵杆事件也会排队。暂停输出时应累积鼠标移动。如果 ikbd 处于相对鼠标位置报告模式,则会将移动累积到超出正常阈值限制,以在恢复输出时生成最少数量的传输数据包。如果鼠标处于相对鼠标位置报告模式,按下或释放任何鼠标按键会导致任何累积的移动立即作为数据包排队。由于微控制器内存的限制,应谨慎使用此命令,并且一次关闭输出的时间不应超过 <待定> 毫秒。输出仅在当前“事件”结束时停止。如果在多字节报告中间收到暂停输出命令,数据包仍会传输到结束,然后暂停才会生效。当 ikbd 处于操纵杆监控模式或开火按键监控模式时,暂停输出命令也会暂时停止监控过程(即,不会将样本排队等待传输)。

4.8.15. 设置操纵杆事件报告

0x14

进入操纵杆事件报告模式(默认)。操纵杆开关或触发器的每次打开或关闭都会导致生成操纵杆事件记录。

4.8.16. 设置操纵杆查询模式

0x15

禁用操纵杆事件报告。主机必须发送单独的操纵杆查询命令来感知操纵杆状态。

4.8.17. 操纵杆查询

0x16

返回一条记录,指示操纵杆的当前状态。此命令在操纵杆事件报告模式或操纵杆查询模式下均有效。

4.8.18. 设置操纵杆监控

0x17
rate                ; time between samples in hundredths of a second
Returns: (in packets of two as long as in mode)
        %000000xy   ; where y is JOYSTICK1 Fire button
                    ; and x is JOYSTICK0 Fire button
        %nnnnmmmm   ; where m is JOYSTICK1 state
                    ; and n is JOYSTICK0 state

将 ikbd 设置为只监控串行命令行、维护时间日期时钟和监控操纵杆。速率设置操纵杆样本之间的间隔。注意:用户不应将速率设置得高于串行通信通道允许传输 2 字节数据包的速率。

4.8.19. 设置开火按键监控

0x18
Returns: (as long as in mode)
        %bbbbbbbb   ; state of the JOYSTICK1 fire button packed
                    ; 8 bits per byte, the first sample if the MSB

将 ikbd 设置为只监控串行命令行、维护时间日期时钟和监控操纵杆 1 上的开火按键。开火按键的扫描速率导致在将前一个字节发送到主机所花费的时间内进行 8 次采样(即,扫描速率 = 8/10 * 波特率)。采样间隔应尽可能恒定。

4.8.20. 设置操纵杆按键码模式

0x19
RX                  ; length of time (in tenths of seconds) until
                    ; horizontal velocity breakpoint is reached
RY                  ; length of time (in tenths of seconds) until
                    ; vertical velocity breakpoint is reached
TX                  ; length (in tenths of seconds) of joystick closure
                    ; until horizontal cursor key is generated before RX
                    ; has elapsed
TY                  ; length (in tenths of seconds) of joystick closure
                    ; until vertical cursor key is generated before RY
                    ; has elapsed
VX                  ; length (in tenths of seconds) of joystick closure
                    ; until horizontal cursor keystrokes are generated
                    ; after RX has elapsed
VY                  ; length (in tenths of seconds) of joystick closure
                    ; until vertical cursor keystrokes are generated
                    ; after RY has elapsed

在此模式下,扫描操纵杆 0 的方式会模拟光标按键。在初始闭合时,会生成一个按键对(生成/断开)。然后在最多 Rn 个十分之一秒后,每 Tn 个十分之一秒生成一个按键对。在达到 Rn 断点后,每 Vn 个十分之一秒生成一个按键对。这提供了一个速度(自动重复)断点功能。请注意,通过将 RX 和/或 Ry 设置为零,可以禁用速度功能。然后,TX 和 TY 的值变得毫无意义,并且光标“按键”的生成由 VX 和 VY 设置。

4.8.21. 禁用操纵杆

0x1A

禁用任何操纵杆事件的生成(并且可能会在内部禁用扫描)。任何有效的操纵杆模式命令都会恢复操纵杆监控。(操纵杆模式命令包括设置操纵杆事件报告、设置操纵杆查询模式、设置操纵杆监控、设置开火按键监控和设置操纵杆按键码模式。)

4.8.22. 时间日期时钟设置

0x1B
YY                  ; year (2 least significant digits)
MM                  ; month
DD                  ; day
hh                  ; hour
mm                  ; minute
ss                  ; second

所有时间日期数据应以压缩 BCD 格式发送到 ikbd。任何不是有效 BCD 数字的数字都应被视为“无关紧要”,并且不会更改日期或时间的特定字段。这允许仅设置时间日期时钟的某些子字段。

4.8.23. 查询时间日期时钟

0x1C
Returns:
        0xFC        ; time-of-day event header
        YY          ; year (2 least significant digits)
        MM          ; month
        DD          ; day
        hh          ; hour
        mm          ; minute
        ss          ; second

All time-of-day is sent in packed BCD format.

4.8.24. 内存加载

0x20
ADRMSB              ; address in controller
ADRLSB              ; memory to be loaded
NUM                 ; number of bytes (0-128)
{ data }

此命令允许主机将任意值加载到 ikbd 控制器内存中。数据字节之间的时间必须小于 20 毫秒。

4.8.25. 内存读取

0x21
ADRMSB              ; address in controller
ADRLSB              ; memory to be read
Returns:
        0xF6        ; status header
        0x20        ; memory access
        { data }    ; 6 data bytes starting at ADR

此命令允许主机从 ikbd 控制器内存中读取数据。

4.8.26. 控制器执行

0x22
ADRMSB              ; address of subroutine in
ADRLSB              ; controller memory to be called

此命令允许主机命令执行 ikbd 控制器内存中的子例程。

4.8.27. 状态查询

Status commands are formed by inclusively ORing 0x80 with the
relevant SET command.

Example:
0x88 (or 0x89 or 0x8A)  ; request mouse mode
Returns:
        0xF6        ; status response header
        mode        ; 0x08 is RELATIVE
                    ; 0x09 is ABSOLUTE
                    ; 0x0A is KEYCODE
        param1      ; 0 is RELATIVE
                    ; XMSB maximum if ABSOLUTE
                    ; DELTA X is KEYCODE
        param2      ; 0 is RELATIVE
                    ; YMSB maximum if ABSOLUTE
                    ; DELTA Y is KEYCODE
        param3      ; 0 if RELATIVE
                    ; or KEYCODE
                    ; YMSB is ABSOLUTE
        param4      ; 0 if RELATIVE
                    ; or KEYCODE
                    ; YLSB is ABSOLUTE
        0           ; pad
        0

状态查询命令请求 ikbd 返回当前模式或与给定命令关联的参数。所有状态报告都填充为 8 字节长的返回数据包。对状态请求的响应经过设计,使得主机可以存储它们(在剥离状态报告头字节之后),并在以后将其作为命令发送回 ikbd 以恢复其状态。 0 填充字节将被 ikbd 视为 NOP。

有效的状态查询命令有:

0x87    mouse button action
0x88    mouse mode
0x89
0x8A
0x8B    mnouse threshold
0x8C    mouse scale
0x8F    mouse vertical coordinates
0x90    ( returns       0x0F Y=0 at bottom
                0x10 Y=0 at top )
0x92    mouse enable/disable
        ( returns       0x00 enabled)
                0x12 disabled )
0x94    joystick mode
0x95
0x96
0x9A    joystick enable/disable
        ( returns       0x00 enabled
                0x1A disabled )

(主机)程序员有责任确保在任何时候只有一个未应答的查询正在处理中。如果 ikbd 处于 操纵杆监视模式 或 开火按钮监视模式,则状态查询命令无效。

4.9. 扫描码

ikbd 返回的按键扫描码经过选择,以简化 GSX 的实现。

GSX 标准键盘映射

十六进制

键帽

01

Esc

02

1

03

2

04

3

05

4

06

5

07

6

08

7

09

8

0A

9

0B

0

0C

-

0D

=

0E

BS

0F

TAB

10

Q

11

W

12

E

13

R

14

T

15

Y

16

U

17

I

18

O

19

P

1A

[

1B

]

1C

RET

1D

CTRL

1E

A

1F

S

20

D

21

F

22

G

23

H

24

J

25

K

26

L

27

;

28

29

`

2A

(左)Shift

2B

\

2C

Z

2D

X

2E

C

2F

V

30

B

31

N

32

M

33

,

34

.

35

/

36

(右)Shift

37

{ 未使用 }

38

ALT

39

空格键

3A

大写锁定

3B

F1

3C

F2

3D

F3

3E

F4

3F

F5

40

F6

41

F7

42

F8

43

F9

44

F10

45

{ 未使用 }

46

{ 未使用 }

47

HOME

48

向上箭头

49

{ 未使用 }

4A

小键盘 -

4B

向左箭头

4C

{ 未使用 }

4D

向右箭头

4E

小键盘 +

4F

{ 未使用 }

50

向下箭头

51

{ 未使用 }

52

插入

53

删除

54

{ 未使用 }

5F

{ 未使用 }

60

ISO键

61

撤销

62

帮助

63

小键盘 (

64

小键盘 /

65

小键盘 *

66

小键盘 *

67

小键盘 7

68

小键盘 8

69

小键盘 9

6A

小键盘 4

6B

小键盘 5

6C

小键盘 6

6D

小键盘 1

6E

小键盘 2

6F

小键盘 3

70

小键盘 0

71

小键盘 .

72

小键盘 Enter