NASM 纯汇编打造简单中文操作系统(4 mouse.inc 鼠标驱动部分(设置鼠标中断,建立中断处理程序))

四、mouse.inc 鼠标驱动部分(设置鼠标中断,建立中断处理程序)

[BITS 32]
[ORG 0x0]
;鼠标中断处理程序
INT_MOUSE:
 PUSHAD
 PUSHF
;刷新鼠标所在区域

 ReadPort 0x60
 MOV AH,0 
 
 CMP [DS:SYSVAR+0x10],BYTE 0
 JZ c0
 CMP [DS:SYSVAR+0x10],BYTE 1
 JZ c1
 CMP [DS:SYSVAR+0x10],BYTE 2
 JZ c2 
c0:
jmp button
c1:
jmp xpos
c2:
jmp ypos
button:
 TEST AL,0x1 ;1=leftbutton 2=rightbutton
 JZ bt0

 bt0:
 MOV [DS:SYSVAR+0x11],BYTE AL ;鼠标按键给变量
 ADD [DS:SYSVAR+0x10],BYTE 1 ;读取累加器+1
 JMP rt    ;处理完毕跳走

 
xpos:
 
 ADD [DS:SYSVAR+0x10],BYTE 1 ;读取累加器+1
 ;计算符号加减
 CBW
 MOV [DS:SYSVAR+0x12],WORD AX ;x坐标放到零时变量
 MOV AX,[DS:SYSVAR+0x0C]  ;读出坐标变量内容与鼠标移动偏移相加
 ADD AX,[DS:SYSVAR+0x12]  ;x坐标+移动偏移
 MOV [DS:SYSVAR+0x12],WORD 0 ;清空临时变量
 
 CMP AX,0xf9ff
 JNG x1
 MOV [DS:SYSVAR+0x0C],WORD 0xF9FF
 JMP x2
 x1:
 CMP AX,0xFA00
 JNG x2
 MOV [DS:SYSVAR+0x0C],WORD 0xFA00
 x2:
 MOV [DS:SYSVAR+0x0C],WORD AX ;累加坐标放到坐标变量中


 JMP rt    ;处理完毕跳走
ypos:
 MOV [DS:SYSVAR+0x10],BYTE 0 ;清零读取累加器
 CBW
 ;ADD [DS:SYSVAR+0x10],BYTE 1 ;读取累加器+1
 ;SHR AL,1
 NEG AX
 MOV [DS:SYSVAR+0x12],WORD AX ;y坐标放到零时变量
 MOV AX,[DS:SYSVAR+0x0E]  ;读出坐标变量内容与鼠标移动偏移相加
 ADD AX,[DS:SYSVAR+0x12]  ;y坐标+移动偏移
 MOV [DS:SYSVAR+0x12],WORD 0 ;清空临时变量
 CMP AX,32767
 JNG y1
 MOV [DS:SYSVAR+0x0E],WORD 0
 JMP y2
 y1:
 CMP AX,598
 JNG y2
 MOV [DS:SYSVAR+0x0E],WORD 598
 y2:
 MOV [DS:SYSVAR+0x0E],WORD AX ;累加坐标放到坐标变量中
;保存鼠标将要显示的区域
; PUSH WORD 8
; PUSH WORD 8
; PUSH WORD  [DS:SYSVAR+0x0E];y
; PUSH WORD  [DS:SYSVAR+0x0C];x
; CALL GetCurLastRect
;区域恢复
; PUSH  DWORD SYSMOUSEBUF
; PUSH WORD  0x80
; PUSH WORD  8
; PUSH WORD  8
; PUSH WORD  [DS:SYSVAR+0x16];y
; PUSH WORD  [DS:SYSVAR+0x14];x
; CALL DrawPixelBuf 
 push word 0  ;0=常规拷贝,1=与目标or,2=与目标and,3=与目标xor
 PUSH WORD  [DS:SYSVAR+0x16];endy
 PUSH WORD  [DS:SYSVAR+0x14];endx
 MOV AX,[DS:SYSVAR+0x16];endy
 MOV BX,[DS:SYSVAR+0x14];endx
 ADD AX,8
 ADD BX,8
 PUSH AX
 PUSH BX
 PUSH WORD  [DS:SYSVAR+0x16];starty
 PUSH WORD  [DS:SYSVAR+0x14];startx 
 CALL BitBlt
;显示鼠标光标
 PUSH  DWORD SYSMOUSEBUF+0x80;鼠标像素所在位置
 PUSH WORD  0x80
 PUSH WORD  8
 PUSH WORD  8
 PUSH WORD  [DS:SYSVAR+0x0E];y
 PUSH WORD  [DS:SYSVAR+0x0C];x
 CALL DrawPixelBuf
 MOV AX,[DS:SYSVAR+0x0E];y
 MOV BX,[DS:SYSVAR+0x0C];x
 MOV [DS:SYSVAR+0x16],AX;y
 MOV [DS:SYSVAR+0x14],BX;x 
 JMP rt
rt:
 
 MOV AL,0x20
 OUT 0x20,AL
 OUT 0xA0,AL
 POPF
 POPAD

IRET
;----------------------------------------------------------------------------
;通过点阵信息生成一个16位色的像素点阵
;鼠标指针是个8*8位的点阵也就是8个子节
;0x4000-0x40ff ;鼠标指针数据256byte
;----------------------------------------------------------------------------
SetCursorColor:
 PUSH EBP
 MOV EBP,ESP
 SUB ESP,2  ;开辟局部变量
    
 MOV ESI,0x4000
 MOV EDI,0x4080
cursor:
MOV BL,[DS:ESI]
MOV ECX,8
MOV [ESP+0],WORD 1   ;指针轮廓开关
 lopshl:
 PUSH CX
 SHL BL,1
 JC matrix   ;CF是否溢出是否有点阵数据
 MOV AX,[ESP+0+2]  ;获得绘制开关-0xffff表示矩阵开始
 CMP AX,2 
 JNZ nomatrix  ;如果指针矩阵还没有开始
  MOV [DS:EDI],WORD 0xFFFF ;鼠标轮廓内部用白色填充
 JMP goon
 nomatrix:   ;处理鼠标光标影响没处理时的空点阵
  MOV [DS:EDI],WORD 0x1111 ;光标外形以外的部分不显示.也就是把鼠标光标的形状挖出来  
 JMP goon
 matrix:
  ADD [ESP+0+2],WORD 1 ;如果有点阵那么标志设置1表示点阵开始 
  MOV [DS:EDI],WORD 0x0000    ;鼠标轮廓用黑色
 goon: 
 ADD EDI,2
 POP CX
 LOOP lopshl
INC SI 
CMP SI,0x4008
JNZ cursor 
;保存鼠标将要显示的区域
 PUSH WORD 8
 PUSH WORD 8
 PUSH WORD  [DS:SYSVAR+0x0E];y
 PUSH WORD  [DS:SYSVAR+0x0C];x
 CALL GetCurLastRect 
 
 MOV ESP,EBP
 POP EBP
ret
;---------------------------------------------------------------------------
;获得指定区域的像素
;并保存到鼠标指针的第一个128b的缓冲区
;PUSH WORD matrix_y
;PUSH WORD matrix_x
;PUSH WORD starty
;PUSH WORD startx
;--------------------------------------------------------------------------
GetCurLastRect:
 PUSH EBP
 MOV EBP,ESP
 SUB ESP,4
 XOR EAX,EAX
 XOR EBX,EBX
 MOV AX,[ESP+8+4] ;x
 MOV BX,[ESP+10+4] ;y
 MOV [ESP+0],AX
 MOV [ESP+2],BX
 ADD [ESP+12+4],AX ;计算endx
 ADD [ESP+14+4],BX ;计算endy
 MOV EDI,SYSMOUSEBUF ;鼠标指针缓冲区地址
my:
 MOV BX,[ESP+10+4]
 MOV [ESP+2],BX ;重置x坐标
  mx: 
   PUSH EDI
   PUSH WORD 1  ;从缓冲区取
   PUSH WORD [ESP+2+6] ;y
   PUSH WORD [ESP+0+8] ;x
   CALL GetPoint
   POP EDI
   MOV [DS:EDI],AX
   ADD EDI,2
  ADD [ESP+2],WORD 1
  MOV BX,[ESP+2]
  CMP BX,[ESP+14+4]
  JNZ mx
ADD [ESP+0],WORD 1
MOV BX,[ESP+0]
CMP BX,[ESP+12+4]
JNZ my
 MOV ESP,EBP
 POP EBP
ret 0x8
;初始化鼠标中断
InitMouse:

 PUSH EBP
 MOV EBP,ESP

  
  
 ;设置中断表项地址
 MOV EAX,INT_MOUSE
 MOV CL,16
 MOV [DS:SYSTB+0x3C*8],WORD AX 
 SHR EAX,CL
 PUSH CS
 POP CX
 MOV [DS:SYSTB+2+0x3C*8],WORD CX
 MOV [DS:SYSTB+6+0x3C*8],WORD AX 
  
 CLI
 XOR EDX,EDX
 XOR EAX,EAX
 MOV DX,0xA1
 IN AL,DX
      AND AL,11101111b ;打开鼠标中断
 OUT DX,AL

  ;对 8042 键盘控制芯片进行编程 

 mov     bl,0xa8                 ; enable mouse cmd
 call    kb_cmd
 call    kb_read                 ; read status
 
 mov     bl,0x20                 ; get command byte
 call    kb_cmd
 call    kb_read
 or      al,3                    ; enable interrupt
 mov     bl,0x60                 ; write command
 push    eax
 call    kb_cmd
 pop     eax
 call    kb_write
 
 mov     bl,0xd4                 ; for mouse
 call    kb_cmd
 mov     al,0xf4                 ; enable mouse device
 call    kb_write
 call    kb_read           ; read status return
 
   
     STI
 MOV ESP,EBP
 POP EBP
ret

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

替计划实验室Plan T Labs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值