62、BIOS 级编程与鼠标编程详解

BIOS 级编程与鼠标编程详解

1. 像素绘制与颜色设置

在视频模式 13h 下,我们可以进行像素绘制和颜色设置。以下是一个示例代码,用于将调色板索引 1 的颜色设置为白色(RGB 值为 63,63,63),并在屏幕中间绘制 10 个像素:

; Sets individual palette colors and draws 
; several pixels.
;------------------------------------------------
; Change the color at index 1 to white (63,63,63).
mov dx,VIDEO_PALLETE_PORT
mov al,1
; set palette index 1
out dx,al
mov dx,COLOR_SELECTION_PORT
mov al,63
; red
out dx,al
mov al,63
; green
out dx,al
mov al,63
; blue
out dx,al
; Calculate the video buffer offset of the first pixel.
; Method is specific to mode 13h, which is 320 X 200.
mov xVal,160
; middle of screen
mov yVal,100
mov ax,320
; 320 for video mode 13h
mul yVal
; y-coordinate
add ax,xVAl
; x-coordinate
; Place the color index into the video buffer.
mov cx,10
; draw 10 pixels
mov di,ax
; AX contains buffer offset
; Draw the pixels now. By default, the assembler assumes 
; DI is an offset from the segment address in DS. The 
; segment override ES:[DI] tells the CPU to use the segment 
; address in ES instead. ES currently points to VRAM.
DP1:
mov BYTE PTR es:[di],COLOR_INDEX
add di,5
; move 5 pixels to the right
loop DP1
ret
Draw_Some_Pixels ENDP
END main

这个程序相对容易实现,因为像素都在同一屏幕行上。如果要绘制垂直线,可以每次将 DI 的值增加 320 以移动到下一行像素;绘制斜率为 1 的对角线,则可以将 DI 增加 321。对于任意两点之间的直线绘制,Bresenham 算法是最佳选择,该算法在许多网站上都有详细解释。

2. 视频模式 13h 相关问题解答

以下是一些关于视频模式 13h 的常见问题及解答:
|问题|答案|
|----|----|
|(True/False): Video mode 13h maps screen pixels as a two-dimensional array of bytes, where each byte corresponds to two pixels.|False|
|(True/False): In video mode 13h, each screen row uses 320 bytes of storage.|True|
|In one sentence, explain how video mode 13h sets the colors of pixels.|通过设置调色板索引和对应的 RGB 值来设置像素颜色。|
|How is the color index used in video mode 13h?|颜色索引用于从调色板中选择特定的颜色,并将其应用到视频缓冲区中的像素上。|
|In video mode 13h, what is contained in each element of the color palette?|每个调色板元素包含一个 RGB 颜色值。|
|What are the three RGB values for dark gray?|通常为(32, 32, 32)。|
|What are the three RGB values for white?|(63, 63, 63)|
|What are the three RGB values for bright red?|(63, 0, 0)|
|Challenge: Show how to set the screen background color in video mode 13h to green.|可以通过设置调色板索引对应的 RGB 值为绿色(如 0, 63, 0),并将该索引应用到整个视频缓冲区。|
|Challenge: Show how to set the screen background color in video mode 13h to white.|设置调色板索引对应的 RGB 值为白色(63, 63, 63),并将该索引应用到整个视频缓冲区。|

3. 鼠标编程基础

鼠标通常通过 PS - 2 鼠标端口、RS - 232 串口、USB 端口或无线连接到计算机主板。在检测鼠标之前,MS - DOS 需要安装设备驱动程序。鼠标的移动以“米基”(mickeys)为单位进行跟踪,1 米基约代表 1/200 英寸的物理鼠标移动距离。鼠标的米基与像素的比例可以设置,默认情况下,每 8 个水平像素对应 8 米基,每 8 个垂直像素对应 16 米基,还有一个双速阈值,默认值为每秒 64 米基。

4. 鼠标 INT 33h 函数

INT 33h 提供了关于鼠标的各种信息,包括其当前位置、最后点击的按钮、速度等,还可以用于显示或隐藏鼠标光标。以下是一些重要的 INT 33h 函数:
|函数编号|描述|接收参数|返回值|示例调用|
|----|----|----|----|----|
|0|Reset mouse and get status|AX = 0|如果支持鼠标,AX = FFFFh 且 BX = 鼠标按钮数量;否则,AX = 0|mov ax,0
int 33h
cmp ax,0
je MouseNotAvailable
mov numberOfButtons,bx|
|1|Show mouse pointer|AX = 1|无|mov ax,1
int 33h|
|2|Hide mouse pointer|AX = 2|无|mov ax,2
int 33h|
|3|Get mouse position and status|AX = 3|BX = 鼠标按钮状态
CX = X 坐标(像素)
DX = Y 坐标(像素)|mov ax,3
int 33h
test bx,1
jne Left_Button_Down
test bx,2
jne Right_Button_Down
test bx,4
jne Center_Button_Down
mov Xcoord,cx
mov yCoord,dx|
|4|Set mouse position|AX = 4
CX = X 坐标(像素)
DX = Y 坐标(像素)|无|mov ax,4
mov cx,200 ; X - position
mov dx,100 ; Y - position
int 33h|
|5|Get button press information|AX = 5
BX = 按钮 ID (0 = 左,1 = 右,2 = 中)|AX = 按钮状态
BX = 按钮按下计数器
CX = 最后按钮按下的 X 坐标
DX = 最后按钮按下的 Y 坐标|mov ax,5
mov bx,0 ; button ID
int 33h
test ax,1 ; left button down?
jz skip ; no - skip
mov X_coord,cx ; yes: save coordinates
mov Y_coord,dx|
|6|Get button release information|AX = 6
BX = 按钮 ID (0 = 左,1 = 右,2 = 中)|AX = 按钮状态
BX = 按钮释放计数器
CX = 最后按钮释放的 X 坐标
DX = 最后按钮释放的 Y 坐标|mov ax,6
mov bx,0 ; button ID
int 33h
test ax,1 ; left button released?
jz skip ; no - skip
mov X_coord,cx ; yes: save coordinates
mov Y_coord,dx|
|7|Set horizontal limits|AX = 7
CX = 最小 X 坐标(像素)
DX = 最大 X 坐标(像素)|无|mov ax,7
mov cx,100 ; set X - range to
mov dx,700 ; (100,700)
int 33h|
|8|Set vertical limits|AX = 8
CX = 最小 Y 坐标(像素)
DX = 最大 Y 坐标(像素)|无|mov ax,8
int 33h
mov cx,100 ; set Y - range to
mov dx,500 ; (100,500)
int 33h|

5. 坐标转换

在 MS - DOS 中,标准文本字体为 8 像素宽、16 像素高,因此可以通过以下公式进行像素坐标和字符坐标的转换:
- 像素坐标转字符坐标:$C = int(P / D)$,其中 $C$ 是字符坐标,$P$ 是像素坐标,$D$ 是字符尺寸。例如,假设字符宽度为 8 像素,如果 INT 33h 函数 3 返回的 X 坐标为 100 像素,则对应的字符位置为 $int(100 / 8) = 12$。
- 字符坐标转像素坐标:$P = C * D$,其中 $C$ 是字符坐标,$P$ 是像素坐标,$D$ 是字符尺寸。例如,如果字符宽度为 8 像素,要将鼠标放在字符单元格 12 中,则该单元格最左侧像素的 X 坐标为 $12 * 8 = 96$。

6. 鼠标跟踪程序

以下是一个简单的鼠标跟踪程序,用于跟踪文本鼠标光标的移动,不断更新屏幕右下角的 X 和 Y 坐标,并在用户按下左键时,在屏幕左下角显示鼠标的位置:

TITLE Tracking the Mouse                      (mouse.asm)
; Demonstrates basic mouse functions available via INT 33h.
; In Standard DOS mode, each character position in the DOS
; window equals 8 mouse units.
INCLUDE Irvine16.inc
GET_MOUSE_STATUS = 0
SHOW_MOUSE_POINTER = 1
HIDE_MOUSE_POINTER = 2
GET_CURSOR_SIZE = 3
GET_BUTTON_PRESS_INFO = 5
GET_MOUSE_POSITION_AND_STATUS = 3
ESCkey = 1Bh
.data
greeting    BYTE "[Mouse.exe] Press Esc to quit",0
statusLine  BYTE "Left button: "
            BYTE "Mouse position: ",0
blanks      BYTE "                ",0
xCoord WORD 0
; current X-coordinate
yCoord WORD 0
; current Y-coordinate
xPress WORD 0
; X-coord of last button press
yPress WORD 0
; Y-coord of last button press
; Display coordinates.
statusRow      BYTE ?
statusCol      BYTE 15
buttonPressCol BYTE 20
statusCol2     BYTE 60
coordCol       BYTE 65
.code
main PROC
mov ax,@data
mov ds,ax
call Clrscr
; Get the screen X/Y coordinates.
call GetMaxXY
; DH = rows, DL = columns
dec dh
; calculate status row value
mov statusRow,dh
; Hide the text cursor and display the mouse.
call HideCursor
mov dx,OFFSET greeting
call WriteString
call ShowMousePointer
; Display status information on the bottom screen line.
mov dh,statusRow
mov dl,0
call Gotoxy
mov dx,OFFSET statusLine
call Writestring
; Loop: show mouse coordinates, check for left mouse
; button press or keypress (Esc key).
L1:
call ShowMousePosition
call LeftButtonPress
; check for button press
mov ah,11h
; key pressed already?
int 16h
jz L2          
; no, continue the loop
mov ah,10h
; remove key from buffer
int 16h
cmp al,ESCkey   
; yes. Is it the ESC key?
je quit        
; yes, quit the program
L2:
jmp L1 
; no, continue the loop
; Hide the mouse, restore the text cursor, clear
; the screen, and wait for a key press.
quit:
call HideMousePointer
call ShowCursor
call Clrscr
call WaitMsg
exit
main ENDP
;---------------------------------------------------------
GetMousePosition PROC USES ax
;
; Gets the current mouse position and button status.
; Receives: nothing
; Returns:  BX = button status (0 = left button down,
;           (1 = right button down, 2 = center button down)
;           CX = X-coordinate
;           DX = Y-coordinate
;---------------------------------------------------------
mov ax,GET_MOUSE_POSITION_AND_STATUS
int 33h
ret
GetMousePosition ENDP
;---------------------------------------------------------
HideCursor PROC USES ax cx
;
; Hide the text cursor by setting its top line
; value to an illegal value.
; Receives: nothing. Returns: nothing
;---------------------------------------------------------
mov ah,GET_CURSOR_SIZE
int 10h
or ch,30h
; set upper row to illegal value
mov ah,1
; set cursor size
int 10h
ret
HideCursor ENDP
;---------------------------------------------------------
ShowCursor PROC USES ax cx
;
; Show the text cursor by setting size to default.
; Receives: nothing. Returns: nothing
;---------------------------------------------------------
mov ah,GET_CURSOR_SIZE
int 10h
mov ah,1
; set cursor size
mov cx,0607h
; default size
int 10h
ret
ShowCursor ENDP
;---------------------------------------------------------
HideMousePointer PROC USES ax
;
; Hides the mouse pointer. 
; Receives: nothing. Returns: nothing
;---------------------------------------------------------
mov ax,HIDE_MOUSE_POINTER
int 33h
ret
HideMousePointer ENDP
;---------------------------------------------------------
ShowMousePointer PROC USES ax
;
; Makes the mouse pointer visible.
; Receives: nothing. Returns: nothing
;---------------------------------------------------------
mov ax,SHOW_MOUSE_POINTER ; make mouse cursor visible
int 33h
ret
ShowMousePointer ENDP
;---------------------------------------------------------
LeftButtonPress PROC
;
; Checks for the most recent left mouse button press
; and displays the mouse location.
; Receives: nothing. Returns: nothing
;---------------------------------------------------------
pusha
mov ax,GET_BUTTON_PRESS_INFO
mov bx,0
; specify the left button
int 33h
; Exit proc if the coordinates have not changed.
cmp cx,xPress
; same X coordinate?
jne L1
; no: continue
cmp dx,yPress
; same Y coordinate?
je L2
; yes: exit
; Coordinates have changed, so save them.
L1:
mov xPress,cx
mov yPress,dx
; Position the cursor, clear the old numbers.
mov dh,statusRow
; screen row
mov dl,statusCol
; screen column
call Gotoxy
push dx
mov dx,OFFSET blanks
call WriteString
pop dx
; Show coordinates where mouse button was pressed.
call Gotoxy
mov ax,xCoord
call WriteDec
mov dl,buttonPressCol
call Gotoxy
mov ax,yCoord
call WriteDec
L2:
popa
ret
LeftButtonPress ENDP
;---------------------------------------------------------
SetMousePosition PROC
;
; Set the mouse's position on the screen.
; Receives: CX = X-coordinate
;           DX = Y-coordinate
; Returns:  nothing
;---------------------------------------------------------
mov ax,4
int 33h
ret
SetMousePosition ENDP
;---------------------------------------------------------
ShowMousePosition PROC
;
; Get and show the mouse coordinates at the
; bottom of the screen.
; Receives: nothing
; Returns:  nothing
;---------------------------------------------------------
pusha
call GetMousePosition
; Exit proc if the coordinates have not changed.
cmp cx,xCoord
; same X coordinate?
jne L1
; no: continue
cmp dx,yCoord
; same Y coordinate?
je L2
; yes: exit
; Save the new X and Y coordinates.
L1:
mov xCoord,cx
mov yCoord,dx
; Position the cursor, clear the old numbers.
mov dh,statusRow
; screen row
mov dl,statusCol2
; screen column
call Gotoxy
push dx
mov dx,OFFSET blanks
call WriteString
pop dx
; Show the mouse coordinates.
call Gotoxy
mov ax,xCoord
call WriteDec
mov dl,coordCol
; screen column
call Gotoxy
mov ax,yCoord
call WriteDec
L2:
popa
ret
ShowMousePosition ENDP
END main

该程序的行为会根据两个因素有所变化:一是所运行的 MS - Windows 版本,二是在控制台窗口还是全屏模式下运行。例如,在 Windows XP 及更高版本中,控制台窗口默认有 50 条垂直文本行。在全屏模式下,鼠标光标是一个实心块,其坐标似乎每次变化一个像素;而在控制台窗口模式下,鼠标光标是一个指针,其坐标水平方向每 8 像素、垂直方向每 16 像素变化一次。

7. 鼠标编程相关问题解答

以下是一些关于鼠标编程的常见问题及解答:
|问题|答案|
|----|----|
|Which INT 33h function resets the mouse and gets the mouse status?|Function 0|
|Write ASM statements that reset the mouse and get the mouse status.|mov ax,0
int 33h
cmp ax,0
je MouseNotAvailable
mov numberOfButtons,bx|
|Which INT 33h function shows and hides the mouse pointer?|Function 1 显示鼠标指针,Function 2 隐藏鼠标指针|
|Write ASM statements that hide the mouse pointer.|mov ax,2
int 33h|
|Which INT 33h function gets the mouse position and status?|Function 3|
|Write ASM statements that get the mouse position and store it in the variables mouseX and mouseY.|mov ax,3
int 33h
mov mouseX,cx
mov mouseY,dx|
|Which INT 33h function sets the mouse position?|Function 4|
|Write ASM statements that set the mouse pointer to X = 100 and Y = 400.|mov ax,4
mov cx,100
mov dx,400
int 33h|
|Which INT 33h function gets mouse button press information?|Function 5|
|Write ASM statements that jump to label Button1 when the left mouse button has been pressed.|mov ax,5
mov bx,0
int 33h
test ax,1
jne Button1|
|Which INT 33h function gets mouse button release information?|Function 6|
|Write ASM statements that get the mouse position at the point when the right button was released, and store the position in the variables mouseX and mouseY.|mov ax,6
mov bx,1
int 33h
mov mouseX,cx
mov mouseY,dx|
|Write ASM statements that set the vertical limits of the mouse to 200 and 400.|mov ax,8
mov cx,200
mov dx,400
int 33h|
|Write ASM statements that set the horizontal limits of the mouse to 300 and 600.|mov ax,7
mov cx,300
mov dx,600
int 33h|

通过以上内容,我们对 BIOS 级编程中的像素绘制、颜色设置以及鼠标编程有了更深入的了解。无论是简单的像素绘制,还是复杂的鼠标跟踪程序,都离不开对相关函数和算法的掌握。希望这些内容能帮助你在编程实践中更好地运用这些知识。

BIOS 级编程与鼠标编程详解

8. 鼠标编程的其他功能

除了前面介绍的主要 INT 33h 函数外,还有一些其他有用的鼠标编程功能,以下是这些功能的详细介绍:
|函数编号|描述|输入/输出参数|
|----|----|----|
|AX = 0Fh|Sets the number of mickeys per 8 pixels for horizontal and vertical mouse motion.|接收:CX = 水平米基数,DX = 垂直米基数。默认值为 CX = 8,DX = 16。|
|AX = 10h|Set mouse exclusion area (prevents mouse from entering a rectangle).|接收:CX, DX = 左上角的 X, Y 坐标。SI, DI = 右下角的 X, Y 坐标|
|AX = 13h|Set double speed threshold.|接收:DX = 双速阈值(米基/秒),默认值为 64|
|AX = 1Ah|Set mouse sensitivity and threshold.|接收:BX = 水平速度(米基/秒),CX = 垂直速度(米基/秒),DX = 双速阈值(米基/秒)|
|AX = 1Bh|Get mouse sensitivity and threshold.|返回:BX = 水平速度,CX = 垂直速度,DX = 双速阈值|
|AX = 1Fh|Disable mouse driver.|返回:如果失败,AX = FFFFh|
|AX = 20h|Enable mouse driver.|无|
|AX = 24h|Get mouse information.|错误时返回 FFFFh;否则,返回:BH = 主版本号,BL = 次版本号,CH = 鼠标类型 (1 = 总线,2 = 串口,3 = InPort,4 = PS/2,5 = HP);CL = IRQ 号(PS/2 鼠标为 0)|

9. 鼠标编程流程总结

下面通过一个 mermaid 流程图来总结鼠标编程的基本流程:

graph TD
    A[初始化] --> B[检测鼠标支持]
    B -- 支持 --> C[显示鼠标指针]
    B -- 不支持 --> D[提示错误并退出]
    C --> E[循环检测鼠标事件]
    E --> F{是否有按键按下}
    F -- 是 --> G[处理按键事件]
    F -- 否 --> H{是否有鼠标移动}
    H -- 是 --> I[更新鼠标位置显示]
    H -- 否 --> E
    G --> E
    I --> E
10. 鼠标编程的实际应用场景

鼠标编程在很多实际场景中都有应用,以下是一些常见的应用场景:
- 游戏开发 :在游戏中,鼠标可以用于控制角色的移动、攻击、选择物品等操作。通过鼠标编程,可以实现精确的鼠标交互,提升游戏的用户体验。
- 图形设计软件 :图形设计软件需要用户通过鼠标进行绘图、选择工具、调整图形等操作。鼠标编程可以实现对鼠标事件的精确处理,满足图形设计的需求。
- 用户界面设计 :在各种软件的用户界面中,鼠标可以用于点击按钮、拖动窗口、选择菜单项等操作。鼠标编程可以实现流畅的用户界面交互,提高软件的易用性。

11. 鼠标编程的注意事项

在进行鼠标编程时,需要注意以下几点:
- 兼容性问题 :不同的操作系统和硬件平台可能对鼠标编程的支持有所不同。在编写代码时,需要考虑兼容性问题,确保程序在不同环境下都能正常运行。
- 性能优化 :鼠标事件的处理可能会对系统性能产生一定的影响。在编写代码时,需要注意性能优化,避免出现卡顿或响应不及时的情况。
- 错误处理 :在鼠标编程过程中,可能会出现各种错误,如鼠标驱动未安装、鼠标设备故障等。在编写代码时,需要进行错误处理,确保程序在出现错误时能够给出合理的提示。

12. 总结

本文详细介绍了 BIOS 级编程中的像素绘制、颜色设置以及鼠标编程的相关知识。通过对视频模式 13h 的了解,我们可以实现像素的绘制和颜色的设置;通过对 INT 33h 函数的掌握,我们可以实现鼠标的各种操作,如检测鼠标状态、显示/隐藏鼠标指针、获取鼠标位置等。同时,我们还介绍了鼠标编程的其他功能、流程总结、实际应用场景以及注意事项。希望这些内容能帮助你在编程实践中更好地运用这些知识,实现更复杂的鼠标交互功能。

通过以上内容,我们对 BIOS 级编程和鼠标编程有了全面的认识。无论是初学者还是有一定经验的开发者,都可以从这些知识中获得启发,进一步提升自己的编程能力。在实际应用中,我们可以根据具体需求,灵活运用这些知识,开发出更加实用和高效的程序。

内容概要:本文档围绕六自由度机械臂的ANN人工神经网络设计展开,涵盖正向逆向运动学求解、正向动力学控制,并采用拉格朗日-欧拉法推导逆向动力学方程,所有内容均通过Matlab代码实现。同时结合RRT路径规划B样条优化技术,提升机械臂运动轨迹的合理性平滑性。文中还涉及多种先进算法仿真技术的应用,如状态估计中的UKF、AUKF、EKF等滤波方法,以及PINN、INN、CNN-LSTM等神经网络模型在工程问题中的建模求解,展示了Matlab在机器人控制、智能算法系统仿真中的强大能力。; 适合人群:具备一定Ma六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)tlab编程基础,从事机器人控制、自动化、智能制造、人工智能等相关领域的科研人员及研究生;熟悉运动学、动力学建模或对神经网络在控制系统中应用感兴趣的工程技术人员。; 使用场景及目标:①实现六自由度机械臂的精确运动学动力学建模;②利用人工神经网络解决传统解析方法难以处理的非线性控制问题;③结合路径规划轨迹优化提升机械臂作业效率;④掌握基于Matlab的状态估计、数据融合智能算法仿真方法; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点理解运动学建模神经网络控制的设计流程,关注算法实现细节仿真结果分析,同时参考文中提及的多种优化估计方法拓展研究思路。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值