; ; File: Mouse.a ; ; Contains: routines related to the mouse ; ; Written by: Steve Horowitz & Francis Stanbach ; ; Copyright: © 1990 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; <7> 1/13/91 dba (KIP) add fix for old key repeat bugs in the Macintosh Plus ROM; ; specifically, be sure that KeyThresh and KeyRepThresh do not ; have 0s in them ; <6> 7/10/90 dba Oops! Frank forgot to export MTable and he didn’t test it (my ; fault, I was with him at the time). ; <5> 7/10/90 fjs more cleanup related to Darin ; <4> 5/19/90 fjs more cleanup related to Darin ; <3> 5/16/90 dba work on it more (tag-team programming) ; <2> 5/16/90 fjs add more comments for Captain Van Eye Patch ; <1> 5/16/90 fjs Annette sure was cute ; 5/15/90 fjs That's right I'm writing this code ; ; To Do: ; load 'StandardEqu.d' include 'LinkedPatchMacros.a' MGlobals record 0 ; mouse mapping globals data structure Count ds.w 1 ; word: number of valid error deltas MaxCnt ds.w 1 ; word: limit on number of error deltas Err7 ds.w 1 ; word: time-7 error magnitude Err6 ds.w 1 ; word: time-6 error magnitude Err5 ds.w 1 ; word: time-5 error magnitude Err4 ds.w 1 ; word: time-4 error magnitude Err3 ds.w 1 ; word: time-3 error magnitude Err2 ds.w 1 ; word: time-2 error magnitude Err1 ds.w 1 ; word: time-1 error magnitude Error ds.w 1 ; word: accumulated error GSize equ * ; size of regular globals Table ds.b 8 ; mickey bytes table TotalSize equ * ; size endr ;———————————————————————————————————————————————————————————————————————————————————————————————————— ; initialize the mouse mapping table PlusMouseInit InstallProc (Plus) import MickeyBytesHelper import MTable ; since the Plus boot code sometimes leaves KeyThresh and KeyRepThresh 0, check for that case. tst.w KeyRepThresh bne.s KeyRepThreshOK move.w #$48*2,KeyRepThresh ; stuff same value used by modern boot code KeyRepThreshOK tst.w KeyThresh bne.s KeyThreshOK move.w #$1FFF<<2,KeyThresh ; stuff same value used by modern boot code KeyThreshOK lea MTable,a2 ; load pointer to table in a2 jmp MickeyBytesHelper endproc ADBMouseInit InstallProc (SE,II,Portable,IIci) import MickeyBytesHelper move.l MickeyBytes,a2 ; get ptr to globals add #MGlobals.Table,a2 ; point past globals to table jmp MickeyBytesHelper endproc MickeyBytesHelper proc ; get the value in PRAM moveq #$78,d0 ; mask off the appropriate bits and.b SPVolCtl,d0 ; of value from PRAM lsr.b #3,d0 ; gets resource # to load ; attempt to get the resource from system file subq #4,sp ; room for ResHandle move.l #'mcky',-(sp) ; Mickey Mouse Tracking bytes move.w d0,-(sp) ; gives us our ID _GetResource move.l (sp)+,d0 ; get handle into d0 beq.s noBytes ; we didn't get one, use default move.l d0,a0 ; get handle in a0 move.l (a0),a0 ; source = mickey bytes bra.s gotMickey ; install the bytes (should this be 'rts' ?) noBytes lea default, a0 ; use the default bytes ; make it default to 2 if there is no resource and.b #87,SPVolCtl ; mask off old setting ori.b #(2<<3),SPVolCtl ; and OR it in PRAM gotMickey move.l (a0)+,(a2)+ ; move the bytes in move.l (a0),(a2) rts default dc.b 4, 10, 15, 255, 255, 255, 255, 255 ENDPROC ;———————————————————————————————————————————————————————————————————————————————————————————————————— ; Mouse Mapping code for Mac Plus ROMs Plus MakePatch MapCode,jCrsrTask MouseMapping PROC EXPORT MapCode EXPORT MTable ; This signature is so that the Mouse control panel can recognize this lovely CrsrTask. ; It is probably completely unnecessary; at the very least we could do something shorter. STRING ASIS Signature dc.b 'Horowitz' ; isn’t that special Globals ; define these as constants instead of storage so that you can give them ; initial values without explicitly initializing them. Is this cheezy or ; genius ? <15may90 fjs> mCount dc.w 1 ; word: number of valid error deltas mMaxCnt dc.w 1 ; word: limit on number of error deltas mErr7 dc.w 0 ; word: time-7 error magnitude mErr6 dc.w 0 ; word: time-6 error magnitude mErr5 dc.w 0 ; word: time-5 error magnitude mErr4 dc.w 0 ; word: time-4 error magnitude mErr3 dc.w 0 ; word: time-3 error magnitude mErr2 dc.w 0 ; word: time-2 error magnitude mErr1 dc.w 0 ; word: time-1 error magnitude mError dc.w 0 ; word: accumulated error mTable dc.b 0,0,0,0,0,0,0,0 ; mickey bytes table (some day put default values here?) with MGlobals MapCode tst.b CrsrNew ; Mouse changed? beq Done ; No … return tst.b CrsrBusy ; Cursor locked? bne Done ; Yes … return tst.b CrsrCouple ; Cursor coupled to mouse? beq NoComp ; No … skip computation move.w MTemp+H,D0 ; Find ∆Mx sub.w RawMouse+H,D0 move.w MTemp+V,d1 ; Find ∆My sub.w RawMouse+V,d1 move.w d0,d2 ; x := |∆Mx| bge.s AbsX neg.w d2 AbsX move.w d1,d3 ; y := |∆My| bge.s AbsY neg.w d3 AbsY cmp.w d2,d3 ; d3 := magnitude(x,y) bls.s magdone exg d2,d3 MagDone ASR.w #1,d3 add.w d2,d3 ; *** BEGIN NEW *** lea Globals,a0 ; Get my globals bne.s DoComp ; <03/07/87 EMT> move.w #1,Count(a0) ; No hits <03/07/87 EMT> clr.w Error(a0) ; No errors <03/07/87 EMT> BRA DoPin ; Redraw the cursor <03/07/87 EMT> DoComp ; <03/07/87 EMT> moveM.l d4-d5,-(A7) ; Save off registers move.w Count(a0),d4 ; d4 is the number of samples cmp.w MaxCnt(a0),d4 ; Is Count less than MaxCnt bge.s CountOK add.w #1,Count(a0) ; Yes … we will have one more error CountOK move.w d3,d5 ; Magnitude at current time move.w d4,d2 ; Get Count sub.w #1,d2 ; Index into JTab ASL.w #1,d2 ; REQUIRES bra.s’s IN JUMP TAbleS JMP JTab(PC,d2.w) ; Jump to the right code per Count JTab bra.s E1 ; Count = 1 bra.s E2 ; Count = 2 bra.s E3 ; Count = 3 bra.s E4 ; Count = 4 bra.s E5 ; Count = 5 bra.s E6 ; Count = 6 bra.s E7 ; Count = 7 ; *** bra.s E8 ; Count = 8 *** E8 add.w Err7(a0),d5 ; Accumulate time-7 magnitude E7 add.w Err6(a0),d5 ; Accumulate time-6 magnitude move.w Err6(a0),Err7(a0) ; Shift out time-6 magnitude E6 add.w Err5(a0),d5 ; Accumulate time-5 magnitude move.w Err5(a0),Err6(a0) ; Shift out time-5 magnitude E5 add.w Err4(a0),d5 ; Accumulate time-4 magnitude move.w Err4(a0),Err5(a0) ; Shift out time-4 magnitude E4 add.w Err3(a0),d5 ; Accumulate time-3 magnitude move.w Err3(a0),Err4(a0) ; Shift out time-3 magnitude E3 add.w Err2(a0),d5 ; Accumulate time-2 magnitude move.w Err2(a0),Err3(a0) ; Shift out time-2 magnitude E2 add.w Err1(a0),d5 ; Accumulate time-1 magnitude move.w Err1(a0),Err2(a0) ; Shift out time-1 magnitude E1 move.w d3,Err1(a0) ; Shift out current magnitude move.w d4,d2 ; Round up the divide ASR.w #1,d2 ; by half the denominator add.w d2,d5 EXT.l d5 ; Set up for the divide DIVU d4,d5 ; Find the average magnitude move.w d3,d4 ; Get the original magnitude sub.w d5,d3 ; Find distance to average magnitude add.w Error(a0),d3 ; add on the accumulated error cmp.w #-1,d3 ; Define -1 div 2 = 0 bne.s DivOK clr.w d3 DivOK ASR.w #1,d3 ; Get half of it move.w d3,Error(a0) ; Update it add.w d5,d3 ; Desired mag is average+Error cmp.w #255,d5 ; mag := MAX(mag,255) BLS.s MaxDone move.b #255,d5 MaxDone lea MTable,a0 ; address Table clr.w d2 ; i := 0 Search add.b #1,d2 ; repeat cmp.b (a0)+,d5 ; i := i+1 BHI.s Search ; until mag ≤ Table[i] muls d2,d3 ; d4 := i*(Mag(∆M)+Error) muls d3,d0 ; ∆Cx := (∆Mx*i*(Mag(∆M)+Error))/Mag(∆M) divs d4,d0 ; <<<<<< d3 >>>>>>> muls d3,d1 ; ∆Cy := (∆My*i*(Mag(∆M)+Error))/Mag(∆M) divs d4,d1 ; <<<<<< d3 >>>>>>> moveM.l (A7)+,d4-d5 ; Restore registers ; *** END NEW *** add.w d0,RawMouse+H ; Update raw mouse location add.w d1,RawMouse+V DoPin ; <03/07/87 EMT> lea CrsrPin,a0 ; Bounding rect for cursor move.l RawMouse,d0 ; Pin mouse inside rect BSR.s PinGuts move.l d0,RawMouse ; Update cursor locations move.l d0,MTemp AND.l MouseMask,d0 ; Do jerky masking to drop low bits move.l MouseOffset,d1 ; Get the offset beq.s SkipPin ; Skip 2nd pin if not add.l d1,d0 ; Do jerky offset BSR.s PinGuts ; Pin mouse inside rect again SkipPin move.l d0,Mouse ; Actual mouse location Repaint TST.b CrsrObscure ; Unpaint the cursor bne.s Unpainted _HideCursor ; Hide the cursor Unpainted clr.b CrsrNew ; Cursor is fresh clr.b CrsrObscure ; Cursor is not obscured _ShowCursor ; Repaint the cursor ; *** BEGIN NEW *** rts ; Goodbye Done lea Globals,a0 ; Get my globals move.w #1,Count(a0) ; No hits clr.w Error(a0) ; No errors rts ; Goodbye NoComp lea Globals,a0 ; Get my globals move.w #1,Count(a0) ; No hits clr.w Error(a0) ; No errors bra.s Repaint ; Update the cursor ; *** END NEW *** ; PinGuts limits the point in d0 to the bounding rectangle pointed to by a0. ; use the ROM instead, since it even works better, but only when you are really sure! ; (Darin) PinGuts cmp.w Left(a0),d0 ; Check left side bge.s LeftOK move.w Left(a0),d0 LeftOK cmp.w Right(a0),d0 ; Check right side ble.s RightOK move.w Right(a0),d0 sub.w #1,d0 RightOK swap d0 ; Deal with vertical coord cmp.w Top(a0),d0 ; Check top bge.s TopOK move.w Top(a0),d0 TopOK cmp.w Bottom(a0),d0 ; Check bottom ble.s BotOK move.w Bottom(a0),d0 sub.w #1,d0 BotOK swap d0 rts endwith endproc end