Newsgroup: it.comp.programmare
Titolo: Mouse

Qualcuno sa programmare a basso livello il mouse? Mi spiego meglio: vorrei
fare in modo da utilizzare il mouse senza aver bisogno di caricare drivers,
o di supportarmi al sistema operativo. Qualcuno puņ aiutarmi, magari con
qualche esempio in Assembly?
Grazie.

fare in modo da utilizzare il mouse senza aver bisogno di caricare drivers
Su che dispositivo? Seriale o PS/2?
E che modello di mouse? Mouse Systems, Logitech, MS 1, MS 2?
Forse ti conviene il driver ;-)
Leonardo
".signature": bad command or file name

 wrote in message
fukrts8rv66gs0dq3...@4ax.com...

E' vero, chiedo scusa: un mouse seriale di qualsiasi tipo (però preferirei
MS 1)
Si, in effetti mi converrebbe il driver, ma non per quel che voglio fare io.

MS 1)
Allora c'era un mio amico (e' un po' che non ci si sente, tra l'altro),
mi pare avesse come mail 
gpa...@usa.net
, che aveva scritto un driver in
assembly e C per Microsoft Mouse 1 seriale :-)
Anzi, visto che quei sorgenti ce li ho anch'io, e che nel sorgente c'e'
scritto quel che c'e' scritto...
...mi sono permesso di cancellare l'indirizzo e il numero di telefono -
che tanto non sono piu' quelli.
/*
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º Project: C Mouse Driver
º
º Version: 0.1á
º
º Date: 28/06/95
º
º File: mouse.c
º
º
º
º Author: Giovanni Pagni
º
º
º
ÇÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¶
º 28/06/95 ³ Work start. Written serial.h
º
º          ³ Functions: Test_Mouse, Find_Mouse
º
º 29/06/95 ³ Working on Find_Mouse
º
º          ³ Started: Mouse_Setup, Mouse_Reset, Mouse_End, Mouse_Isr
º
º          ³
º
º          ³
º
ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼
*/
/*
  Questo codice puo` essere utilizzato da chiunque (anche ditte) a
condizione
  che nella documentazione o nei credits del programma finale sia
incluso il
  mio nome. Inoltre se questo codice viene modificato gradirei ricevere
il
  sorgente delle modifiche apportate.
  La variabile Ports contiene la definizione di 4 porte seriali da
testare.
  La variabile Mouse contiene le info sul mouse.
  Mi scuso per la scarsa documentazione del codice, ma e` stato scritto
in una
  giornata.
  Il codice e` stato testato solo sul mio computer:
    486DX 50Mhz
    3 seriali (COM1,IRQ4)(COM2,IRQ3)(COM3,IRQ9)
  Per il testing ho usato il Borland Turbo C ver 2.0
  cambiando i define iniziali sara` facile adattarlo ad altri
compilatori.
  Attenzione! Non funziona nella DOS Box di Os/2.
  Funziona anche se c'e` presente un mouse driver, forse pero`
all'uscita
  potrebbe essere opportuno resettare il driver tramite una chiamata
  all'int 33 (ax=0000 se non erro).
*/
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#define WORD   unsigned int
#define I_PORT (WORD)inp
#define O_PORT outp
#define GETVECTOR   getvect
#define SETVECTOR   setvect
#define DISABLE     disable()
#define ENABLE      enable()
#define MASK(x,y)        O_PORT((x),I_PORT((x))|(y))
#define UNMASK(x,y)      O_PORT((x),I_PORT((x))&(~(y)))
#include "serial.h"
#include "mouse.h"
struct Port Ports[4]={ { 0x03f8,12,  I_COM1,MRCI },
                       { 0x02f8,11,  I_COM2,MRCI },
                       { 0x03e8,0x71,I_IRQ9,SRCI },
                       { 0x02e8,11,  I_COM2,MRCI } };
/* Globals    */
int                 Valid=FALSE;
WORD                Addr;
int                 Vector;
int                 Pic;
unsigned char       Mask;
void (interrupt far *OldInt)(void);
volatile struct MouseEvent   Mouse;
volatile unsigned char far *Timer=MK_FP(0x0000,0x046c);
int Find_Mouse()
{
    int i;
    Valid=FALSE;
    for(i=0;!Test_Mouse(Ports[i].Address) && i<4 ;i++);
    if(i<4)
    {
        Addr=Ports[i].Address;
        Vector=Ports[i].Vector;
        Mask=Ports[i].Mask;
        Pic=Ports[i].Pic;
	  Valid=TRUE;
    }
#ifdef MOUSEFOUND
    if(i==0)
          printf("\nMouse found on COM1\n");
    if(i==1)
          printf("\nMouse found on COM2\n");
    if(i==2)
	  printf("\nMouse found on COM3\n");
    if(i==3)
          printf("\nMouse found on COM4\n");
#endif
    return (i<4);
}
int Test_Mouse(int PortAddr)
{
    WORD    divisor,lcr,mcr,ier;
    unsigned char lap;
    register WORD  count;
    unsigned char received;
    ier=I_PORT(IER(PortAddr));      /* save IER */
    O_PORT(IER(PortAddr),NO_AB);
    lcr=I_PORT(LCR(PortAddr));
    O_PORT(LCR(PortAddr),SETBAUD);
    divisor=I_PORT(DBRL(PortAddr))+(I_PORT(DBRM(PortAddr))<<8);
    O_PORT(DBRL(PortAddr),0x60);
    O_PORT(DBRM(PortAddr),0x00);
    O_PORT(LCR(PortAddr),BITS7);
    mcr=I_PORT(MCR(PortAddr));
    O_PORT(MCR(PortAddr),DTR);
    for(lap=*Timer+0x05;*Timer<lap;);
    O_PORT(MCR(PortAddr),DTR|RTS|OUT2);
    count=0;
    received=2;
    while(--count && received)
    {
        if(I_PORT(LSR(PortAddr))&L_DR)
	    if(I_PORT(RXT(PortAddr))==0x4d)
                received--;
    }
    O_PORT(MCR(PortAddr),mcr);
    O_PORT(LCR(PortAddr),SETBAUD);
    O_PORT(DBRL(PortAddr),divisor & 0xff);
    O_PORT(DBRM(PortAddr),divisor >> 8);
    O_PORT(LCR(PortAddr),lcr);
    O_PORT(IER(PortAddr),ier);
    return (int)(received<2);
}
int Mouse_Setup(int xMax,int yMax)
{
    if(!Valid) return FALSE;
    DISABLE;
    UNMASK(MRMI,I_IRQ2);
    O_PORT(IER(Addr),NO_AB);
    OldInt=GETVECTOR(Vector);
    SETVECTOR(Vector,Mouse_Isr);
    MASK(Pic+1,Mask);
    ENABLE;
    Mouse.xMax=xMax;
    Mouse.yMax=yMax;
    Mouse.xPos=xMax/2;
    Mouse.yPos=yMax/2;
    Mouse.Button=0;
    if(Mouse_Reset()) return TRUE;
    DISABLE;
    SETVECTOR(Vector,OldInt);
    ENABLE;
    return FALSE;
}
int Mouse_Reset()
{
    register WORD  count;
    unsigned char received;
    unsigned char lap;
    O_PORT(IER(Addr),NO_AB);
    O_PORT(LCR(Addr),SETBAUD);
    O_PORT(DBRL(Addr),0x60);
    O_PORT(DBRM(Addr),0x00);
    O_PORT(LCR(Addr),BITS7);
    O_PORT(MCR(Addr),DTR);
    for(lap=*Timer+0x05;*Timer<lap;);
    O_PORT(MCR(Addr),DTR|RTS|OUT2);
    count=0;
    received=2;
    while(--count && received)
    {
        if(I_PORT(LSR(Addr))&L_DR)
            if(I_PORT(RXT(Addr))==0x4d)
                received--;
    }
    if(received<2)
    {
        O_PORT(IER(Addr),AB_LINE|AB_RX);
        UNMASK(Pic+1,Mask);
	  count=I_PORT(RXT(Addr));
        return TRUE;
    }
    return FALSE;
}
int Mouse_End()
{
    if(!Valid) return FALSE;
    DISABLE;
    UNMASK(MRMI,I_IRQ2);
    O_PORT(IER(Addr),NO_AB);
    SETVECTOR(Vector,OldInt);
    MASK(Pic+1,Mask);
    ENABLE;
    return TRUE;
}
void interrupt far Mouse_Isr(void)
{
    static int              ix=0;
    static char             buffer[4];
    static int              flag=0;
    WORD                    iir;
    register int            temp;
    if(flag) return;
    if(!((iir=I_PORT(IIR(Addr)))&NO_INT))
    {
        flag++;
        switch(iir&ID_MASK)
        {
            case ID_RX:
                if(((temp=(char)I_PORT(RXT(Addr)))&0x40))
                    buffer[0]=temp,ix=1;
                else
                {
                    buffer[ix++]=temp;
                    if(ix==3)
                    {
                        Mouse.Button=(buffer[0]&0x30)>>4;
                        Mouse.yPos+=((int)((signed
char)((buffer[0]<<4)&0xc0)))|(int)buffer[2];
                        Mouse.xPos+=((int)((signed
char)((buffer[0]<<6)&0xc0)))|(int)buffer[1];
                        if(Mouse.xPos>Mouse.xMax) Mouse.xPos=Mouse.xMax;
                        if(Mouse.xPos<0) Mouse.xPos=0;
                        if(Mouse.yPos<0) Mouse.yPos=0;
                        if(Mouse.yPos>Mouse.yMax) Mouse.yPos=Mouse.yMax;
                        ix=0;
                    }
                }
            case ID_ERR:
                if(I_PORT(LSR(Addr))&L_OE)
                    ix=0;
        }
        flag--;
    }
    O_PORT(Pic,END_OF_I);
    if(Pic!=MRCI)
        O_PORT(MRCI,END_OF_I);
}
#ifdef MOUSETEST
int main(void)
{
    Find_Mouse();
    Mouse_Setup(640,320);
    while(!kbhit())
    {
        printf("%0.2X %0.4d %0.4d %0.4d
%0.4d\r",Mouse.Button,Mouse.xPos,
                                                 Mouse.yPos,Mouse.xMax,
                                                 Mouse.yMax);
    }
    Mouse_End();
    return TRUE;
}
#endif
Include
/*
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º Project: C Mouse Driver
º
º Version: 0.1á
º
º Date: 28/06/95
º
º File: serial.h (header)
º
º
º
º Author: Giovanni Pagni
º
º
º
ÇÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¶
º 28/06/95 ³ Work start. Written serial.h
º
º          ³
º
º          ³
º
ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼
*/
/*************************************************************************
Porta seriale RS232C
    pin 	logico			sigla
( 8)	1	Carrier Detect		CD	<-
( 3)	2	Received Data		Rx	<-
( 2)	3	Transmitted Data	Tx	->
(20)	4	Data Terminal Ready	DTR	->
( 7)	5	Signal Ground		GND	<>
( 6)	6	Data Set Ready		DSR	<-
( 4)	7	Request To Send 	RTS	->
( 5)	8	Clear to		CTS	<-
(22)	9	Ring Indicator		RI	<-
**************************************************************************
controllore di interrupt 8259
     Puo' essere gestito attraverso due porte di 8 bit:
20h -> MRCI- Master - Registro Comandi Interruzioni;
21h -> MRMI- Master - Registro Maschera Interruzioni.
A0h -> SRCI- Slave - Registro Comandi interruzioni;
A1h -> SRMI- Slave - Registro Maschera Interruzioni.
**************************************************************************
--- MRMI ---		  [il livello 0 abilita l'interruzione]
|0|- Timer			0
|1|- Tastiera			0
|2|- Display/Cascade		0
|3|- Seriale (COM2/COM4)
|4|- Seriale (COM1/COM3)
|5|- LPT2/Sound 		1
|6|- Floppy Disks		0
|7|- LPT1			1
*************************************************************************
--- SRMI ---		  [il livello 0 abilita l'interruzione]
|0|- Real Time Clock		0
|1|- IRQ2/IRQ9
|2|- IRQ10
|3|- IRQ11			1
|4|- IRQ12			1
|5|- IRQ13/Coprocessor		0
|6|- IRQ14/Hard Disks		0
|7|- IRQ15			1
*************************************************************************/
#define MRMI	  0x0021
#define SRMI	  0x00A1
#define I_IRQ0	  0x0001
#define I_IRQ1	  0x0002
#define I_IRQ2	  0x0004
#define I_IRQ3	  0x0008
#define I_IRQ4	  0x0010
#define I_IRQ5	  0x0020
#define I_IRQ6	  0x0040
#define I_IRQ7	  0x0080
#define I_IRQ8	  0x0001
#define I_IRQ9	  0x0002
#define I_IRQ10   0x0004
#define I_IRQ11   0x0008
#define I_IRQ12   0x0010
#define I_IRQ13   0x0020
#define I_IRQ14   0x0040
#define I_IRQ15   0x0080
#define I_TIMER   I_IRQ0
#define I_KEY	  I_IRQ1
#define I_COM2	  I_IRQ3
#define I_COM1	  I_IRQ4
#define I_LPT2	  I_IRQ5
#define I_FLOPPY  I_IRQ6
#define I_LPT1	  I_IRQ7
#define I_RTC	  I_IRQ8
#define I_80X87   I_IRQ13
#define I_HDC	  I_IRQ14
/*************************************************************************
--- RCI ---
     L'unico modo di impiego di cui sono venuto a conoscenza
consiste  nella  segnalazione di END_OF_INTERRUPT  che	deve
essere effettuata al termine della  gestione  dell'interrupt
mediante la scrittura alla porta 20H del valore 20H.
*************************************************************************/
#define MRCI	  0x0020
#define SRCI	  0x00A0
#define END_OF_I  0x0020
/*************************************************************************
UART 8250
     E' programmabile mediante 7 porte di 8 bit che  assumono
significati logici diversi asseconda delle configurazioni:
--- 3fbH - LCR - Registro Controllo di Linea [out] ---
			  | 00 -- 5 bit
|0|-|			  | 01 -- 6 bit
|-| | lunghezza carattera | 10 -- 7 bit
|1|-|			  | 11 -- 8 bit
|-|			  |- 0 -|   1  bit
|2| - bit di stop --------|- 1 -|- 1.5 bit se RCL.0 = 0
|-|				|-  2  bit se RCL.0 = 1
|3| - parita' ------------|- 0 bit di parita' non generato
|-|			  |- 1 generazione bit di parita'
|4| - tipo parita' -------|- 0 dispari
|-|			  |- 1 pari
|5| - test parita' -------|- 0 non abilitata (default)
|-|			  |- 1 bit di parita' = NOT (RCL.4)
|6| - break --------------|- 0 non abilitato (default)
|-|			  |- 1 forza in uscita il valore 0
|7| - indirizzamento -----|- 0 porta 3f8H - RXT  -; 3f9H - ABI
			  |- 1 porta 3f8H - DBRL -; 3f9H - DBRH
**************************************************************************
   3B= 0011 1011: ABI,NObreak,test parita',pari,generata,1stop,8bits
   BB= 1011 1011: DBR,NObreak,test parita',pari,generata,1stop,8bits
*************************************************************************/
#define LCR(x)	    ((x)+0x03)
#define SETBAUD       0x0080
#define DLAB	    SETBAUD
#define BITS5	    0x0000
#define BITS6	    0x0001
#define BITS7	    0x0002
#define BITS8	    0x0003
#define STOP1	    0x0000
#define STOP2	    0x0004
#define PARITY	    0x0008
#define EVEN	    0x0010
#define ODD	    0x0000
#define STICK	    0x0020
#define BREAK	    0x0040
/*************************************************************************
--- 3fcH - MCR - Registro Controllo Modem [out] ---
     [Deve essere settato anche in assenza del modem.]
|0|- 1		attivazione DTR (Data Terminal Ready)
|1|- 1		attivazione RTS (Request TO Send)
|2|- 0		non utilizzato
|3|- 1		interrupt verso 8259;		0 interrupt bloccate
|4|- 0		funzionamento normale;		1 UART cortocircuitata;
|5|- 0		non utilizzato
|6|- 0		non utilizzato
|7|- 0		non utilizzato
*************************************************************************/
#define MCR(x)	    ((x)+0x04)
#define DTR	          0x0001
#define RTS	          0x0002
#define OUT1	    0x0004
#define OUT2	    0x0008
#define LOOP	    0x0010
/*************************************************************************
--- 3f9H - IER - ABilitazione Interrupt [out] - [ 1 indica
abilitazione.]
     [E' indirizzabile quando RCL.7 = 0]
					     PRIORITA'
|0|- Dato Ricevuto				  [2]
|1|- Trasmettitore Vuoto			  [3]
|2|- Errore Dato Ricevuto / condizione di Break   [1]
|3|- Cambiamento Stato del Modem		  [4]
|4|- 0 non utilizzato
|5|- 0 non utilizzato
|6|- 0 non utilizzato
|7|- 0 non utilizzato
*************************************************************************/
#define IER(x)		((x)+0x01)
#define NO_AB		0x0000
#define AB_RX		0x0001
#define AB_TX		0x0002
#define AB_RX_TX	0x0003
#define AB_LINE 	0x0004
#define AB_MODEM	0x0008
/*************************************************************************
--- 3faH - IIR - IDentificazione Interrupt [in] ---
			  |  0 Interrupt in attesa
|0|-----------------------|  1 Interrupt servite
|1|-----------------------| 00 Cambiamento Stato Modem
|2|-----------------------| 01 Trasmettitore Vuoto
|3|- 0 non utilizzato	  | 10 Dato Pronto
|4|- 0 non utilizzato	  | 11 Errore in Ricezione /Break
|5|- 0 non utilizzato
|6|- 0 non utilizzato
|7|- 0 non utilizzato
*************************************************************************/
#define IIR(x)	    ((x)+0x02)
#define NO_INT      0x0001
#define ID_MODEM    0x0000
#define ID_TX       0x0002
#define ID_RX       0x0004
#define ID_ERR      0x0006
#define ID_MASK     0x0006
/*************************************************************************
--- 3feH - MSR - Registro Stato Modem [in] - [Lo Stato esiste se bit a
1]
     [IL FETCH DA 'RSM' RESETTA AUTOMATICAMENTE SATO E INTERRUPT
(IDI.1)]
|0|- cambiato clear to send		\
|1|- cambiato data set ready		\ cambiamenti di stato
|2|- cambiato ring indicator		\
|3|- cambiato data carrier detect	\
|4|- clear to send			/
|5|- data set ready			/ stato del modem
|6|- ring indicator			/
|7|- data carrier detect		/
*************************************************************************/
#define MSR(x)      ((x)+0x06)
#define M_DCTS      0x0001
#define M_DDSR      0x0002
#define M_DRING     0x0004
#define M_DDCD      0x0008
#define M_CTS       0x0010
#define M_DSR       0x0020
#define M_RING      0x0040
#define M_DCD       0x0080
/*************************************************************************
--- 3fdH - LSR - Registro Stato Linea [in] -    [Il livello 1 indica
TRUE.]
[IL FETCH DA 'RSL' RESETTA AUTOMATICAMENTE STATO E INTERRUPT
(IDI.1,IDI.2)]
|0|- Dato Ricevuto
|1|- Errore di Sovrapposizione
|2|- Errore di Parita'
|3|- Errore di Framing
|4|- Presenza di Break
|5|- Trasmettitore Vuoto
|6|- Shifter di Trasmissione Vuoto
|7|- Time Out Scaduto
*************************************************************************/
#define LSR(x)      ((x)+0x05)
#define L_DR        0x0001
#define L_OE        0x0002
#define L_PE        0x0004
#define L_FE        0x0008
#define L_BREAK     0x0010
#define L_TX        0x0020
#define L_TE        0x0040
/*************************************************************************
--- 3f8H - RXT - Registro Ricezione Trasmissione [in/out] ---
	     [E' indirizzabile quando RCL.7 = 0]
*************************************************************************/
#define RXT(x)      ((x))
/*************************************************************************
--- 3f8H - DBRL - Divisore Baud Rate Less sign. byte [out] ---
	     [E' indirizzabile quando RCL.7 = 1]
*************************************************************************/
#define DBRL(x)     ((x))
/*************************************************************************
--- 3f9H - DBRM - Divisore Baud Rate Most sign. byte [out] ---
	     [E' indirizzabile quando RCL.7 = 1]
*************************************************************************/
#define DBRM(x)     ((x)+0x01)


 wrote:
Grazie