Google Groups unterstützt keine neuen Usenet-Beiträge oder ‑Abos mehr. Bisherige Inhalte sind weiterhin sichtbar.

Mouse Driver

2 Aufrufe
Direkt zur ersten ungelesenen Nachricht

Robert Lee

ungelesen,
25.01.2001, 02:01:1825.01.01
an

I'm trying to make a small PS/2 mouse driver for an OS I'm writing. I'm
starting off by writing a small program for DOS that hooks IRQ12 and signals
the user when INT 74h is triggered. The signal is a character being printed
on the screen at the top of video memory (B800h). The idea is to make sure I
understand the concept of IRQs correctly before going in too deep.
Unfortunately, my simple experiment isn't working.

Here's my understanding, tell me if I'm wrong. There are 2 PIC chips, one is
cascaded on the other. PIC1 uses ports 20h and 21h and covers IRQs 1 to 7.
PIC2 uses ports 0A0h and 0A1h and covers IRQs 8 to 15. The PS/2 mouse uses
IRQ 12 on PIC2. I can access mouse calls on INT 74h. To setup my interrupt
routine and enable IRQ 12 I would map INT 74h to my ISR and clear bit 5 of
port 0A1h. When INT 74h is called, the ISR confirms the IRQ to PIC2 by
writing 20h to port 0A0h before IRETing.

Is that about it? Anything else I should do when installing the IRQ handler?
Is there anything else I should do when confirming the IRQ in the ISR? Can I
experiment with this in Windows or must I restart in MSDOS mode to program
the PIC?

My defunct mouse experiment is at http://leeos.cjb.net/software/ps2.asm , it
doesn't work in windows or dos.

-Robert

anon...@bogus_address.con

ungelesen,
25.01.2001, 08:35:5125.01.01
an

On 2001-01-25 robe...@maine.rr.nodamnspam.com said:

>I'm trying to make a small PS/2 mouse driver for an OS I'm writing.
>

> [...snip...] [...snip...]


>
>My defunct mouse experiment is at http://leeos.cjb.net/software/ps2.

>asm, it doesn't work in windows or dos.

Go to http://www.vein.hu/~nagyd/

There you'll find the 'Cute Mouse' driver (CTMOUS18.RAR). Download it.
All your questions will be answered.

You'll need RAR or UNRAR to extract the archive.

'Cute Mouse' is the official mouse driver of the FreeDOS Project. It's
available for free, and comes complete with 100 per cent ASM source code.

'Cute Mouse' supports serial and PS/2 mice. It includes auto-detection
routines, as well as fully functional PS/2 mouse code.

This is an amazing and thoroughly comprehensive work. It'll teach you
more about writing mouse drivers than any 17 textbooks ever could.

Alexei A. Frounze

ungelesen,
25.01.2001, 08:36:1325.01.01
an
20h should be written to port 0A0h prior to writing 20h to port 20h for IRQs
above 8. This is because 1st PIC is master and 2nd is slave, which is
cascaded, e.g. 2nd always involves working with 1st.
btw, there was a simple ps/2 mouse driver for DOS with source....
I can not remember the site but I have the source, executable and a short
doc. I also have a PDF file on one mouse on my homepage...
Just look thru miscdocs section of the page. they are both there.

Good Luck
--
Alexei A. Frounze
alexfru [AT] chat [DOT] ru
frounze [AT] ece [DOT] rochester [DOT] edu
http://alexfru.chat.ru
http://members.xoom.com/alexfru/
http://welcome.to/pmode/

"Robert Lee" <robe...@maine.rr.nodamnspam.com> wrote in message
news:t6vjpue...@corp.supernews.com...

Rick C. Hodgin

ungelesen,
25.01.2001, 13:24:4325.01.01
an

>Is that about it? Anything else I should do when installing the IRQ handler?
>Is there anything else I should do when confirming the IRQ in the ISR? Can I
>experiment with this in Windows or must I restart in MSDOS mode to program
>the PIC?

You need to also write 20h to port 20h after you write it to 0A0h.
That will correctly signal the EOI on both PICs.

You have to send a command to the PS/2 mouse to enable it. Send
command 0D4h to port 64h followed by command 0F4h to port 60h. This
will enable the mouse. It will respond with some characters to IRQ12.

The only thing I've found that needs to be done to make it work is to
correctly align the mouse driver packet count with the 3-byte packets
the PS/2 driver will be sending. You do this by initializing a count
variable to 0 after you receive all the bytes the mouse has to send
back from the command 0F4h. Then you receive all 3 bytes before
processing. If you don't have a copy of the PS/2 packet layout I can
provide it for you.

Personally I didn't find that mouse program the other people are
mentioning very useful. I did buy some books and I figured out the
theory behind why it works the way it does, a method I would always
recommend over just looking at someone else's code.

- Rick C. Hodgin

Robert Lee

ungelesen,
25.01.2001, 13:24:4525.01.01
an

In my ISR I put:

gogomouse:
stosw
; ----------
mov al, 20h
mov dx, 20h
out dx, al
mov al, 20h
mov dx, 0a0h
out dx, al
; ----------
iret

And its still not being called. Note that its not even being called the
first time which leads me to beleave the problem lies in the way I'm setting
up the IRQ:

mov dx, 0a1h
in al, dx
and al, 11011111b
out dx, al

Should I be sending 20h to 21h before this code as well or should I be
sending 11011111b to 21h before this code? Or should I be sending 20h to 20h
again?

-Robert

Alexei A. Frounze

ungelesen,
25.01.2001, 15:53:0625.01.01
an

"Robert Lee" <robe...@maine.rr.nodamnspam.com> wrote in message
news:t70rrdn...@corp.supernews.com...

>
> In my ISR I put:
>
> gogomouse:
> stosw
> ; ----------
> mov al, 20h
> mov dx, 20h
> out dx, al
> mov al, 20h
> mov dx, 0a0h
> out dx, al
> ; ----------
> iret

this seems to be fine.

> And its still not being called. Note that its not even being called the
> first time which leads me to beleave the problem lies in the way I'm
setting
> up the IRQ:
>
> mov dx, 0a1h
> in al, dx
> and al, 11011111b
> out dx, al

now this is a problem.
it should be
and al, 11101111b
instead.

>
> Should I be sending 20h to 21h before this code as well or should I be
> sending 11011111b to 21h before this code? Or should I be sending 20h to
20h
> again?

just unmask irq12 at the beginning (well, after you set up ISR and patched
vector table).

Rick C. Hodgin

ungelesen,
25.01.2001, 15:53:0825.01.01
an

>gogomouse:
> stosw

What is stosw from? In order to read from the mouse you need to read
from port 60h. My PS/2 mouse handler basically does this:

push eax
in al,60h ; read byte from mouse
; I store it here, process the packet if this is the 3rd byte
mov al,020h
out 0a0h,al
out 020h,al
pop eax
iretd

> ; ----------
> mov al, 20h
> mov dx, 20h
> out dx, al
> mov al, 20h
> mov dx, 0a0h
> out dx, al
>; ----------
> iret

You can simplify this:
mov al,20h
out 0a0h,al
out 020h,al

>And its still not being called. Note that its not even being called the
>first time which leads me to beleave the problem lies in the way I'm setting
>up the IRQ:

Are you unmasking IRQ12? Are you enabling the mouse with command
0f4h? Are you sure that IRQ's are vectored to the INTs you think they
are?

- Rick C. Hodgin

Robert Lee

ungelesen,
25.01.2001, 15:53:1125.01.01
an

Ok, I've got this: http://leeos.cjb.net/software/ps2.asm

Basically after mapping the interupt to my routine I'm doing this:

mov dx, 0a1h ; Clear IRQ 12 bit
in al, dx
and al, 11101111b
out dx, al
mov al, 0D4h ; Enable Mouse
mov dx, 64h
out dx, al
mov al, 0F4h
mov dx, 60h
out dx, al

And in my routine (which still never gets called) I'm doing this:

mov al, 20h ; Call Ack


mov dx, 0a0h
out dx, al

mov al, 20h
mov dx, 20h
out dx, al

iret

I must be still missing something in the init code. I can directly clear bit
4 of a1h without dealing with 20h or 21h right? Or do I need to tell PIC1
something as well?

Robert Lee

ungelesen,
25.01.2001, 16:35:2825.01.01
an

My updated code is at http://leeos.cjb.net/software/ps2.asm go by that no
what's on here because the code posted here is old (its a moderated board,
the lag is throwing our conversation out of sync).

The stosw is my signal. At the beginning of my program (see URL above) I'm
setting ES to B800 and DI to 0 (video memory). My ISR is only signalling the
user that its being called in this version by printing a character onto the
top of the screen). That's why I'm calling it a PS2 mouse 'experiment'. As
you can see by my code above, I'm mapping the interrupt, programming the PIC
and enabling the mouse as you said. IRQ 12 always goes to INT 74h right? I'm
under the impression that that's always the case, if its not, then how do I
tell what interrupt, IRQ 12 is calling?

Anyways, the code is less then 1 page in size (very simple) so it won't be
hard to read at all. Its well commented too. I think my problem is in the
"Setup the hardware" section since the ISR never gets called. When the ISR
is called all its supposed to do is print a character to video memory (as a
signal to the user). Thanks for your help BTW!

-Robert

johnfine

ungelesen,
25.01.2001, 20:56:0625.01.01
an
Robert Lee wrote:

> The stosw is my signal. At the beginning of my program (see URL above) I'm
> setting ES to B800 and DI to 0 (video memory). My ISR is only signalling the
> user that its being called in this version by printing a character onto the
> top of the screen).

The stosw is one of your bugs. While you wait, you call int 16h.
It almost certainly uses ES and DI, so that when the interrupt occurs
ES and DI don't have the expected value. A related bug is that you
are destroying the value that int 16h may have in AX. Even if you
didn't call int 16h, there would be a risk of your service routine
tripping over some other hardware service routine.

Fix those problems as follows

gogomouse:
push ax
push ds
; ---------- Temporary: Signal User ---------------------------- ;
mov ax, 0b800h
mov ds, ax
mov word ptr ds:[2], 5020h


; ---------- Process the event --------------------------------- ;
in al,60h
; (We're going to ignore the data for now)

; ---------- Acknoledge the call ------------------------------- ;
mov al, 20h
out 0a0h, al
out 20h, al

; ---------- Return ------------------------------------------- ;
pop ds
pop ax
iret

> I think my problem is in the
> "Setup the hardware" section

Most of that looks right. I know (without looking it up) the
correct way to do everything but the

mov al, 0D4h
out 64h, al
mov al, 0F4h
out 60h, al

so if that step is wrong, someone else will need to tell you. The PIC
and vector parts look right.

Alexei A. Frounze

ungelesen,
25.01.2001, 23:54:4425.01.01
an

no, u don't have to tell PIC anything, if you just mask/unmask an IRQ.

--
Alexei A. Frounze
alexfru [AT] chat [DOT] ru
frounze [AT] ece [DOT] rochester [DOT] edu
http://alexfru.chat.ru
http://members.xoom.com/alexfru/
http://welcome.to/pmode/

"Robert Lee" <robe...@maine.rr.nodamnspam.com> wrote in message

news:t714hnk...@corp.supernews.com...

Robert Lee

ungelesen,
26.01.2001, 00:48:2126.01.01
an

Ok great. Still doesn't work after fixing the signal methods though. Am I
supposed to do something to the PIC to activate it or tell it what INT to
use? Does it automatically know that IRQ12 should trigger INT 74h?

I'm also lost on the mouse commands by the way. I'm not sure why I was told
to do...

mov al, 0D4h
out 64h, al
mov al, 0F4h
out 60h, al

....becouse port 60h is the keyboard data port. Why would I write to that?

-Robert

Alexei A. Frounze

ungelesen,
26.01.2001, 07:50:3826.01.01
an
"Robert Lee" <robe...@maine.rr.nodamnspam.com> wrote in message
news:t723t59...@corp.supernews.com...

>
> Ok great. Still doesn't work after fixing the signal methods though. Am I
> supposed to do something to the PIC to activate it or tell it what INT to
> use? Does it automatically know that IRQ12 should trigger INT 74h?

by default it knows and there's no reason to do anything else with PIC. just
one thing -- unmask IRQ12 and that's it. and sent EOI to slave and master
parts of PIC upon return from ISR.

>
> I'm also lost on the mouse commands by the way. I'm not sure why I was
told
> to do...
>
> mov al, 0D4h
> out 64h, al
> mov al, 0F4h
> out 60h, al
>
> ....becouse port 60h is the keyboard data port. Why would I write to that?

Because this is the way PS/2 has been done. Have you ever seen keyboards
with mice connected directly to them instead of the computer? If so, this
answers the question completely. This is a design of PS/2 kbd+mouse stuff.
They are both connected to the same port.

Here's a source for incomplete PS/2 mouse driver which actually works (A386
assembler is required):

-----------8<----------


xor ax,ax
int 33h
cmp ax,0ffffh
jmp not_loaded

mov ah,9
mov dx,offset already_loaded
int 21h

mov ax,4c01h
int 21h

not_loaded:

mov ah,9
mov dx,offset intro_string
int 21h

mov ax,2574h
mov dx,offset new_isr
int 21h

mov ax,2533h
mov dx,offset new_33
int 21h

cli

mov bl,0a8h
call keyboard_cmd

mov bl,20h
call keyboard_cmd
call keyboard_read
or al,2
mov bl,60h
push ax
call keyboard_cmd
pop ax
call keyboard_write

mov bl,0d4h
call keyboard_cmd
mov al,0f4h
call keyboard_write

sti

mov dx,offset end_of_tsr
int 27h

intro_string db 0dh,0ah,'DPSMouseDRV (c) 1998',0dh,0ah,'$'
already_loaded db 0dh,0ah,'Mouse driver already loaded!',0dh,0ah,'$'

call_user_isr:
db 60h
mov cx,cs:[pos_x]
mov dx,cs:[pos_y]
mov di,0 ;cs:[x_move]
mov si,0 ;cs:[y_move]
mov w[cs:x_move],0
mov w[cs:y_move],0
mov bl,cs:[buttons]
xor bh,bh
call dword ptr cs:[user_subroutine]
db 61h
ret

new_isr:
pushf
cli
push ax
push bx
push cx
push dx
push di
push si
push es
push ds

push cs
pop ds

mov bl,0adh
call keyboard_cmd

cmp b[first_time],0
je not_first_time

mov b[first_time],0
call keyboard_read
call keyboard_read
call keyboard_read
jmp no_show

not_first_time:
mov w[temp_mask],0

mov cx,word ptr [offset pos_x]
mov dx,word ptr [offset pos_y]

call keyboard_read
and al,7 ;3
mov ah,[buttons]
mov [buttons],al
cmp al,ah
je no_button_change
and al,3
and ah,3
xor al,ah
xor bx,bx

push ax
test al,2
jz no_right_button_change
and ah,2
jz right_button_pressed
or bx,16
jmp no_right_button_change
right_button_pressed:
or bx,8
no_right_button_change:

pop ax

test al,1
jz no_left_button_change
and ah,1
jz left_button_pressed
or bx,4
jmp no_left_button_change
left_button_pressed:
or bx,2
no_left_button_change:

mov [temp_mask],bx

no_button_change:
call keyboard_read
cbw
add word ptr [pos_x],ax
add word ptr [x_move],ax
mov ax,[x_min]
cmp word ptr [pos_x],ax
jg good_hor1
mov word ptr [pos_x],ax
good_hor1:
mov ax,[x_max]
cmp word ptr [pos_x],ax
jle good_hor2
mov word ptr [pos_x],ax
good_hor2:

call keyboard_read
neg al
cbw
add word ptr [pos_y],ax
add word ptr [y_move],ax
mov ax,[y_min]
cmp word ptr [pos_y],ax
jg good_ver1
mov word ptr [pos_y],ax
good_ver1:
mov ax,[y_max]
cmp word ptr [pos_y],ax
jle good_ver2
mov word ptr [pos_y],ax
good_ver2:

mov ax,[x_move]
or ax,[y_move]
or ax,ax
jz no_change_position
or w[temp_mask],1
no_change_position:

mov ax,[temp_mask]
and ax,[user_mask]
jz no_call_user
call call_user_isr
no_call_user:

cmp byte ptr [sm_flag],1
jne no_show

shr cx,3
shr dx,3
mov ax,80
mul dl
add ax,cx
shl ax,1
mov di,ax
mov ax,0b800h
mov es,ax
mov ax,word ptr [offset save_char]
stosw

mov cx,word ptr [offset pos_x]
mov dx,word ptr [offset pos_y]
shr cx,3
shr dx,3
mov ax,80
mul dl
add ax,cx
shl ax,1
mov di,ax
mov ax,0b800h
mov es,ax
mov ax,word ptr es:[di]
mov word ptr [offset save_char],ax
not ah
and ah,7fh
stosw
no_show:
mov bl,0aeh
call keyboard_cmd

mov al,20h
out 0a0h,al
out 20h,al

pop ds
pop es
pop si
pop di
pop dx
pop cx
pop bx
pop ax
popf
iret

first_time db 1
buttons db 0
pos_x dw 0
pos_y dw 0
sm_flag dw 0
save_char dw 0
x_move dw 0
y_move dw 0
x_max dw 639
x_min dw 0
y_max dw 199
y_min dw 0
user_subroutine dw 0,0
user_mask dw 0
temp_mask dw 0

keyboard_read:
push cx
push dx
xor cx,cx
key_read_loop:
in al,64h
jmp $+2
jmp $+2
test al,1
jnz key_read_ready
loop key_read_loop
mov ah,1
jmp key_read_exit
key_read_ready:
push cx
mov cx,32
key_read_delay:
jmp $+2
jmp $+2
loop key_read_delay

pop cx

in al,60h
jmp $+2
jmp $+2
xor ah,ah
key_read_exit:
pop dx
pop cx
ret

keyboard_write:
push cx
push dx
mov dl,al
xor cx,cx
kbd_wrt_loop1:
in al,64h
jmp $+2
jmp $+2
test al,20h
jz kbd_wrt_ok1

loop kbd_wrt_loop1

mov ah,1
jmp kbd_wrt_exit

kbd_wrt_ok1:
in al,60h

xor cx,cx
kbd_wrt_loop:
in al,64h
jmp $+2
jmp $+2
test al,2
jz kbd_wrt_ok

loop kbd_wrt_loop

mov ah,1
jmp kbd_wrt_exit

kbd_wrt_ok:
mov al,dl
out 60h,al
jmp $+2
jmp $+2

xor cx,cx
kbd_wrt_loop3:
in al,64h
jmp $+2
jmp $+2
test al,2
jz kbd_wrt_ok3

loop kbd_wrt_loop3

mov ah,1
jmp kbd_wrt_exit

kbd_wrt_ok3:
mov ah,8
kbd_wrt_loop4:
xor cx,cx
kbd_wrt_loop5:
in al,64h
jmp $+2
jmp $+2
test al,1
jnz kbd_wrt_ok4

loop kbd_wrt_loop5

dec ah
jnz kbd_wrt_loop4

kbd_wrt_ok4:
xor ah,ah
kbd_wrt_exit:
pop dx
pop cx
ret

keyboard_cmd:
xor cx,cx
cmd_wait:
in al,64h
jmp $+2
jmp $+2
test al,2
jz cmd_send
loop cmd_wait

jmp cmd_error

cmd_send:
mov al,bl
out 64h,al
jmp $+2
jmp $+2

xor cx,cx
cmd_accept:
in al,64h
jmp $+2
jmp $+2
test al,2
jz cmd_ok
loop cmd_accept

cmd_error:
mov ah,1
jmp cmd_exit
cmd_ok:
xor ah,ah
cmd_exit:
ret

new_33:
cli
cmp al,0
je reset_mouse
cmp al,1
je show_mouse
cmp al,2
je hide_mouse
cmp al,3
je get_pos
cmp al,4
je set_pos
cmp al,7
je set_hor_pos
cmp al,8
je set_ver_pos
cmp al,0bh
je get_mouse_movement
cmp al,0ch
je set_subroutines
cmp al,14h
je swap_subroutines
iret

reset_mouse:
jmp _reset_mouse
show_mouse:
jmp _show_mouse
hide_mouse:
jmp _hide_mouse
get_pos:
jmp _get_pos
set_pos:
jmp _set_pos
set_hor_pos:
jmp _set_hor_pos
set_ver_pos:
jmp _set_ver_pos
get_mouse_movement:
jmp _get_mouse_movement
set_subroutines:
jmp _set_subroutines
swap_subroutines:
jmp _swap_subroutines

_reset_mouse:
mov b[cs:offset buttons],0
mov w[cs:offset pos_x],0
mov w[cs:offset pos_y],0
mov w[cs:offset x_move],0
mov w[cs:offset y_move],0
mov w[cs:offset x_max],639
mov w[cs:offset x_min],0
mov w[cs:offset y_max],199
mov w[cs:offset y_min],0
mov w[cs:offset user_mask],0
mov w[cs:offset user_subroutine],0
mov w[cs:offset user_subroutine+2],0
mov ax,0ffffh
mov bx,3
iret

_get_pos:
mov cx,word ptr cs:[offset pos_x]
mov dx,word ptr cs:[offset pos_y]
mov bx,word ptr cs:[offset buttons]
xor bh,bh
iret

_get_mouse_movement:
mov cx,word ptr cs:[offset x_move]
mov dx,word ptr cs:[offset y_move]
mov word ptr cs:[offset x_move],0
mov word ptr cs:[offset y_move],0
iret

_show_mouse:
push ax
push bx
push di
push es
mov byte ptr cs:[offset sm_flag],1
mov ax,word ptr cs:[offset pos_y]
shr ax,3
mov bl,80
mul bl
mov bx,word ptr cs:[offset pos_x]
shr bx,3
add ax,bx
shl ax,1
mov di,ax
mov ax,0b800h
mov es,ax
mov ax,word ptr es:[di]
mov cs:[offset save_char],ax
not ah
and ah,7fh
mov es:[di],ax
pop es
pop di
pop bx
pop ax
iret

_hide_mouse:
push ax
push bx
push di
push es
mov byte ptr cs:[offset sm_flag],0
mov ax,word ptr cs:[offset pos_y]
shr ax,3
mov bl,80
mul bl
mov bx,word ptr cs:[offset pos_x]
shr bx,3
add ax,bx
shl ax,1
mov di,ax
mov ax,0b800h
mov es,ax
mov ax,word ptr cs:[offset save_char]
mov word ptr es:[di],ax
pop es
pop di
pop bx
pop ax
iret

_set_pos:
mov cx,cs:[pos_x]
mov dx,cs:[pos_y]
mov w[cs:x_move],0
mov w[cs:y_move],0
iret

_set_hor_pos:
call max_min
mov cs:[x_min],cx
mov cs:[x_max],dx
cmp cs:[pos_x],cx
jge good_hor_min
mov cs:[pos_x],cx
good_hor_min:
cmp cs:[pos_x],dx
jle good_hor_max
mov cs:[pos_x],dx
good_hor_max:
iret

_set_ver_pos:
call max_min
mov cs:[y_min],cx
mov cs:[y_max],dx
cmp cs:[pos_y],cx
jge good_ver_min
mov cs:[pos_y],cx
good_ver_min:
cmp cs:[pos_y],dx
jle good_ver_max
mov cs:[pos_y],dx
good_ver_max:
iret

max_min:
cmp cx,dx
jle no_swap
xchg cx,dx
no_swap:
ret

_set_subroutines:
mov cs:[user_subroutine],dx
mov cs:[user_subroutine+2],es
mov cs:[user_mask],cx
iret

_swap_subroutines:
push w[cs:user_mask]
push w[cs:user_subroutine+2]
push w[cs:user_subroutine]
mov cs:[user_subroutine],dx
mov cs:[user_subroutine+2],es
mov cs:[user_mask],cx
pop dx
pop es
pop cx
iret

end_of_tsr:
end
-----------8<----------

Try to understand what it does...

Rick C. Hodgin

ungelesen,
26.01.2001, 12:37:3026.01.01
an

You really need to get a book on programming PS/2 mice and not rely on
other people's code.

The command 0D4h tells the controller that the next data item is not
going to the keyboard but rather going to the nice. They share the
same ports, the only difference is the protocols used to communicate
with them.

- Rick C. Hodgin

Rick C. Hodgin

ungelesen,
26.01.2001, 12:37:3126.01.01
an

>no, u don't have to tell PIC anything, if you just mask/unmask an IRQ.

You're not telling the PIC. You're telling the device itself to
generate interrupts. PS/2 mouses, like the keyboard controller
they're mated with, have a single bit which indicates whether or not
they are to signal their IRQ12 each time they have data to send. That
must be enabled for the mouse to work.

- Rick C. Hodgin

0 neue Nachrichten