flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Good Beefy PS/2 Mouse Driver for your OS |
Author |
|
MI-7 22 Aug 2024, 14:04
Cool that my code still lives on. (I should have put my name in it )
This is the, my, original NASM code: (thx for translating it to FASM, not much is changed though) I've written this around 2001 orso for use from programmersheaven.com. It was a part of my own OS called I-os (wow I should have registered that name back then before Apple took it ) Code: [ORG 0x0100] ;* YEP its a .COM file! ;I will use the NASM syntax!! ;I made this code for a Logitech M-S48a mouse. (normal PS/2 Code) ;For some reason the keyboard wil stall after program is terminated :S ;If you have problems understandig this code take a look at my mouseprog for the COM-mouse ;(Piece of disclaimer) ;(I do NOT give any guarantee or what so ever on this piece of code.) ;(I am not responsible for any damage whatsoever ) ;(By using this code u accept the two lines above ) ;(USAGE IS AT YOUR OWN RISK ) ;*************************************************** ;* This is for the system to know where to jump to * ;*************************************************** ; load source into DS:SI, * ; load target into ES:DI: * MOV AX, CS ;* MOV DS, AX ;* MOV ES, AX ;* ;*************************************************** JMP MAINP ;*********************************************************************** ;Activate mouse port (PS/2) ;*********************************************************************** PS2SET: mov al, 0xa8 ; enable mouse port out 0x64, al ; write to keyboardcontroller call CHKPRT ; check if command is progressed (demand!) ret ;*********************************************************************** ;Check if command is accepted. (not got stuck in inputbuffer) ;*********************************************************************** CHKPRT: xor cx, cx .again: in al, 0x64 ; read from keyboardcontroller test al, 2 ; Check if input buffer is empty jz .go jmp .again ; (demand!) This may couse hanging, use only when sure. .go ret ;*********************************************************************** ;Write to mouse ;*********************************************************************** WMOUS: mov al, 0xd4 ; write to mouse device instead of to keyboard out 0x64, al ; write to keyboardcontroller call CHKPRT ; check if command is progressed (demand!) ret ;*********************************************************************** ;mouse output buffer full ;*********************************************************************** MBUFFUL: xor cx, cx .mn: in al, 0x64 ; read from keyboardcontroller test al, 0x20 ; check if mouse output buffer is full jz .mnn loop .mn .mnn: ret ;*********************************************************************** ;Write activate Mouse HardWare ;*********************************************************************** ACTMOUS: call WMOUS mov al, 0xf4 ; Command to activate mouse itselve (Stream mode) out 0x60, al ; write ps/2 controller output port (activate mouse) call CHKPRT ; check if command is progressed (demand!) call CHKMOUS ; check if a byte is available ret ;*********************************************************************** ;Check if mouse has info for us ;*********************************************************************** CHKMOUS: mov bl, 0 xor cx, cx .vrd: in al, 0x64 ; read from keyboardcontroller test al, 1 ; check if controller buffer (60h) has data jnz .yy loop .vrd mov bl, 1 .yy: ret ;*********************************************************************** ;Disable Keyboard ;*********************************************************************** DKEYB: mov al, 0xad ; Disable Keyboard out 0x64, al ; write to keyboardcontroller call CHKPRT ; check if command is progressed (demand!) ret ;*********************************************************************** ;Enable Keyboard ;*********************************************************************** EKEYB: mov al, 0xae ; Enable Keyboard out 0x64, al ; write to keyboardcontroller call CHKPRT ; check if command is progressed (demand!) ret ;*********************************************************************** ;Get Mouse Byte ;*********************************************************************** GETB: .cagain call CHKMOUS ; check if a byte is available or bl, bl jnz .cagain call DKEYB ; disable keyboard to read mouse byte xor ax, ax in al, 0x60 ; read ps/2 controller output port (mousebyte) mov dl, al call EKEYB ; enable keyboard mov al, dl ret ;*********************************************************************** ;Get 1ST Mouse Byte ;*********************************************************************** GETFIRST: call GETB ;Get byte1 of packet xor ah, ah mov bl, al and bl, 1 mov BYTE [LBUTTON], bl mov bl, al and bl, 2 shr bl, 1 mov BYTE [RBUTTON], bl mov bl, al and bl, 4 shr bl, 2 mov BYTE [MBUTTON], bl mov bl, al and bl, 16 shr bl, 4 mov BYTE [XCOORDN], bl mov bl, al and bl, 32 shr bl, 5 mov BYTE [YCOORDN], bl mov bl, al and bl, 64 shr bl, 6 mov BYTE [XFLOW], bl mov bl, al and bl, 128 shr bl, 7 mov BYTE [YFLOW], bl ret ;*********************************************************************** ;Get 2ND Mouse Byte ;*********************************************************************** GETSECOND: call GETB ;Get byte2 of packet xor ah, ah mov BYTE [XCOORD], al ret ;*********************************************************************** ;Get 3RD Mouse Byte ;*********************************************************************** GETTHIRD: call GETB ;Get byte3 of packet xor ah, ah mov BYTE [YCOORD], al ret ;----------------------------------------------------------------------- ;*********************************************************************** ;* MAIN PROGRAM ;*********************************************************************** ;----------------------------------------------------------------------- MAINP: call PS2SET call ACTMOUS call GETB ;Get the responce byte of the mouse (like: Hey i am active) If the bytes are mixed up, remove this line or add another of this line. .main call GETFIRST call GETSECOND call GETTHIRD ;*NOW WE HAVE XCOORD & YCOORD* + the button status of L-butten and R-button and M-button allsow overflow + sign bits ;!!! ;! The Sign bit of X tells if the XCOORD is Negative or positive. (if 1 this means -256) ;! The XCOORD is allways positive ;!!! ;??? ;? Like if: X-Signbit = 1 Signbit ;? | ;? XCOORD = 11111110 ---> -256 + 254 = -2 (the mouse cursor goes left) ;? \ / ;? \ / ;? \Positive ;??? ;?? FOR MORE INFORMATION ON THE PS/2 PROTOCOL SEE BELOW!!!! ;!!!!!!!!!!!!! ;the rest of the source... (like move cursor) (i leave this up to you m8!) ;!!!!!!!!!!!!! ;************************************************************* ;Allright, Allright i'll give an example! |EXAMPLE CODE| ;************************************************************* ;============================= ;**Mark a position on scr** ;============================= mov BYTE [row], 15 mov BYTE [col], 0 ;============================= ;**go to start position** ;============================= call GOTOXY ;============================= ;**Lets display the X coord** ;============================= mov si, strcdx ; display the text for Xcoord call disp mov al, BYTE [XCOORDN] or al, al jz .negative mov si, strneg ; if the sign bit is 1 then display - sign call disp jmp .positive .negative mov si, strsp ; else display a space call disp .positive xor ah, ah mov al, BYTE [XCOORD] call DISPDEC mov si, stretr ; goto nextline on scr call disp ;============================= ;**Lets display the Y coord** ;============================= mov si, strcdy ; display the text for Ycoord call disp mov al, BYTE [YCOORDN] or al, al jz .negativex mov si, strneg ; if the sign bit is 1 then display - sign call disp jmp .positivex .negativex mov si, strsp ; else display a space call disp .positivex xor ah, ah mov al, BYTE [YCOORD] call DISPDEC mov si, stretr ; goto nextline on scr call disp ;============================= ;**Lets display the L button** ;============================= mov si, strlbt ; display the text for Lbutton call disp mov al, BYTE [LBUTTON] xor ah, ah call DISPDEC mov si, stretr ; goto nextline on scr call disp ;============================= ;**Lets display the R button** ;============================= mov si, strrbt ; display the text for Rbutton call disp mov al, BYTE [RBUTTON] xor ah, ah call DISPDEC mov si, stretr ; goto nextline on scr call disp ;============================= ;**Lets display the M button** ;============================= mov si, strmbt ; display the text for Mbutton call disp mov al, BYTE [MBUTTON] xor ah, ah call DISPDEC mov si, stretr ; goto nextline on scr call disp ;============================= ;**stop program on keypress** |Note: sometimes it takes a while for the program stops, or keyboard stalls| ;============================= |due to more time is spend looking at the PS/2 mouse port (keyb disabled) | xor ax, ax mov ah, 0x11 int 0x16 jnz quitprog ;************************************************************* jmp .main quitprog: MOV AH, 0x4C ;Return to OS INT 0x21 ;----------------------------------------------------------------------- ;*********************************************************************** ;* END OF MAIN PROGRAM ;*********************************************************************** ;----------------------------------------------------------------------- ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;X Dont Worry about this displaypart, its yust ripped of my os. ;X (I know it could be done nicer but this works ) ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXX ;************************************************ ;* Displays AX in a decimal way ;************************************************ DISPDEC: mov BYTE [zerow], 0x00 mov WORD [varbuff], ax xor ax, ax xor cx, cx xor dx, dx mov bx, 10000 mov WORD [deel], bx .mainl mov bx, WORD [deel] mov ax, WORD [varbuff] xor dx, dx xor cx, cx div bx mov WORD [varbuff], dx jmp .ydisp .vdisp cmp BYTE [zerow], 0x00 je .nodisp .ydisp mov ah, 0x0E ; BIOS teletype add al, 48 ; lets make it a 0123456789 mov bx, 1 int 0x10 ; invoke BIOS mov BYTE [zerow], 0x01 jmp .yydis .nodisp .yydis xor dx, dx xor cx, cx xor bx, bx mov ax, WORD [deel] cmp ax, 1 je .bver cmp ax, 0 je .bver mov bx, 10 div bx mov WORD [deel], ax jmp .mainl .bver ret ;***************END of PROCEDURE********************************* ;**************************************************************** ;* PROCEDURE disp ;* display a string at ds:si via BIOS ;**************************************************************** disp: .HEAD lodsb ; load next character or al, al ; test for NUL character jz .DONE ; if NUL char found then goto done mov ah, 0x0E ; BIOS teletype mov bx, 1 ; make it a nice fluffy blue (mostly it will be grey but ok..) int 0x10 ; invoke BIOS jmp .HEAD .DONE: ret ;*******************End Procedure *********************** ;***************************** ;*GOTOXY go back to startpos ;***************************** GOTOXY: mov ah, 2 mov bh, 0 ;0:graphic mode 0-3: in modes 2&3 0-7: in modes 0&1 mov dl, BYTE [col] mov dh, BYTE [row] int 0x10 ret ;*******END******** ; ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;*********************************************************************** ;variables ;*********************************************************************** LBUTTON db 0x00 ; Left button status 1=PRESSED 0=RELEASED RBUTTON db 0x00 ; Right button status 1=PRESSED 0=RELEASED MBUTTON db 0x00 ; Middle button status 1=PRESSED 0=RELEASED XCOORD db 0x00 ; the moved distance (horizontal) YCOORD db 0x00 ; the moved distance (vertical) XCOORDN db 0x00 ; Sign bit (positive/negative) of X Coord YCOORDN db 0x00 ; Sign bit (positive/negative) of Y Coord XFLOW db 0x00 ; Overflow bit (Movement too fast) of X Coord YFLOW db 0x00 ; Overflow bit (Movement too fast) of Y Coord ;************************************ ;* Some var's of my display function ;************************************ deel dw 0x0000 varbuff dw 0x0000 zerow db 0x00 strlbt db "Left button: ", 0x00 strrbt db "Right button: ", 0x00 strmbt db "Middle button: ", 0x00 strcdx db "Mouse moved (X): ", 0x00 strcdy db "Mouse moved (Y): ", 0x00 stretr db 0x0D, 0x0A, 0x00 strneg db "-", 0x00 strsp db " ", 0x00 row db 0x00 col db 0x00 ;*********************************************************************** ; PS/2 mouse protocol (Standard PS/2 protocol) ;*********************************************************************** ; ---------------------------------------------------------------------- ; ; Data packet format: ; Data packet is 3 byte packet. ; It is send to the computer every time mouse state changes ; (mouse moves or keys are pressed/released). ; ; Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 ; ; 1. YO XO YS XS 1 MB RB LB ; 2. X7 X6 X5 X4 X3 X2 X1 X0 ; 3. Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 ; ; This means: ; YO : Overflow bit for Y-coord (movement to fast) ; XO : Overflow bit for X-coord (movement to fast) ; X0-X7: byte of the x-coord ; Y0-Y7: byte of the y-coord ; LB : Left button pressed ; RB : Right button pressed ; MB : Middle button pressed ; ;*********************************************************************** ;If you want to use the scroll function u might look up the protocol at ;the company that made the mouse. ;(the packet format will then mostly be greater then 3) ;*********************************************************************** |
|||
22 Aug 2024, 14:04 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.