Subject: Re: A3 mouse patches
To: David Bushong <dbushong@cory.EECS.Berkeley.EDU>
From: Colin Wood <ender@is.rice.edu>
List: port-mac68k
Date: 05/08/1997 13:25:19
> Doing a little browsing through the mailing lists, I noted that at one
> point someone (Colin Wood, I believe) happened to have written kernel
> patches to allow A3 mice to work.  I have a MacPoint Pro and was curious
> whether the same code might apply (as I believe they use the same MacOS
> driver)  Does anyone happen to know if the patches are still around, where
> I could get them, and if they work with current -current sources?

I don't know whether or not my patches will work with a MacPoint Pro or
not, but you can feel free to try them.  The patches still apply cleanly
to -current sources, but since my mouse is currently broken, I'm not sure
whether or not the patches actually work under John's new code.

Below is a copy of my patches to get a Mouse System's A^3 mouse working
under NetBSD.

I hope this helps.

Later.

-- 
Colin Wood                                      ender@is.rice.edu
Consultant                                        Rice University
Information Technology Services                       Houston, TX

file: adbMSA3MOUSE.patch
*** adb.c.orig	Thu Apr 10 15:38:16 1997
--- adb.c	Thu Apr 10 15:38:29 1997
***************
*** 333,338 ****
--- 333,345 ----
  			else
  				buttons = (event->bytes[0] & 0x80) ? 0 : 1;
  			break;
+ 		case ADBMS_MSA3:
+ 			/* Mouse Systems A3 mouse */
+ 			if (max_byte == 3)
+ 				buttons = (~event->bytes[2]) & 0x07;
+ 			else
+ 				buttons = (event->bytes[0] & 0x80) ? 0 : 1;
+ 			break;
  		default:
  			/* Classic Mouse Protocol (up to 2 buttons) */
  			for (i = 0; i < 2; i++, button_bit <<= 1)
*** adbsys.c.orig	Thu Apr 10 15:38:15 1997
--- adbsys.c	Thu Apr 10 15:38:29 1997
***************
*** 87,92 ****
--- 87,133 ----
  	adb_processevent(&event);
  }
  
+ void 
+ adb_msa3_complete(buffer, data_area, adb_command)
+ 	caddr_t buffer;
+ 	caddr_t data_area;
+ 	int adb_command;
+ {
+ 	adb_event_t event;
+ 	ADBDataBlock adbdata;
+ 	int adbaddr;
+ 	int error;
+ #ifdef MRG_DEBUG
+ 	register int i;
+ 
+ 	printf("adb: transaction completion\n");
+ #endif
+ 
+ 	adbaddr = (adb_command & 0xf0) >> 4;
+ 	error = GetADBInfo(&adbdata, adbaddr);
+ #ifdef MRG_DEBUG
+ 	printf("adb: GetADBInfo returned %d\n", error);
+ #endif
+ 
+ 	event.addr = adbaddr;
+ 	event.hand_id = ADBMS_MSA3;
+ 	event.def_addr = adbdata.origADBAddr;
+ 	event.byte_count = buffer[0];
+ 	memcpy(event.bytes, buffer + 1, event.byte_count);
+ 
+ #ifdef MRG_DEBUG
+ 	printf("adb: from %d at %d (org %d) %d:", event.addr,
+ 		event.hand_id, event.def_addr, buffer[0]);
+ 	for (i = 1; i <= buffer[0]; i++)
+ 		printf(" %x", buffer[i]);
+ 	printf("\n");
+ #endif
+ 
+ 	microtime(&event.timestamp);
+ 
+ 	adb_processevent(&event);
+ }
+ 
  static volatile int extdms_done;
  
  /*
***************
*** 153,158 ****
--- 194,200 ----
  			while (!extdms_done)
  				/* busy wait until done */;
  
+ 			/* Attempt to initialize Extended Mouse Protocol */
  			buffer[2] = '\004'; /* make handler ID 4 */
  			extdms_done = 0;
  			cmd = (cmd & 0xf3) | 0x08; /* listen command */
***************
*** 160,165 ****
--- 202,257 ----
  			      (Ptr)&extdms_done, cmd);
  			while (!extdms_done)
  				/* busy wait until done */;
+ 
+ 			/* Check to see if successful, if not
+ 			 * try to initialize it as other types */
+ 			cmd = ((adbaddr << 4) & 0xf0) | 0x3;
+ 			extdms_done = 0;
+ 			cmd = (cmd & 0xf3) | 0x0c; /* talk command */
+ 			ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ 			      (Ptr)&extdms_done, cmd);
+ 			while (!extdms_done)
+ 				/* busy wait until done */;
+ 				
+ 			if (buffer[2] != ADBMS_EXTENDED) {
+ 				/* Attempt to initialize as an A3 mouse */
+ 				buffer[2] = 0x03; /* make handler ID 3 */
+ 				extdms_done = 0;
+ 				cmd = (cmd & 0xf3) | 0x08; /* listen command */
+ 				ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ 				      (Ptr)&extdms_done, cmd);
+ 				while (!extdms_done)
+ 					/* busy wait until done */;
+ 		
+ 				/* Check to see if successful, if not
+ 				 * try to initialize it as other types */
+ 				cmd = ((adbaddr << 4) & 0xf0) | 0x3;
+ 				extdms_done = 0;
+ 				cmd = (cmd & 0xf3) | 0x0c; /* talk command */
+ 				ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ 				      (Ptr)&extdms_done, cmd);
+ 				while (!extdms_done)
+ 					/* busy wait until done */;
+ 					
+ 				if (buffer[2] == ADBMS_MSA3) {
+ 					/* Initialize as above */
+ 					cmd = ((adbaddr << 4) & 0xF0) | 0xA;
+ 					/* listen 2 */
+ 					buffer[0] = 3;
+ 					buffer[1] = 0x00;
+ 					/* Irrelevant, buffer has 0x77 */
+ 					buffer[2] = 0x07;
+ 					/* enable 3 button mode = 0111b,
+ 					 * speed = normal */
+ 					extdms_done = 0;
+ 					ADBOp((Ptr)buffer, (Ptr)extdms_complete,
+ 					      (Ptr)&extdms_done, cmd);
+ 					while (!extdms_done)
+ 						/* busy wait until done */;
+ 				} else {
+ 					/* No special support for this mouse */
+ 				}
+ 			}
  		}
  	}
  }
***************
*** 254,259 ****
--- 346,354 ----
  			case ADBMS_200DPI:
  				printf("200 dpi mouse");
  				break;
+ 			case ADBMS_MSA3:
+ 				printf("Mouse Systems A3 mouse, default parameters");
+ 				break;
  			case ADBMS_USPEED:
  				printf("MicroSpeed mouse, default parameters");
  				break;
***************
*** 294,300 ****
  		printf(" at %d\n", adbaddr);
  
  		/* Set completion routine to be MacBSD's */
! 		adbinfo.siServiceRtPtr = (Ptr) adb_asmcomplete;
  		adbinfo.siDataAreaAddr = NULL;
  		error = SetADBInfo(&adbinfo, adbaddr);
  #ifdef MRG_DEBUG
--- 389,402 ----
  		printf(" at %d\n", adbaddr);
  
  		/* Set completion routine to be MacBSD's */
! 		if ((adbdata.origADBAddr == ADBADDR_REL) && 
! 		    (buffer[0] > 0) && (buffer[2] == ADBMS_MSA3)) {
! 			/* Special device handler for the A3 mouse */
! 			adbinfo.siServiceRtPtr = (Ptr)adb_msa3_asmcomplete;
! 		} else {
! 			/* Default completion routine */
! 			adbinfo.siServiceRtPtr = (Ptr)adb_asmcomplete;
! 		}
  		adbinfo.siDataAreaAddr = NULL;
  		error = SetADBInfo(&adbinfo, adbaddr);
  #ifdef MRG_DEBUG
*** adbsys.h.orig	Thu Apr 10 15:38:49 1997
--- adbsys.h	Thu Apr 10 15:38:04 1997
***************
*** 97,102 ****
--- 97,103 ----
  #define ADB_PBKBD	12
  #define ADBMS_100DPI	1
  #define ADBMS_200DPI	2
+ #define ADBMS_MSA3	3	/* Mouse Systems A3 Mouse */
  #define ADBMS_EXTENDED	4
  #define ADBMS_USPEED	47	/* MicroSpeed mouse */
  
*** adbsysasm.s.orig	Thu Apr 10 15:38:15 1997
--- adbsysasm.s	Thu Apr 10 15:38:50 1997
***************
*** 63,68 ****
--- 63,82 ----
  	moveml	sp@+, #0x0303	| restore scratch regs
  	rts
  
+ /* This routine is called when an A3 mouse has sent us some data. */
+ /* (provided it has been set up with SetADBInfo) */
+ 	.global	_adb_msa3_asmcomplete
+ _adb_msa3_asmcomplete:
+ 	moveml	#0xc0c0, sp@-	| save scratch regs
+ 	movl	d0, sp@-	/* ADB command byte */
+ 	movl	a2, sp@-	/* data area pointer */
+ 	/*	a1 is the pointer to this routine itself. */
+ 	movl	a0, sp@-	/* device data buffer */
+ 	jbsr	_adb_msa3_complete
+ 	addl	#12, sp		/* pop params */
+ 	moveml	sp@+, #0x0303	| restore scratch regs
+ 	rts
+ 
  _adb_jadbprochello:
  	.asciz	"adb: hello from adbproc\n"
  	.even
*** adbvar.h.orig	Thu Apr 10 15:38:15 1997
--- adbvar.h	Thu Apr 10 15:38:50 1997
***************
*** 45,51 ****
  extern adb_trace_xlate_t adb_trace_xlations[];
  
  /* adb.c */
- void    adb_asmcomplete __P((void));
  void	adb_enqevent __P((adb_event_t *event));
  void	adb_handoff __P((adb_event_t *event));
  void	adb_autorepeat __P((void *keyp));
--- 45,50 ----
***************
*** 59,69 ****
  int	adbioctl __P((dev_t , int , caddr_t , int , struct proc *));
  int	adbpoll __P((dev_t dev, int events, struct proc *p));
  
! /* adbsysadm.s */
  void	extdms_complete __P((void));
  
  /* adbsys.c */
  void	adb_complete __P((caddr_t buffer, caddr_t data_area, int adb_command));
  void	extdms_init __P((int));
  
  #ifndef MRG_ADB
--- 58,71 ----
  int	adbioctl __P((dev_t , int , caddr_t , int , struct proc *));
  int	adbpoll __P((dev_t dev, int events, struct proc *p));
  
! /* adbsysasm.s */
! void	adb_asmcomplete __P((void));
! void	adb_msa3_asmcomplete __P((void));
  void	extdms_complete __P((void));
  
  /* adbsys.c */
  void	adb_complete __P((caddr_t buffer, caddr_t data_area, int adb_command));
+ void	adb_msa3_complete __P((caddr_t buffer, caddr_t data_area, int adb_command));
  void	extdms_init __P((int));
  
  #ifndef MRG_ADB